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

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

 77:       for (k = 0; k < nboxes; k++) {
 78:         PetscBool isSub = PETSC_FALSE;

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

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

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

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

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

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