1 #include <petsc/private/vecimpl.h> /*I "petscvec.h" I*/
2 #include "../src/vec/vec/utils/tagger/impls/andor.h"
3
4 /*@C
5 VecTaggerAndGetSubs - Get the sub `VecTagger`s whose intersection defines the outer `VecTagger`
6
7 Not Collective
8
9 Input Parameter:
10 . tagger - the `VecTagger` context
11
12 Output Parameters:
13 + nsubs - the number of sub `VecTagger`s
14 - subs - the sub `VecTagger`s
15
16 Level: advanced
17
18 .seealso: `VecTagger`, `VecTaggerAndSetSubs()`
19 @*/
VecTaggerAndGetSubs(VecTagger tagger,PetscInt * nsubs,VecTagger * subs[])20 PetscErrorCode VecTaggerAndGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger *subs[])
21 {
22 PetscFunctionBegin;
23 PetscCall(VecTaggerGetSubs_AndOr(tagger, nsubs, subs));
24 PetscFunctionReturn(PETSC_SUCCESS);
25 }
26
27 /*@C
28 VecTaggerAndSetSubs - Set the sub `VecTagger`s whose intersection defines the outer `VecTagger`
29
30 Logically Collective
31
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`
37
38 Level: advanced
39
40 .seealso: `VecTagger`
41 @*/
VecTaggerAndSetSubs(VecTagger tagger,PetscInt nsubs,VecTagger subs[],PetscCopyMode mode)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 }
48
VecTaggerComputeBoxes_And(VecTagger tagger,Vec vec,PetscInt * numBoxes,VecTaggerBox ** boxes,PetscBool * listed)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;
56
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;
65
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;
75
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];
92
93 for (k = 0; k < nboxes; k++) {
94 PetscBool isEmpty;
95 VecTaggerBox *prevBox = &bxs[bs * k];
96
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;
101
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;
107
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 }
126
VecTaggerComputeIS_And(VecTagger tagger,Vec vec,IS * is,PetscBool * listed)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;
133
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;
149
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 }
161
VecTaggerCreate_And(VecTagger tagger)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 }
170