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

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

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

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

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

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

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

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

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

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