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;
      8:   PetscErrorCode  ierr;

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

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

     27:   if (nsubs) {
     29:     *nsubs = andOr->nsubs;
     30:   }
     31:   if (subs) {
     33:     *subs = andOr->subs;
     34:   }
     35:   return(0);
     36: }

     38: PetscErrorCode VecTaggerSetSubs_AndOr(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
     39: {
     40:   PetscInt        i;
     41:   VecTagger_AndOr *andOr = (VecTagger_AndOr *) tagger->data;
     42:   PetscErrorCode  ierr;

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

     80:     VecTaggerGetBlockSize(tagger,&bs);
     81:     PetscObjectGetOptionsPrefix((PetscObject)tagger,&prefix);
     82:     andOr->mode = PETSC_OWN_POINTER;
     83:     PetscMalloc1(nsubs,&(andOr->subs));
     84:     for (i = 0; i < nsubs; i++) {
     85:       VecTagger sub;

     87:       PetscSNPrintf(tprefix,128,"sub_%D_",i);
     88:       VecTaggerCreate(comm,&sub);
     89:       VecTaggerSetBlockSize(sub,bs);
     90:       PetscObjectSetOptionsPrefix((PetscObject)sub,prefix);
     91:       PetscObjectAppendOptionsPrefix((PetscObject)sub,tprefix);
     92:       andOr->subs[i] = sub;
     93:     }
     94:   }
     95:   return(0);
     96: }

     98: static PetscErrorCode VecTaggerSetFromOptions_AndOr(PetscOptionItems *PetscOptionsObject,VecTagger tagger)
     99: {
    100:   PetscInt       i, nsubs, nsubsOrig;
    101:   const char     *name;
    102:   char           headstring[BUFSIZ];
    103:   char           funcstring[BUFSIZ];
    104:   char           descstring[BUFSIZ];
    105:   VecTagger      *subs;

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

    128: static PetscErrorCode VecTaggerSetUp_AndOr (VecTagger tagger)
    129: {
    130:   PetscInt        nsubs, i;
    131:   VecTagger       *subs;
    132:   PetscErrorCode  ierr;

    135:   VecTaggerGetSubs_AndOr(tagger,&nsubs,&subs);
    136:   if (!nsubs) SETERRQ(PetscObjectComm((PetscObject)tagger),PETSC_ERR_ARG_WRONGSTATE,"Must set sub taggers before calling setup.");
    137:   for (i = 0; i < nsubs; i++) {
    138:     VecTaggerSetUp(subs[i]);
    139:   }
    140:   return(0);
    141: }

    143: static PetscErrorCode VecTaggerView_AndOr(VecTagger tagger, PetscViewer viewer)
    144: {
    145:   PetscBool       iascii;
    146:   PetscErrorCode  ierr;

    149:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    150:   if (iascii) {
    151:     PetscInt i, nsubs;
    152:     VecTagger *subs;
    153:     const char *name;

    155:     VecTaggerGetSubs_AndOr(tagger,&nsubs,&subs);
    156:     PetscObjectGetType((PetscObject)tagger,&name);
    157:     PetscViewerASCIIPrintf(viewer," %s of %D subtags:\n",name,nsubs);
    158:     PetscViewerASCIIPushTab(viewer);
    159:     for (i = 0; i < nsubs; i++) {
    160:       VecTaggerView(subs[i],viewer);
    161:     }
    162:     PetscViewerASCIIPopTab(viewer);
    163:   }
    164:   return(0);
    165: }

    167: PetscErrorCode VecTaggerCreate_AndOr(VecTagger tagger)
    168: {
    169:   VecTagger_AndOr    *andOr;
    170:   PetscErrorCode     ierr;

    173:   tagger->ops->destroy          = VecTaggerDestroy_AndOr;
    174:   tagger->ops->setfromoptions   = VecTaggerSetFromOptions_AndOr;
    175:   tagger->ops->setup            = VecTaggerSetUp_AndOr;
    176:   tagger->ops->view             = VecTaggerView_AndOr;
    177:   tagger->ops->computeis        = VecTaggerComputeIS_FromBoxes;
    178:   PetscNewLog(tagger,&andOr);
    179:   tagger->data = andOr;
    180:   return(0);
    181: }

    183: PetscErrorCode VecTaggerAndOrIsSubBox_Private(PetscInt bs, const VecTaggerBox *superBox, const VecTaggerBox *subBox,PetscBool *isSub)
    184: {
    185:   PetscInt       i;

    188:   *isSub = PETSC_TRUE;
    189:   for (i = 0; i < bs; i++) {
    190: #if !defined(PETSC_USE_COMPLEX)
    191:     if (superBox[i].min > subBox[i].min || superBox[i].max < subBox[i].max) {
    192:       *isSub = PETSC_FALSE;
    193:       break;
    194:     }
    195: #else
    196:     if (PetscRealPart(superBox[i].min) > PetscRealPart(subBox[i].min) || PetscImaginaryPart(superBox[i].min) > PetscImaginaryPart(subBox[i].min) ||
    197:         PetscRealPart(superBox[i].max) < PetscRealPart(subBox[i].max) || PetscImaginaryPart(superBox[i].max) < PetscImaginaryPart(subBox[i].max)) {
    198:       *isSub = PETSC_FALSE;
    199:       break;
    200:     }
    201: #endif
    202:   }
    203:   return(0);
    204: }

    206: PetscErrorCode VecTaggerAndOrIntersect_Private(PetscInt bs, const VecTaggerBox *a, const VecTaggerBox *b,VecTaggerBox *c,PetscBool *empty)
    207: {
    208:   PetscInt       i;

    211:   *empty = PETSC_FALSE;
    212:   for (i = 0; i < bs; i++) {
    213: #if !defined(PETSC_USE_COMPLEX)
    214:     c[i].min = PetscMax(a[i].min,b[i].min);
    215:     c[i].max = PetscMin(a[i].max,b[i].max);
    216:     if (c[i].max < c[i].min) {
    217:       *empty = PETSC_TRUE;
    218:       break;
    219:     }
    220: #else
    221:     {
    222:       PetscReal maxMinReal = PetscMax(PetscRealPart(a[i].min),PetscRealPart(b[i].min));
    223:       PetscReal maxMinImag = PetscMax(PetscImaginaryPart(a[i].min),PetscImaginaryPart(b[i].min));
    224:       PetscReal minMaxReal = PetscMin(PetscRealPart(a[i].max),PetscRealPart(b[i].max));
    225:       PetscReal minMaxImag = PetscMin(PetscImaginaryPart(a[i].max),PetscImaginaryPart(b[i].max));

    227:       c[i].min = PetscCMPLX(maxMinReal,maxMinImag);
    228:       c[i].max = PetscCMPLX(minMaxReal,minMaxImag);
    229:       if ((PetscRealPart(c[i].max - c[i].min) < 0.) || (PetscImaginaryPart(c[i].max - c[i].min) < 0.)) {
    230:         *empty = PETSC_TRUE;
    231:         break;
    232:       }
    233:     }
    234: #endif
    235:   }
    236:   return(0);
    237: }