xref: /petsc/src/vec/vec/utils/tagger/impls/or.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   VecTaggerOrGetSubs - Get the sub `VecTagger`s whose union 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: `VecTaggerOrSetSubs()`
19 @*/
VecTaggerOrGetSubs(VecTagger tagger,PetscInt * nsubs,VecTagger * subs[])20 PetscErrorCode VecTaggerOrGetSubs(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   VecTaggerOrSetSubs - Set the sub `VecTagger`s whose union 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: `VecTaggetOrGetStubs()`
41 @*/
VecTaggerOrSetSubs(VecTagger tagger,PetscInt nsubs,VecTagger subs[],PetscCopyMode mode)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 }
48 
VecTaggerComputeBoxes_Or(VecTagger tagger,Vec vec,PetscInt * numBoxes,VecTaggerBox ** boxes,PetscBool * listed)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;
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, 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;
65 
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;
75 
76     for (j = 0; j < numSubBoxes[i]; j++) {
77       PetscInt      k;
78       VecTaggerBox *subBox = &subBoxes[i][j * bs];
79 
80       for (k = 0; k < nboxes; k++) {
81         PetscBool isSub = PETSC_FALSE;
82 
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;
89 
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 }
106 
VecTaggerComputeIS_Or(VecTagger tagger,Vec vec,IS * is,PetscBool * listed)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;
113 
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;
124 
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 }
137 
VecTaggerCreate_Or(VecTagger tagger)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 }
146