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:   PetscFunctionBegin;
 10:   for (i = 0; i < andOr->nsubs; i++) PetscCall(VecTaggerDestroy(&andOr->subs[i]));
 11:   if (andOr->mode == PETSC_OWN_POINTER) PetscCall(PetscFree(andOr->subs));
 12:   PetscCall(PetscFree(tagger->data));
 13:   PetscFunctionReturn(PETSC_SUCCESS);
 14: }

 16: PetscErrorCode VecTaggerGetSubs_AndOr(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
 17: {
 18:   VecTagger_AndOr *andOr = (VecTagger_AndOr *)tagger->data;

 20:   PetscFunctionBegin;
 22:   if (nsubs) {
 23:     PetscAssertPointer(nsubs, 2);
 24:     *nsubs = andOr->nsubs;
 25:   }
 26:   if (subs) {
 27:     PetscAssertPointer(subs, 3);
 28:     *subs = andOr->subs;
 29:   }
 30:   PetscFunctionReturn(PETSC_SUCCESS);
 31: }

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

 38:   PetscFunctionBegin;
 40:   if (subs) PetscAssertPointer(subs, 3);
 41:   if (nsubs == andOr->nsubs && subs == andOr->subs && mode != PETSC_COPY_VALUES) PetscFunctionReturn(PETSC_SUCCESS);
 42:   if (subs) {
 43:     for (i = 0; i < nsubs; i++) PetscCall(PetscObjectReference((PetscObject)subs[i]));
 44:   }
 45:   for (i = 0; i < andOr->nsubs; i++) PetscCall(VecTaggerDestroy(&andOr->subs[i]));
 46:   if (andOr->mode == PETSC_OWN_POINTER && andOr->subs != subs) PetscCall(PetscFree(andOr->subs));
 47:   andOr->nsubs = nsubs;
 48:   if (subs) {
 49:     if (mode == PETSC_COPY_VALUES) {
 50:       andOr->mode = PETSC_OWN_POINTER;
 51:       PetscCall(PetscMalloc1(nsubs, &andOr->subs));
 52:       for (i = 0; i < nsubs; i++) andOr->subs[i] = subs[i];
 53:     } else {
 54:       andOr->subs = subs;
 55:       andOr->mode = mode;
 56:       for (i = 0; i < nsubs; i++) PetscCall(PetscObjectDereference((PetscObject)subs[i]));
 57:     }
 58:   } else {
 59:     MPI_Comm    comm = PetscObjectComm((PetscObject)tagger);
 60:     PetscInt    bs;
 61:     const char *prefix;
 62:     char        tprefix[128];

 64:     PetscCall(VecTaggerGetBlockSize(tagger, &bs));
 65:     PetscCall(PetscObjectGetOptionsPrefix((PetscObject)tagger, &prefix));
 66:     andOr->mode = PETSC_OWN_POINTER;
 67:     PetscCall(PetscMalloc1(nsubs, &andOr->subs));
 68:     for (i = 0; i < nsubs; i++) {
 69:       VecTagger sub;

 71:       PetscCall(PetscSNPrintf(tprefix, 128, "sub_%" PetscInt_FMT "_", i));
 72:       PetscCall(VecTaggerCreate(comm, &sub));
 73:       PetscCall(VecTaggerSetBlockSize(sub, bs));
 74:       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)sub, prefix));
 75:       PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)sub, tprefix));
 76:       andOr->subs[i] = sub;
 77:     }
 78:   }
 79:   PetscFunctionReturn(PETSC_SUCCESS);
 80: }

 82: static PetscErrorCode VecTaggerSetFromOptions_AndOr(VecTagger tagger, PetscOptionItems *PetscOptionsObject)
 83: {
 84:   PetscInt    i, nsubs, nsubsOrig;
 85:   const char *name;
 86:   char        headstring[BUFSIZ];
 87:   char        funcstring[BUFSIZ];
 88:   char        descstring[BUFSIZ];
 89:   VecTagger  *subs;

 91:   PetscFunctionBegin;
 92:   PetscCall(PetscObjectGetType((PetscObject)tagger, &name));
 93:   PetscCall(VecTaggerGetSubs_AndOr(tagger, &nsubs, NULL));
 94:   nsubsOrig = nsubs;
 95:   PetscCall(PetscSNPrintf(headstring, sizeof(headstring), "VecTagger %s options", name));
 96:   PetscCall(PetscSNPrintf(funcstring, sizeof(funcstring), "VecTagger%sSetSubs()", name));
 97:   PetscCall(PetscSNPrintf(descstring, sizeof(descstring), "number of sub tags in %s tag", name));
 98:   PetscOptionsHeadBegin(PetscOptionsObject, headstring);
 99:   PetscCall(PetscOptionsInt("-vec_tagger_num_subs", descstring, funcstring, nsubs, &nsubs, NULL));
100:   PetscOptionsHeadEnd();
101:   if (nsubs != nsubsOrig) {
102:     PetscCall(VecTaggerSetSubs_AndOr(tagger, nsubs, NULL, PETSC_OWN_POINTER));
103:     PetscCall(VecTaggerGetSubs_AndOr(tagger, NULL, &subs));
104:     for (i = 0; i < nsubs; i++) PetscCall(VecTaggerSetFromOptions(subs[i]));
105:   }
106:   PetscFunctionReturn(PETSC_SUCCESS);
107: }

