Actual source code: or.c

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

  4: /*@C
  5:   VecTaggerOrGetSubs - Get the sub `VecTagger`s whose union defines the outer `VecTagger`

  7:   Not Collective

  9:   Input Parameter:
 10: . tagger - the `VecTagger` context

 12:   Output Parameters:
 13: + nsubs - the number of sub `VecTagger`s
 14: - subs  - the sub `VecTagger`s

 16:   Level: advanced

 18: .seealso: `VecTaggerOrSetSubs()`
 19: @*/
 20: PetscErrorCode VecTaggerOrGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
 21: {
 22:   PetscFunctionBegin;
 23:   PetscCall(VecTaggerGetSubs_AndOr(tagger, nsubs, subs));
 24:   PetscFunctionReturn(PETSC_SUCCESS);
 25: }

 27: /*@C
 28:   VecTaggerOrSetSubs - Set the sub `VecTagger`s whose union defines the outer `VecTagger`

 30:   Logically Collective

 32:   Input Parameters:
 33: + tagger - the `VecTagger` context
 34: . nsubs  - the number of sub `VecTagger`s
 35: . subs   - the sub `VecTagger`s
 36: - mode   - the copy mode to use for `subs`

 38:   Level: advanced

 40: .seealso: `VecTaggetOrGetStubs()`
 41: @*/
 42: PetscErrorCode VecTaggerOrSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
 43: {
 44:   PetscFunctionBegin;
 45:   PetscCall(VecTaggerSetSubs_AndOr(tagger, nsubs, subs, mode));
 46:   PetscFunctionReturn(PETSC_SUCCESS);
 47: }

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

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

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

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

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

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

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

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

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

125:     PetscCall(VecTaggerComputeIS(subs[i], vec, &subIS, &boxlisted));
126:     PetscCheck(boxlisted, PetscObjectComm((PetscObject)tagger), PETSC_ERR_SUP, "Tagger cannot VecTaggerComputeIS()");
127:     PetscCall(ISExpand(unionIS, subIS, &newUnionIS));
128:     PetscCall(ISSort(newUnionIS));
129:     PetscCall(ISDestroy(&unionIS));
130:     unionIS = newUnionIS;
131:     PetscCall(ISDestroy(&subIS));
132:   }
133:   *is = unionIS;
134:   if (listed) *listed = PETSC_TRUE;
135:   PetscFunctionReturn(PETSC_SUCCESS);
136: }

138: PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
139: {
140:   PetscFunctionBegin;
141:   PetscCall(VecTaggerCreate_AndOr(tagger));
142:   tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
143:   tagger->ops->computeis    = VecTaggerComputeIS_Or;
144:   PetscFunctionReturn(PETSC_SUCCESS);
145: }