Actual source code: and.c

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

      4: /*@C
      5:   VecTaggerAndGetSubs - Get the sub `VecTagger`s whose intersection 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: `VecTagger`, `VecTaggerAndSetSubs()`
     19: @*/
     20: PetscErrorCode VecTaggerAndGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger *subs[])
     21: {
     22:   PetscFunctionBegin;
     23:   PetscCall(VecTaggerGetSubs_AndOr(tagger, nsubs, subs));
     24:   PetscFunctionReturn(PETSC_SUCCESS);
     25: }

     27: /*@C
     28:   VecTaggerAndSetSubs - Set the sub `VecTagger`s whose intersection 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: `VecTagger`
     41: @*/
     42: PetscErrorCode VecTaggerAndSetSubs(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_And(VecTagger tagger, Vec vec, PetscInt *numBoxes, VecTaggerBox **boxes, PetscBool *listed)
     50: {
     51:   PetscInt       i, bs, nsubs, *numSubBoxes, nboxes;
     52:   VecTaggerBox **subBoxes;
     53:   VecTagger     *subs;
     54:   VecTaggerBox  *bxs = NULL;
     55:   PetscBool      sublisted;

     57:   PetscFunctionBegin;
     58:   PetscCall(VecTaggerGetBlockSize(tagger, &bs));
     59:   PetscCall(VecTaggerOrGetSubs(tagger, &nsubs, &subs));
     60:   PetscCall(PetscMalloc2(nsubs, &numSubBoxes, nsubs, &subBoxes));
     61:   for (i = 0; i < nsubs; i++) {
     62:     PetscCall(VecTaggerComputeBoxes(subs[i], vec, &numSubBoxes[i], &subBoxes[i], &sublisted));
     63:     if (!sublisted) {
     64:       PetscInt j;

     66:       for (j = 0; j < i; j++) PetscCall(PetscFree(subBoxes[j]));
     67:       PetscCall(PetscFree2(numSubBoxes, subBoxes));
     68:       *listed = PETSC_FALSE;
     69:       PetscFunctionReturn(PETSC_SUCCESS);
     70:     }
     71:   }
     72:   for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^3) check to intersect boxes */
     73:     VecTaggerBox *isect;
     74:     PetscInt      j, k, l, m, n;

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

     93:       for (k = 0; k < nboxes; k++) {
     94:         PetscBool     isEmpty;
     95:         VecTaggerBox *prevBox = &bxs[bs * k];

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

    102:           PetscCall(VecTaggerAndOrIsSubBox_Private(bs, &isect[m * bs], &isect[l * bs], &isSub));
    103:           if (isSub) break;
    104:           PetscCall(VecTaggerAndOrIsSubBox_Private(bs, &isect[l * bs], &isect[m * bs], &isSub));
    105:           if (isSub) {
    106:             PetscInt r;

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

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

    134:   PetscFunctionBegin;
    135:   PetscCall(VecTaggerComputeIS_FromBoxes(tagger, vec, is, &boxlisted));
    136:   if (boxlisted) {
    137:     if (listed) *listed = PETSC_TRUE;
    138:     PetscFunctionReturn(PETSC_SUCCESS);
    139:   }
    140:   PetscCall(VecTaggerOrGetSubs(tagger, &nsubs, &subs));
    141:   if (!nsubs) {
    142:     PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)vec), 0, NULL, PETSC_OWN_POINTER, is));
    143:     PetscFunctionReturn(PETSC_SUCCESS);
    144:   }
    145:   PetscCall(VecTaggerComputeIS(subs[0], vec, &isectIS, &boxlisted));
    146:   PetscCheck(boxlisted, PetscObjectComm((PetscObject)tagger), PETSC_ERR_SUP, "Does not support VecTaggerComputeIS()");
    147:   for (i = 1; i < nsubs; i++) {
    148:     IS subIS, newIsectIS;

    150:     PetscCall(VecTaggerComputeIS(subs[i], vec, &subIS, &boxlisted));
    151:     PetscCheck(boxlisted, PetscObjectComm((PetscObject)tagger), PETSC_ERR_SUP, "Does not support VecTaggerComputeIS()");
    152:     PetscCall(ISIntersect(isectIS, subIS, &newIsectIS));
    153:     PetscCall(ISDestroy(&isectIS));
    154:     PetscCall(ISDestroy(&subIS));
    155:     isectIS = newIsectIS;
    156:   }
    157:   *is = isectIS;
    158:   if (listed) *listed = PETSC_TRUE;
    159:   PetscFunctionReturn(PETSC_SUCCESS);
    160: }

    162: PETSC_INTERN PetscErrorCode VecTaggerCreate_And(VecTagger tagger)
    163: {
    164:   PetscFunctionBegin;
    165:   PetscCall(VecTaggerCreate_AndOr(tagger));
    166:   tagger->ops->computeboxes = VecTaggerComputeBoxes_And;
    167:   tagger->ops->computeis    = VecTaggerComputeIS_And;
    168:   PetscFunctionReturn(PETSC_SUCCESS);
    169: }