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