Actual source code: andor.c
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;
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: }
16: PetscErrorCode VecTaggerGetSubs_AndOr(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
17: {
18: VecTagger_AndOr *andOr = (VecTagger_AndOr *)tagger->data;
20: PetscFunctionBegin;
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: }
33: PetscErrorCode VecTaggerSetSubs_AndOr(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
34: {
35: PetscInt i;
36: VecTagger_AndOr *andOr = (VecTagger_AndOr *)tagger->data;
38: PetscFunctionBegin;
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];
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;
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: }
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;
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: }
109: static PetscErrorCode VecTaggerSetUp_AndOr(VecTagger tagger)
110: {
111: PetscInt nsubs, i;
112: VecTagger *subs;
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: }
121: static PetscErrorCode VecTaggerView_AndOr(VecTagger tagger, PetscViewer viewer)
122: {
123: PetscBool iascii;
125: PetscFunctionBegin;
126: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
127: if (iascii) {
128: PetscInt i, nsubs;
129: VecTagger *subs;
130: const char *name;
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: }
142: PetscErrorCode VecTaggerCreate_AndOr(VecTagger tagger)
143: {
144: VecTagger_AndOr *andOr;
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: }
157: PetscErrorCode VecTaggerAndOrIsSubBox_Private(PetscInt bs, const VecTaggerBox *superBox, const VecTaggerBox *subBox, PetscBool *isSub)
158: {
159: PetscInt i;
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: }
180: PetscErrorCode VecTaggerAndOrIntersect_Private(PetscInt bs, const VecTaggerBox *a, const VecTaggerBox *b, VecTaggerBox *c, PetscBool *empty)
181: {
182: PetscInt i;
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));
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: }