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