Actual source code: and.c

petsc-3.11.2 2019-05-18
Report Typos and Errors

  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: }