109: static PetscErrorCode VecTaggerSetUp_AndOr(VecTagger tagger)
110: {
111:   PetscInt   nsubs, i;
112:   VecTagger *subs;

114:   PetscFunctionBegin;
115:   PetscCall(VecTaggerGetSubs_AndOr(tagger, &nsubs, &subs));
116:   PetscCheck(nsubs, PetscObjectComm((PetscObject)tagger), PETSC_ERR_ARG_WRONGSTATE, "Must set sub taggers before calling setup.");
117:   for (i = 0; i < nsubs; i++) PetscCall(VecTaggerSetUp(subs[i]));
118:   PetscFunctionReturn(PETSC_SUCCESS);
119: }

121: static PetscErrorCode VecTaggerView_AndOr(VecTagger tagger, PetscViewer viewer)
122: {
123:   PetscBool iascii;

125:   PetscFunctionBegin;
126:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
127:   if (iascii) {
128:     PetscInt    i, nsubs;
129:     VecTagger  *subs;
130:     const char *name;

132:     PetscCall(VecTaggerGetSubs_AndOr(tagger, &nsubs, &subs));
133:     PetscCall(PetscObjectGetType((PetscObject)tagger, &name));
134:     PetscCall(PetscViewerASCIIPrintf(viewer, " %s of %" PetscInt_FMT " subtags:\n", name, nsubs));
135:     PetscCall(PetscViewerASCIIPushTab(viewer));
136:     for (i = 0; i < nsubs; i++) PetscCall(VecTaggerView(subs[i], viewer));
137:     PetscCall(PetscViewerASCIIPopTab(viewer));
138:   }
139:   PetscFunctionReturn(PETSC_SUCCESS);
140: }

142: PetscErrorCode VecTaggerCreate_AndOr(VecTagger tagger)
143: {
144:   VecTagger_AndOr *andOr;

146:   PetscFunctionBegin;
147:   tagger->ops->destroy        = VecTaggerDestroy_AndOr;
148:   tagger->ops->setfromoptions = VecTaggerSetFromOptions_AndOr;
149:   tagger->ops->setup          = VecTaggerSetUp_AndOr;
150:   tagger->ops->view           = VecTaggerView_AndOr;
151:   tagger->ops->computeis      = VecTaggerComputeIS_FromBoxes;
152:   PetscCall(PetscNew(&andOr));
153:   tagger->data = andOr;
154:   PetscFunctionReturn(PETSC_SUCCESS);
155: }

157: PetscErrorCode VecTaggerAndOrIsSubBox_Private(PetscInt bs, const VecTaggerBox *superBox, const VecTaggerBox *subBox, PetscBool *isSub)
158: {
159:   PetscInt i;

161:   PetscFunctionBegin;
162:   *isSub = PETSC_TRUE;
163:   for (i = 0; i < bs; i++) {
164: #if !defined(PETSC_USE_COMPLEX)
165:     if (superBox[i].min > subBox[i].min || superBox[i].max < subBox[i].max) {
166:       *isSub = PETSC_FALSE;
167:       break;
168:     }
169: #else
170:     if (PetscRealPart(superBox[i].min) > PetscRealPart(subBox[i].min) || PetscImaginaryPart(superBox[i].min) > PetscImaginaryPart(subBox[i].min) || PetscRealPart(superBox[i].max) < PetscRealPart(subBox[i].max) ||
171:         PetscImaginaryPart(superBox[i].max) < PetscImaginaryPart(subBox[i].max)) {
172:       *isSub = PETSC_FALSE;
173:       break;
174:     }
175: #endif
176:   }
177:   PetscFunctionReturn(PETSC_SUCCESS);
178: }

180: PetscErrorCode VecTaggerAndOrIntersect_Private(PetscInt bs, const VecTaggerBox *a, const VecTaggerBox *b, VecTaggerBox *c, PetscBool *empty)
181: {
182:   PetscInt i;

184:   PetscFunctionBegin;
185:   *empty = PETSC_FALSE;
186:   for (i = 0; i < bs; i++) {
187: #if !defined(PETSC_USE_COMPLEX)
188:     c[i].min = PetscMax(a[i].min, b[i].min);
189:     c[i].max = PetscMin(a[i].max, b[i].max);
190:     if (c[i].max < c[i].min) {
191:       *empty = PETSC_TRUE;
192:       break;
193:     }
194: #else
195:     {
196:       PetscReal maxMinReal = PetscMax(PetscRealPart(a[i].min), PetscRealPart(b[i].min));
197:       PetscReal maxMinImag = PetscMax(PetscImaginaryPart(a[i].min), PetscImaginaryPart(b[i].min));
198:       PetscReal minMaxReal = PetscMin(PetscRealPart(a[i].max), PetscRealPart(b[i].max));
199:       PetscReal minMaxImag = PetscMin(PetscImaginaryPart(a[i].max), PetscImaginaryPart(b[i].max));

201:       c[i].min = PetscCMPLX(maxMinReal, maxMinImag);
202:       c[i].max = PetscCMPLX(minMaxReal, minMaxImag);
203:       if ((PetscRealPart(c[i].max - c[i].min) < 0.) || (PetscImaginaryPart(c[i].max - c[i].min) < 0.)) {
204:         *empty = PETSC_TRUE;
205:         break;
206:       }
207:     }
208: #endif
209:   }
210:   PetscFunctionReturn(PETSC_SUCCESS);
211: }