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