Actual source code: andor.c

  1: #include <petsc/private/vecimpl.h>
  2: #include "../src/vec/vec/utils/tagger/impls/andor.h"

  4: static PetscErrorCode VecTaggerDestroy_AndOr(VecTagger tagger)
  5: {
  6:   VecTagger_AndOr *andOr = (VecTagger_AndOr *) tagger->data;
  7:   PetscInt        i;

  9:   for (i = 0; i < andOr->nsubs; i++) {
 10:     VecTaggerDestroy(&andOr->subs[i]);
 11:   }
 12:   if (andOr->mode == PETSC_OWN_POINTER) {
 13:     PetscFree(andOr->subs);
 14:   }
 15:   PetscFree(tagger->data);
 16:   return 0;
 17: }

 19: PetscErrorCode VecTaggerGetSubs_AndOr(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
 20: {
 21:   VecTagger_AndOr *andOr = (VecTagger_AndOr *) tagger->data;

 24:   if (nsubs) {
 26:     *nsubs = andOr->nsubs;
 27:   }
 28:   if (subs) {
 30:     *subs = andOr->subs;
 31:   }
 32:   return 0;
 33: }

 35: PetscErrorCode VecTaggerSetSubs_AndOr(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
 36: {
 37:   PetscInt        i;
 38:   VecTagger_AndOr *andOr = (VecTagger_AndOr *) tagger->data;

 42:   if (nsubs == andOr->nsubs && subs == andOr->subs && mode != PETSC_COPY_VALUES) return 0;
 43:   if (subs) {
 44:     for (i = 0; i < nsubs; i++) {
 45:       PetscObjectReference((PetscObject)subs[i]);
 46:     }
 47:   }
 48:   for (i = 0; i < andOr->nsubs; i++) {
 49:     VecTaggerDestroy(&(andOr->subs[i]));
 50:   }
 51:   if (andOr->mode == PETSC_OWN_POINTER && andOr->subs != subs) {
 52:     PetscFree(andOr->subs);
 53:   }
 54:   andOr->nsubs = nsubs;
 55:   if (subs) {
 56:     if (mode == PETSC_COPY_VALUES) {
 57:       andOr->mode = PETSC_OWN_POINTER;
 58:       PetscMalloc1(nsubs,&(andOr->subs));
 59:       for (i = 0; i < nsubs; i++) {
 60:         andOr->subs[i] = subs[i];
 61:       }
 62:     } else {
 63:       andOr->subs = subs;
 64:       andOr->mode = mode;
 65:       for (i = 0; i < nsubs; i++) {
 66:         PetscObjectDereference((PetscObject)subs[i]);
 67:       }
 68:     }
 69:   } else {
 70:     MPI_Comm   comm = PetscObjectComm((PetscObject)tagger);
 71:     PetscInt   bs;
 72:     const char *prefix;
 73:     char       tprefix[128];

 75:     VecTaggerGetBlockSize(tagger,&bs);
 76:     PetscObjectGetOptionsPrefix((PetscObject)tagger,&prefix);
 77:     andOr->mode = PETSC_OWN_POINTER;
 78:     PetscMalloc1(nsubs,&(andOr->subs));
 79:     for (i = 0; i < nsubs; i++) {
 80:       VecTagger sub;

 82:       PetscSNPrintf(tprefix,128,"sub_%" PetscInt_FMT "_",i);
 83:       VecTaggerCreate(comm,&sub);
 84:       VecTaggerSetBlockSize(sub,bs);
 85:       PetscObjectSetOptionsPrefix((PetscObject)sub,prefix);
 86:       PetscObjectAppendOptionsPrefix((PetscObject)sub,tprefix);
 87:       andOr->subs[i] = sub;
 88:     }
 89:   }
 90:   return 0;
 91: }

 93: static PetscErrorCode VecTaggerSetFromOptions_AndOr(PetscOptionItems *PetscOptionsObject,VecTagger tagger)
 94: {
 95:   PetscInt       i, nsubs, nsubsOrig;
 96:   const char     *name;
 97:   char           headstring[BUFSIZ];
 98:   char           funcstring[BUFSIZ];
 99:   char           descstring[BUFSIZ];
100:   VecTagger      *subs;

102:   PetscObjectGetType((PetscObject)tagger,&name);
103:   VecTaggerGetSubs_AndOr(tagger,&nsubs,NULL);
104:   nsubsOrig = nsubs;
105:   PetscSNPrintf(headstring,sizeof(headstring),"VecTagger %s options",name);
106:   PetscSNPrintf(funcstring,sizeof(funcstring),"VecTagger%sSetSubs()",name);
107:   PetscSNPrintf(descstring,sizeof(descstring),"number of sub tags in %s tag",name);
108:   PetscOptionsHead(PetscOptionsObject,headstring);
109:   PetscOptionsInt("-vec_tagger_num_subs",descstring,funcstring,nsubs,&nsubs,NULL);
110:   PetscOptionsTail();
111:   if (nsubs != nsubsOrig) {
112:     VecTaggerSetSubs_AndOr(tagger,nsubs,NULL,PETSC_OWN_POINTER);
113:     VecTaggerGetSubs_AndOr(tagger,NULL,&subs);
114:     for (i = 0; i < nsubs; i++) {
115:       VecTaggerSetFromOptions(subs[i]);
116:     }
117:   }
118:   return 0;
119: }

121: static PetscErrorCode VecTaggerSetUp_AndOr (VecTagger tagger)
122: {
123:   PetscInt        nsubs, i;
124:   VecTagger       *subs;

126:   VecTaggerGetSubs_AndOr(tagger,&nsubs,&subs);
128:   for (i = 0; i < nsubs; i++) {
129:     VecTaggerSetUp(subs[i]);
130:   }
131:   return 0;
132: }

134: static PetscErrorCode VecTaggerView_AndOr(VecTagger tagger, PetscViewer viewer)
135: {
136:   PetscBool       iascii;

138:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
139:   if (iascii) {
140:     PetscInt i, nsubs;
141:     VecTagger *subs;
142:     const char *name;

144:     VecTaggerGetSubs_AndOr(tagger,&nsubs,&subs);
145:     PetscObjectGetType((PetscObject)tagger,&name);
146:     PetscViewerASCIIPrintf(viewer," %s of %" PetscInt_FMT " subtags:\n",name,nsubs);
147:     PetscViewerASCIIPushTab(viewer);
148:     for (i = 0; i < nsubs; i++) {
149:       VecTaggerView(subs[i],viewer);
150:     }
151:     PetscViewerASCIIPopTab(viewer);
152:   }
153:   return 0;
154: }

156: PetscErrorCode VecTaggerCreate_AndOr(VecTagger tagger)
157: {
158:   VecTagger_AndOr    *andOr;

160:   tagger->ops->destroy          = VecTaggerDestroy_AndOr;
161:   tagger->ops->setfromoptions   = VecTaggerSetFromOptions_AndOr;
162:   tagger->ops->setup            = VecTaggerSetUp_AndOr;
163:   tagger->ops->view             = VecTaggerView_AndOr;
164:   tagger->ops->computeis        = VecTaggerComputeIS_FromBoxes;
165:   PetscNewLog(tagger,&andOr);
166:   tagger->data = andOr;
167:   return 0;
168: }

170: PetscErrorCode VecTaggerAndOrIsSubBox_Private(PetscInt bs, const VecTaggerBox *superBox, const VecTaggerBox *subBox,PetscBool *isSub)
171: {
172:   PetscInt       i;

174:   *isSub = PETSC_TRUE;
175:   for (i = 0; i < bs; i++) {
176: #if !defined(PETSC_USE_COMPLEX)
177:     if (superBox[i].min > subBox[i].min || superBox[i].max < subBox[i].max) {
178:       *isSub = PETSC_FALSE;
179:       break;
180:     }
181: #else
182:     if (PetscRealPart(superBox[i].min) > PetscRealPart(subBox[i].min) || PetscImaginaryPart(superBox[i].min) > PetscImaginaryPart(subBox[i].min) ||
183:         PetscRealPart(superBox[i].max) < PetscRealPart(subBox[i].max) || PetscImaginaryPart(superBox[i].max) < PetscImaginaryPart(subBox[i].max)) {
184:       *isSub = PETSC_FALSE;
185:       break;
186:     }
187: #endif
188:   }
189:   return 0;
190: }

192: PetscErrorCode VecTaggerAndOrIntersect_Private(PetscInt bs, const VecTaggerBox *a, const VecTaggerBox *b,VecTaggerBox *c,PetscBool *empty)
193: {
194:   PetscInt       i;

196:   *empty = PETSC_FALSE;
197:   for (i = 0; i < bs; i++) {
198: #if !defined(PETSC_USE_COMPLEX)
199:     c[i].min = PetscMax(a[i].min,b[i].min);
200:     c[i].max = PetscMin(a[i].max,b[i].max);
201:     if (c[i].max < c[i].min) {
202:       *empty = PETSC_TRUE;
203:       break;
204:     }
205: #else
206:     {
207:       PetscReal maxMinReal = PetscMax(PetscRealPart(a[i].min),PetscRealPart(b[i].min));
208:       PetscReal maxMinImag = PetscMax(PetscImaginaryPart(a[i].min),PetscImaginaryPart(b[i].min));
209:       PetscReal minMaxReal = PetscMin(PetscRealPart(a[i].max),PetscRealPart(b[i].max));
210:       PetscReal minMaxImag = PetscMin(PetscImaginaryPart(a[i].max),PetscImaginaryPart(b[i].max));

212:       c[i].min = PetscCMPLX(maxMinReal,maxMinImag);
213:       c[i].max = PetscCMPLX(minMaxReal,minMaxImag);
214:       if ((PetscRealPart(c[i].max - c[i].min) < 0.) || (PetscImaginaryPart(c[i].max - c[i].min) < 0.)) {
215:         *empty = PETSC_TRUE;
216:         break;
217:       }
218:     }
219: #endif
220:   }
221:   return 0;
222: }