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 Parameter:
 11: . tagger - the VecTagger context

 13:   Output Parameters:
 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: {
 23:   VecTaggerGetSubs_AndOr(tagger,nsubs,subs);
 24:   return 0;
 25: }

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

 30:   Logically collective

 32:   Input Parameters:
 33: + tagger - the VecTagger context
 34: . nsubs - the number of sub VecTaggers
 35: - subs - the sub VecTaggers

 37:   Level: advanced

 39: .seealso: VecTaggerAndSetSubs()
 40: @*/
 41: PetscErrorCode VecTaggerAndSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
 42: {
 43:   VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);
 44:   return 0;
 45: }

 47: static PetscErrorCode VecTaggerComputeBoxes_And(VecTagger tagger,Vec vec,PetscInt *numBoxes,VecTaggerBox **boxes,PetscBool *listed)
 48: {
 49:   PetscInt        i, bs, nsubs, *numSubBoxes, nboxes;
 50:   VecTaggerBox    **subBoxes;
 51:   VecTagger       *subs;
 52:   VecTaggerBox    *bxs = NULL;
 53:   PetscBool       sublisted;

 55:   VecTaggerGetBlockSize(tagger,&bs);
 56:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
 57:   PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);
 58:   for (i = 0; i < nsubs; i++) {
 59:     VecTaggerComputeBoxes(subs[i],vec,&numSubBoxes[i],&subBoxes[i],&sublisted);
 60:     if (!sublisted) {
 61:       PetscInt j;

 63:       for (j = 0; j < i; j++) {
 64:         PetscFree(subBoxes[j]);
 65:       }
 66:       PetscFree2(numSubBoxes,subBoxes);
 67:       *listed = PETSC_FALSE;
 68:       return 0;
 69:     }
 70:   }
 71:   for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^3) check to intersect boxes */
 72:     VecTaggerBox *isect;
 73:     PetscInt j, k, l, m, n;

 75:     n = numSubBoxes[i];
 76:     if (!n) {
 77:       nboxes = 0;
 78:       PetscFree(bxs);
 79:       break;
 80:     }
 81:     if (!i) {
 82:       PetscMalloc1(n * bs, &bxs);
 83:       for (j = 0; j < numSubBoxes[i] * bs; j++) bxs[j] = subBoxes[i][j];
 84:       nboxes = n;
 85:       PetscFree(subBoxes[i]);
 86:       continue;
 87:     }
 88:     PetscMalloc1(n * nboxes * bs,&isect);
 89:     for (j = 0, l = 0; j < n; j++) {
 90:       VecTaggerBox *subBox = &subBoxes[i][j*bs];

 92:       for (k = 0; k < nboxes; k++) {
 93:         PetscBool    isEmpty;
 94:         VecTaggerBox *prevBox = &bxs[bs*k];

 96:         VecTaggerAndOrIntersect_Private(bs,prevBox,subBox,&isect[l * bs],&isEmpty);
 97:         if (isEmpty) continue;
 98:         for (m = 0; m < l; m++) {
 99:           PetscBool isSub = PETSC_FALSE;

101:           VecTaggerAndOrIsSubBox_Private(bs,&isect[m*bs],&isect[l*bs],&isSub);
102:           if (isSub) break;
103:           VecTaggerAndOrIsSubBox_Private(bs,&isect[l*bs],&isect[m*bs],&isSub);
104:           if (isSub) {
105:             PetscInt r;

107:             for (r = 0; r < bs; r++) isect[m*bs + r] = isect[l * bs + r];
108:             break;
109:           }
110:         }
111:         if (m == l) l++;
112:       }
113:     }
114:     PetscFree(bxs);
115:     bxs = isect;
116:     nboxes = l;
117:     PetscFree(subBoxes[i]);
118:   }
119:   PetscFree2(numSubBoxes,subBoxes);
120:   *numBoxes = nboxes;
121:   *boxes = bxs;
122:   if (listed) *listed = PETSC_TRUE;
123:   return 0;
124: }

126: static PetscErrorCode VecTaggerComputeIS_And(VecTagger tagger, Vec vec, IS *is,PetscBool *listed)
127: {
128:   PetscInt       nsubs, i;
129:   VecTagger      *subs;
130:   IS             isectIS;
131:   PetscBool      boxlisted;

133:   VecTaggerComputeIS_FromBoxes(tagger,vec,is,&boxlisted);
134:   if (boxlisted) {
135:     if (listed) *listed = PETSC_TRUE;
136:     return 0;
137:   }
138:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
139:   if (!nsubs) {
140:     ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,is);
141:     return 0;
142:   }
143:   VecTaggerComputeIS(subs[0],vec,&isectIS,&boxlisted);
145:   for (i = 1; i < nsubs; i++) {
146:     IS subIS, newIsectIS;

148:     VecTaggerComputeIS(subs[i],vec,&subIS,&boxlisted);
150:     ISIntersect(isectIS,subIS,&newIsectIS);
151:     ISDestroy(&isectIS);
152:     ISDestroy(&subIS);
153:     isectIS = newIsectIS;
154:   }
155:   *is = isectIS;
156:   if (listed) *listed = PETSC_TRUE;
157:   return 0;
158: }

160: PETSC_INTERN PetscErrorCode VecTaggerCreate_And(VecTagger tagger)
161: {
162:   VecTaggerCreate_AndOr(tagger);
163:   tagger->ops->computeboxes = VecTaggerComputeBoxes_And;
164:   tagger->ops->computeis    = VecTaggerComputeIS_And;
165:   return 0;
166: }