1 #include <petsc/private/vecimpl.h> /*I "petscvec.h" I*/
2 #include "../src/vec/vec/utils/tagger/impls/andor.h"
3
VecTaggerDestroy_AndOr(VecTagger tagger)4 static PetscErrorCode VecTaggerDestroy_AndOr(VecTagger tagger)
5 {
6 VecTagger_AndOr *andOr = (VecTagger_AndOr *)tagger->data;
7 PetscInt i;
8
9 PetscFunctionBegin;
10 for (i = 0; i < andOr->nsubs; i++) PetscCall(VecTaggerDestroy(&andOr->subs[i]));
11 if (andOr->mode == PETSC_OWN_POINTER) PetscCall(PetscFree(andOr->subs));
12 PetscCall(PetscFree(tagger->data));
13 PetscFunctionReturn(PETSC_SUCCESS);
14 }
15
VecTaggerGetSubs_AndOr(VecTagger tagger,PetscInt * nsubs,VecTagger ** subs)16 PetscErrorCode VecTaggerGetSubs_AndOr(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
17 {
18 VecTagger_AndOr *andOr = (VecTagger_AndOr *)tagger->data;
19
20 PetscFunctionBegin;
21 PetscValidHeaderSpecific(tagger, VEC_TAGGER_CLASSID, 1);
22 if (nsubs) {
23 PetscAssertPointer(nsubs, 2);
24 *nsubs = andOr->nsubs;
25 }
26 if (subs) {
27 PetscAssertPointer(subs, 3);
28 *subs = andOr->subs;
29 }
30 PetscFunctionReturn(PETSC_SUCCESS);
31 }
32
VecTaggerSetSubs_AndOr(VecTagger tagger,PetscInt nsubs,VecTagger * subs,PetscCopyMode mode)33 PetscErrorCode VecTaggerSetSubs_AndOr(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
34 {
35 PetscInt i;
36 VecTagger_AndOr *andOr = (VecTagger_AndOr *)tagger->data;
37
38 PetscFunctionBegin;
39 PetscValidHeaderSpecific(tagger, VEC_TAGGER_CLASSID, 1);
40 if (subs) PetscAssertPointer(subs, 3);
41 if (nsubs == andOr->nsubs && subs == andOr->subs && mode != PETSC_COPY_VALUES) PetscFunctionReturn(PETSC_SUCCESS);
42 if (subs) {
43 for (i = 0; i < nsubs; i++) PetscCall(PetscObjectReference((PetscObject)subs[i]));
44 }
45 for (i = 0; i < andOr->nsubs; i++) PetscCall(VecTaggerDestroy(&andOr->subs[i]));
46 if (andOr->mode == PETSC_OWN_POINTER && andOr->subs != subs) PetscCall(PetscFree(andOr->subs));
47 andOr->nsubs = nsubs;
48 if (subs) {
49 if (mode == PETSC_COPY_VALUES) {
50 andOr->mode = PETSC_OWN_POINTER;
51 PetscCall(PetscMalloc1(nsubs, &andOr->subs));
52 for (i = 0; i < nsubs; i++) andOr->subs[i] = subs[i];
53 } else {
54 andOr->subs = subs;
55 andOr->mode = mode;
56 for (i = 0; i < nsubs; i++) PetscCall(PetscObjectDereference((PetscObject)subs[i]));
57 }
58 } else {
59 MPI_Comm comm = PetscObjectComm((PetscObject)tagger);
60 PetscInt bs;
61 const char *prefix;
62 char tprefix[128];
63
64 PetscCall(VecTaggerGetBlockSize(tagger, &bs));
65 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)tagger, &prefix));
66 andOr->mode = PETSC_OWN_POINTER;
67 PetscCall(PetscMalloc1(nsubs, &andOr->subs));
68 for (i = 0; i < nsubs; i++) {
69 VecTagger sub;
70
71 PetscCall(PetscSNPrintf(tprefix, 128, "sub_%" PetscInt_FMT "_", i));
72 PetscCall(VecTaggerCreate(comm, &sub));
73 PetscCall(VecTaggerSetBlockSize(sub, bs));
74 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)sub, prefix));
75 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)sub, tprefix));
76 andOr->subs[i] = sub;
77 }
78 }
79 PetscFunctionReturn(PETSC_SUCCESS);
80 }
81
VecTaggerSetFromOptions_AndOr(VecTagger tagger,PetscOptionItems PetscOptionsObject)82 static PetscErrorCode VecTaggerSetFromOptions_AndOr(VecTagger tagger, PetscOptionItems PetscOptionsObject)
83 {
84 PetscInt i, nsubs, nsubsOrig;
85 const char *name;
86 char headstring[BUFSIZ];
87 char funcstring[BUFSIZ];
88 char descstring[BUFSIZ];
89 VecTagger *subs;
90
91 PetscFunctionBegin;
92 PetscCall(PetscObjectGetType((PetscObject)tagger, &name));
93 PetscCall(VecTaggerGetSubs_AndOr(tagger, &nsubs, NULL));
94 nsubsOrig = nsubs;
95 PetscCall(PetscSNPrintf(headstring, sizeof(headstring), "VecTagger %s options", name));
96 PetscCall(PetscSNPrintf(funcstring, sizeof(funcstring), "VecTagger%sSetSubs()", name));
97 PetscCall(PetscSNPrintf(descstring, sizeof(descstring), "number of sub tags in %s tag", name));
98 PetscOptionsHeadBegin(PetscOptionsObject, headstring);
99 PetscCall(PetscOptionsInt("-vec_tagger_num_subs", descstring, funcstring, nsubs, &nsubs, NULL));
100 PetscOptionsHeadEnd();
101 if (nsubs != nsubsOrig) {
102 PetscCall(VecTaggerSetSubs_AndOr(tagger, nsubs, NULL, PETSC_OWN_POINTER));
103 PetscCall(VecTaggerGetSubs_AndOr(tagger, NULL, &subs));
104 for (i = 0; i < nsubs; i++) PetscCall(VecTaggerSetFromOptions(subs[i]));
105 }
106 PetscFunctionReturn(PETSC_SUCCESS);
107 }
108
VecTaggerSetUp_AndOr(VecTagger tagger)109 static PetscErrorCode VecTaggerSetUp_AndOr(VecTagger tagger)
110 {
111 PetscInt nsubs, i;
112 VecTagger *subs;
113
114 PetscFunctionBegin;
115 PetscCall(VecTaggerGetSubs_AndOr(tagger, &nsubs, &subs));
116 PetscCheck(nsubs, PetscObjectComm((PetscObject)tagger), PETSC_ERR_ARG_WRONGSTATE, "Must set sub taggers before calling setup.");
117 for (i = 0; i < nsubs; i++) PetscCall(VecTaggerSetUp(subs[i]));
118 PetscFunctionReturn(PETSC_SUCCESS);
119 }
120
VecTaggerView_AndOr(VecTagger tagger,PetscViewer viewer)121 static PetscErrorCode VecTaggerView_AndOr(VecTagger tagger, PetscViewer viewer)
122 {
123 PetscBool isascii;
124
125 PetscFunctionBegin;
126 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
127 if (isascii) {
128 PetscInt i, nsubs;
129 VecTagger *subs;
130 const char *name;
131
132 PetscCall(VecTaggerGetSubs_AndOr(tagger, &nsubs, &subs));
133 PetscCall(PetscObjectGetType((PetscObject)tagger, &name));
134 PetscCall(PetscViewerASCIIPrintf(viewer, " %s of %" PetscInt_FMT " subtags:\n", name, nsubs));
135 PetscCall(PetscViewerASCIIPushTab(viewer));
136 for (i = 0; i < nsubs; i++) PetscCall(VecTaggerView(subs[i], viewer));
137 PetscCall(PetscViewerASCIIPopTab(viewer));
138 }
139 PetscFunctionReturn(PETSC_SUCCESS);
140 }
141
VecTaggerCreate_AndOr(VecTagger tagger)142 PetscErrorCode VecTaggerCreate_AndOr(VecTagger tagger)
143 {
144 VecTagger_AndOr *andOr;
145
146 PetscFunctionBegin;
147 tagger->ops->destroy = VecTaggerDestroy_AndOr;
148 tagger->ops->setfromoptions = VecTaggerSetFromOptions_AndOr;
149 tagger->ops->setup = VecTaggerSetUp_AndOr;
150 tagger->ops->view = VecTaggerView_AndOr;
151 tagger->ops->computeis = VecTaggerComputeIS_FromBoxes;
152 PetscCall(PetscNew(&andOr));
153 tagger->data = andOr;
154 PetscFunctionReturn(PETSC_SUCCESS);
155 }
156
VecTaggerAndOrIsSubBox_Private(PetscInt bs,const VecTaggerBox * superBox,const VecTaggerBox * subBox,PetscBool * isSub)157 PetscErrorCode VecTaggerAndOrIsSubBox_Private(PetscInt bs, const VecTaggerBox *superBox, const VecTaggerBox *subBox, PetscBool *isSub)
158 {
159 PetscInt i;
160
161 PetscFunctionBegin;
162 *isSub = PETSC_TRUE;
163 for (i = 0; i < bs; i++) {
164 #if !defined(PETSC_USE_COMPLEX)
165 if (superBox[i].min > subBox[i].min || superBox[i].max < subBox[i].max) {
166 *isSub = PETSC_FALSE;
167 break;
168 }
169 #else
170 if (PetscRealPart(superBox[i].min) > PetscRealPart(subBox[i].min) || PetscImaginaryPart(superBox[i].min) > PetscImaginaryPart(subBox[i].min) || PetscRealPart(superBox[i].max) < PetscRealPart(subBox[i].max) ||
171 PetscImaginaryPart(superBox[i].max) < PetscImaginaryPart(subBox[i].max)) {
172 *isSub = PETSC_FALSE;
173 break;
174 }
175 #endif
176 }
177 PetscFunctionReturn(PETSC_SUCCESS);
178 }
179
VecTaggerAndOrIntersect_Private(PetscInt bs,const VecTaggerBox * a,const VecTaggerBox * b,VecTaggerBox * c,PetscBool * empty)180 PetscErrorCode VecTaggerAndOrIntersect_Private(PetscInt bs, const VecTaggerBox *a, const VecTaggerBox *b, VecTaggerBox *c, PetscBool *empty)
181 {
182 PetscInt i;
183
184 PetscFunctionBegin;
185 *empty = PETSC_FALSE;
186 for (i = 0; i < bs; i++) {
187 #if !defined(PETSC_USE_COMPLEX)
188 c[i].min = PetscMax(a[i].min, b[i].min);
189 c[i].max = PetscMin(a[i].max, b[i].max);
190 if (c[i].max < c[i].min) {
191 *empty = PETSC_TRUE;
192 break;
193 }
194 #else
195 {
196 PetscReal maxMinReal = PetscMax(PetscRealPart(a[i].min), PetscRealPart(b[i].min));
197 PetscReal maxMinImag = PetscMax(PetscImaginaryPart(a[i].min), PetscImaginaryPart(b[i].min));
198 PetscReal minMaxReal = PetscMin(PetscRealPart(a[i].max), PetscRealPart(b[i].max));
199 PetscReal minMaxImag = PetscMin(PetscImaginaryPart(a[i].max), PetscImaginaryPart(b[i].max));
200
201 c[i].min = PetscCMPLX(maxMinReal, maxMinImag);
202 c[i].max = PetscCMPLX(minMaxReal, minMaxImag);
203 if ((PetscRealPart(c[i].max - c[i].min) < 0.) || (PetscImaginaryPart(c[i].max - c[i].min) < 0.)) {
204 *empty = PETSC_TRUE;
205 break;
206 }
207 }
208 #endif
209 }
210 PetscFunctionReturn(PETSC_SUCCESS);
211 }
212