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