xref: /petsc/src/vec/vec/utils/tagger/impls/and.c (revision 1ed6e3ff8437baa411029a28c2b08f047df9ad9a)
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