Actual source code: or.c


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

  5: /*@C
  6:   VecTaggerOrGetSubs - Get the sub VecTaggers whose union 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: VecTaggerOrSetSubs()
 20: @*/
 21: PetscErrorCode VecTaggerOrGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
 22: {
 23:   VecTaggerGetSubs_AndOr(tagger,nsubs,subs);
 24:   return 0;
 25: }

 27: /*@C
 28:   VecTaggerOrSetSubs - Set the sub VecTaggers whose union 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: VecTaggerOrSetSubs()
 40: @*/
 41: PetscErrorCode VecTaggerOrSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
 42: {
 43:   VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);
 44:   return 0;
 45: }

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

 55:   VecTaggerGetBlockSize(tagger,&bs);
 56:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
 57:   PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);
 58:   for (i = 0, total = 0; i < nsubs; i++) {
 59:     VecTaggerComputeBoxes(subs[i],vec,&numSubBoxes[i],&subBoxes[i],&boxlisted);
 60:     if (!boxlisted) { /* no support, clean up and exit */
 61:       PetscInt j;

 63:       for (j = 0; j < i; j++) {
 64:         PetscFree(subBoxes[j]);
 65:       }
 66:       PetscFree2(numSubBoxes,subBoxes);
 67:       if (listed) *listed = PETSC_FALSE;
 68:     }
 69:     total += numSubBoxes[i];
 70:   }
 71:   PetscMalloc1(bs * total, &bxs);
 72:   for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^2) check to remove subboxes */
 73:     PetscInt j;

 75:     for (j = 0; j < numSubBoxes[i]; j++) {
 76:       PetscInt     k;
 77:       VecTaggerBox *subBox = &subBoxes[i][j*bs];

 79:       for (k = 0; k < nboxes; k++) {
 80:         PetscBool   isSub = PETSC_FALSE;

 82:         VecTaggerBox *prevBox = &bxs[bs * k];
 83:         VecTaggerAndOrIsSubBox_Private(bs,prevBox,subBox,&isSub);
 84:         if (isSub) break;
 85:         VecTaggerAndOrIsSubBox_Private(bs,subBox,prevBox,&isSub);
 86:         if (isSub) {
 87:           PetscInt l;

 89:           for (l = 0; l < bs; l++) prevBox[l] = subBox[l];
 90:           break;
 91:         }
 92:       }
 93:       if (k < nboxes) continue;
 94:       for (k = 0; k < bs; k++) bxs[nboxes * bs + k] = subBox[k];
 95:       nboxes++;
 96:     }
 97:     PetscFree(subBoxes[i]);
 98:   }
 99:   PetscFree2(numSubBoxes,subBoxes);
100:   *numBoxes = nboxes;
101:   *boxes = bxs;
102:   if (listed) *listed = PETSC_TRUE;
103:   return 0;
104: }

106: static PetscErrorCode VecTaggerComputeIS_Or(VecTagger tagger, Vec vec, IS *is,PetscBool *listed)
107: {
108:   PetscInt       nsubs, i;
109:   VecTagger      *subs;
110:   IS             unionIS;
111:   PetscBool      boxlisted;

113:   VecTaggerComputeIS_FromBoxes(tagger,vec,is,&boxlisted);
114:   if (boxlisted) {
115:     if (listed) *listed = PETSC_TRUE;
116:     return 0;
117:   }
118:   VecTaggerOrGetSubs(tagger,&nsubs,&subs);
119:   ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,&unionIS);
120:   for (i = 0; i < nsubs; i++) {
121:     IS subIS, newUnionIS;

123:     VecTaggerComputeIS(subs[i],vec,&subIS,&boxlisted);
125:     ISExpand(unionIS,subIS,&newUnionIS);
126:     ISSort(newUnionIS);
127:     ISDestroy(&unionIS);
128:     unionIS = newUnionIS;
129:     ISDestroy(&subIS);
130:   }
131:   *is = unionIS;
132:   if (listed) *listed = PETSC_TRUE;
133:   return 0;
134: }

136: PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
137: {
138:   VecTaggerCreate_AndOr(tagger);
139:   tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
140:   tagger->ops->computeis        = VecTaggerComputeIS_Or;
141:   return 0;
142: }