Actual source code: andor.c
petsc-3.9.4 2018-09-11
1: #include <petsc/private/vecimpl.h>
2: #include "../src/vec/vec/utils/tagger/impls/andor.h"
4: static PetscErrorCode VecTaggerDestroy_AndOr(VecTagger tagger)
5: {
6: VecTagger_AndOr *andOr = (VecTagger_AndOr *) tagger->data;
7: PetscInt i;
8: PetscErrorCode ierr;
11: for (i = 0; i < andOr->nsubs; i++) {
12: VecTaggerDestroy(&andOr->subs[i]);
13: }
14: if (andOr->mode == PETSC_OWN_POINTER) {
15: PetscFree(andOr->subs);
16: }
17: PetscFree(tagger->data);
18: return(0);
19: }
21: PetscErrorCode VecTaggerGetSubs_AndOr(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
22: {
23: VecTagger_AndOr *andOr = (VecTagger_AndOr *) tagger->data;
27: if (nsubs) {
29: *nsubs = andOr->nsubs;
30: }
31: if (subs) {
33: *subs = andOr->subs;
34: }
35: return(0);
36: }
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;
47: if (nsubs == andOr->nsubs && subs == andOr->subs && mode != PETSC_COPY_VALUES) return(0);
48: if (subs) {
49: for (i = 0; i < nsubs; i++) {
50: PetscObjectReference((PetscObject)subs[i]);
51: }
52: }
53: for (i = 0; i < andOr->nsubs; i++) {
54: VecTaggerDestroy(&(andOr->subs[i]));
55: }
56: if (andOr->mode == PETSC_OWN_POINTER && andOr->subs != subs) {
57: PetscFree(andOr->subs);
58: }
59: andOr->nsubs = nsubs;
60: if (subs) {
61: if (mode == PETSC_COPY_VALUES) {
62: andOr->mode = PETSC_OWN_POINTER;
63: PetscMalloc1(nsubs,&(andOr->subs));
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: PetscObjectDereference((PetscObject)subs[i]);
72: }
73: }
74: } else {
75: MPI_Comm comm = PetscObjectComm((PetscObject)tagger);
76: PetscInt bs;
77: const char *prefix;
78: char tprefix[128];
80: VecTaggerGetBlockSize(tagger,&bs);
81: PetscObjectGetOptionsPrefix((PetscObject)tagger,&prefix);
82: andOr->mode = PETSC_OWN_POINTER;
83: PetscMalloc1(nsubs,&(andOr->subs));
84: for (i = 0; i < nsubs; i++) {
85: VecTagger sub;
87: PetscSNPrintf(tprefix,128,"sub_%D_",i);
88: VecTaggerCreate(comm,&sub);
89: VecTaggerSetBlockSize(sub,bs);
90: PetscObjectSetOptionsPrefix((PetscObject)sub,prefix);
91: PetscObjectAppendOptionsPrefix((PetscObject)sub,tprefix);
92: andOr->subs[i] = sub;
93: }
94: }
95: return(0);
96: }
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;
109: PetscObjectGetType((PetscObject)tagger,&name);
110: VecTaggerGetSubs_AndOr(tagger,&nsubs,NULL);
111: nsubsOrig = nsubs;
112: PetscSNPrintf(headstring,BUFSIZ,"VecTagger %s options",name);
113: PetscSNPrintf(funcstring,BUFSIZ,"VecTagger%sSetSubs()",name);
114: PetscSNPrintf(descstring,BUFSIZ,"number of sub tags in %s tag",name);
115: PetscOptionsHead(PetscOptionsObject,headstring);
116: PetscOptionsInt("-vec_tagger_num_subs",descstring,funcstring,nsubs,&nsubs,NULL);
117: PetscOptionsTail();
118: if (nsubs != nsubsOrig) {
119: VecTaggerSetSubs_AndOr(tagger,nsubs,NULL,PETSC_OWN_POINTER);
120: VecTaggerGetSubs_AndOr(tagger,NULL,&subs);
121: for (i = 0; i < nsubs; i++) {
122: VecTaggerSetFromOptions(subs[i]);
123: }
124: }
125: return(0);
126: }
128: static PetscErrorCode VecTaggerSetUp_AndOr (VecTagger tagger)
129: {
130: PetscInt nsubs, i;
131: VecTagger *subs;
132: PetscErrorCode ierr;
135: VecTaggerGetSubs_AndOr(tagger,&nsubs,&subs);
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: VecTaggerSetUp(subs[i]);
139: }
140: return(0);
141: }
143: static PetscErrorCode VecTaggerView_AndOr(VecTagger tagger, PetscViewer viewer)
144: {
145: PetscBool iascii;
146: PetscErrorCode ierr;
149: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
150: if (iascii) {
151: PetscInt i, nsubs;
152: VecTagger *subs;
153: const char *name;
155: VecTaggerGetSubs_AndOr(tagger,&nsubs,&subs);
156: PetscObjectGetType((PetscObject)tagger,&name);
157: PetscViewerASCIIPrintf(viewer," %s of %D subtags:\n",name,nsubs);
158: PetscViewerASCIIPushTab(viewer);
159: for (i = 0; i < nsubs; i++) {
160: VecTaggerView(subs[i],viewer);
161: }
162: PetscViewerASCIIPopTab(viewer);
163: }
164: return(0);
165: }
167: PetscErrorCode VecTaggerCreate_AndOr(VecTagger tagger)
168: {
169: VecTagger_AndOr *andOr;
170: PetscErrorCode ierr;
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: PetscNewLog(tagger,&andOr);
179: tagger->data = andOr;
180: return(0);
181: }
183: PetscErrorCode VecTaggerAndOrIsSubBox_Private(PetscInt bs, const VecTaggerBox *superBox, const VecTaggerBox *subBox,PetscBool *isSub)
184: {
185: PetscInt i;
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: return(0);
204: }
206: PetscErrorCode VecTaggerAndOrIntersect_Private(PetscInt bs, const VecTaggerBox *a, const VecTaggerBox *b,VecTaggerBox *c,PetscBool *empty)
207: {
208: PetscInt i;
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));
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: return(0);
237: }