Actual source code: and.c

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

      5: /*@C
      6:   VecTaggerAndGetSubs - Get the sub VecTaggers whose intersection defines the outer VecTagger

      8:   Not collective

     10:   Input Arguments:
     11: . tagger - the VecTagger context

     13:   Output Arguments:
     14: + nsubs - the number of sub VecTaggers
     15: - subs - the sub VecTaggers

     17:   Level: advanced

     19: .seealso: VecTaggerAndSetSubs()
     20: @*/
     21: PetscErrorCode VecTaggerAndGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
     22: {

     26:   VecTaggerGetSubs_AndOr(tagger,nsubs,subs);
     27:   return(0);
     28: }

     30: /*@C
     31:   VecTaggerAndSetSubs - Set the sub VecTaggers whose intersection defines the outer VecTagger

     33:   Logically collective

     35:   Input Arguments:
     36: + tagger - the VecTagger context
     37: . nsubs - the number of sub VecTaggers
     38: - subs - the sub VecTaggers

     40:   Level: advanced

     42: .seealso: VecTaggerAndSetSubs()
     43: @*/
     44: PetscErrorCode VecTaggerAndSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
     45: {

     49:   VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);
     50:   return(0);
     51: }

     53: static PetscErrorCode VecTaggerComputeBoxes_And(VecTagger tagger,Vec vec,PetscInt *numBoxes,VecTaggerBox **boxes)
     54: {
     55:   PetscInt        i, bs, nsubs, *numSubBoxes, nboxes;
     56:   VecTaggerBox    **subBoxes;
     57:   VecTagger       *subs;
     58:   VecTaggerBox    *bxs = NULL;
     59:   PetscErrorCode  ierr;

     62:   VecTaggerGetBlockSize(tagger,&bs);
     63:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
     64:   PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);
     65:   for (i = 0; i < nsubs; i++) {
     66:     PetscErrorCode ierr2;

     68:     ierr2 = VecTaggerComputeBoxes(subs[i],vec,&numSubBoxes[i],&subBoxes[i]);
     69:     if (ierr2 == PETSC_ERR_SUP) { /* no support, clean up and exit */
     70:       PetscInt j;

     72:       for (j = 0; j < i; j++) {
     73:         PetscFree(subBoxes[j]);
     74:       }
     75:       PetscFree2(numSubBoxes,subBoxes);
     76:       SETERRQ(PetscObjectComm((PetscObject)tagger),PETSC_ERR_SUP,"Sub tagger does not support box computation");
     77:     } else {
     78:       CHKERRQ(ierr2);
     79:     }
     80:   }
     81:   for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^3) check to intersect boxes */
     82:     VecTaggerBox *isect;
     83:     PetscInt j, k, l, m, n;

     85:     n = numSubBoxes[i];
     86:     if (!n) {
     87:       nboxes = 0;
     88:       PetscFree(bxs);
     89:       break;
     90:     }
     91:     if (!i) {
     92:       PetscMalloc1(n * bs, &bxs);
     93:       for (j = 0; j < numSubBoxes[i] * bs; j++) bxs[j] = subBoxes[i][j];
     94:       nboxes = n;
     95:       PetscFree(subBoxes[i]);
     96:       continue;
     97:     }
     98:     PetscMalloc1(n * nboxes * bs,&isect);
     99:     for (j = 0, l = 0; j < n; j++) {
    100:       VecTaggerBox *subBox = &subBoxes[i][j*bs];

    102:       for (k = 0; k < nboxes; k++) {
    103:         PetscBool    isEmpty;
    104:         VecTaggerBox *prevBox = &bxs[bs*k];

    106:         VecTaggerAndOrIntersect_Private(bs,prevBox,subBox,&isect[l * bs],&isEmpty);
    107:         if (isEmpty) continue;
    108:         for (m = 0; m < l; m++) {
    109:           PetscBool isSub = PETSC_FALSE;

    111:           VecTaggerAndOrIsSubBox_Private(bs,&isect[m*bs],&isect[l*bs],&isSub);
    112:           if (isSub) break;
    113:           VecTaggerAndOrIsSubBox_Private(bs,&isect[l*bs],&isect[m*bs],&isSub);
    114:           if (isSub) {
    115:             PetscInt r;

    117:             for (r = 0; r < bs; r++) isect[m*bs + r] = isect[l * bs + r];
    118:             break;
    119:           }
    120:         }
    121:         if (m == l) l++;
    122:       }
    123:     }
    124:     PetscFree(bxs);
    125:     bxs = isect;
    126:     nboxes = l;
    127:     PetscFree(subBoxes[i]);
    128:   }
    129:   PetscFree2(numSubBoxes,subBoxes);
    130:   *numBoxes = nboxes;
    131:   *boxes = bxs;
    132:   return(0);
    133: }

    135: static PetscErrorCode VecTaggerComputeIS_And(VecTagger tagger, Vec vec, IS *is)
    136: {
    137:   PetscInt       nsubs, i;
    138:   VecTagger      *subs;
    139:   IS             isectIS;
    140:   PetscErrorCode ierr, ierr2;

    143:   ierr2 = VecTaggerComputeIS_FromBoxes(tagger,vec,is);
    144:   if (ierr2 != PETSC_ERR_SUP) {
    145:     CHKERRQ(ierr2);
    146:     return(0);
    147:   }
    148:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
    149:   if (!nsubs) {
    150:     ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,is);
    151:     return(0);
    152:   }
    153:   VecTaggerComputeIS(subs[0],vec,&isectIS);
    154:   for (i = 1; i < nsubs; i++) {
    155:     IS subIS, newIsectIS;

    157:     VecTaggerComputeIS(subs[i],vec,&subIS);
    158:     ISIntersect(isectIS,subIS,&newIsectIS);
    159:     ISDestroy(&isectIS);
    160:     ISDestroy(&subIS);
    161:     isectIS = newIsectIS;
    162:   }
    163:   *is = isectIS;
    164:   return(0);
    165: }

    167: PETSC_INTERN PetscErrorCode VecTaggerCreate_And(VecTagger tagger)
    168: {

    172:   VecTaggerCreate_AndOr(tagger);
    173:   tagger->ops->computeboxes = VecTaggerComputeBoxes_And;
    174:   tagger->ops->computeis    = VecTaggerComputeIS_And;
    175:   return(0);
    176: }