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 isascii;

    125:   PetscFunctionBegin;
    126:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
    127:   if (isascii) {
    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: }