Actual source code: and.c
2: #include <petsc/private/vecimpl.h>
3: #include "../src/vec/vec/utils/tagger/impls/andor.h"
5: /*@C
6: VecTaggerAndGetSubs - Get the sub VecTaggers whose intersection defines the outer VecTagger
8: Not collective
10: Input Parameter:
11: . tagger - the VecTagger context
13: Output Parameters:
14: + nsubs - the number of sub VecTaggers
15: - subs - the sub VecTaggers
17: Level: advanced
19: .seealso: `VecTaggerAndSetSubs()`
20: @*/
21: PetscErrorCode VecTaggerAndGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
22: {
23: VecTaggerGetSubs_AndOr(tagger, nsubs, subs);
24: return 0;
25: }
27: /*@C
28: VecTaggerAndSetSubs - Set the sub VecTaggers whose intersection defines the outer VecTagger
30: Logically collective
32: Input Parameters:
33: + tagger - the VecTagger context
34: . nsubs - the number of sub VecTaggers
35: - subs - the sub VecTaggers
37: Level: advanced
39: .seealso: `VecTaggerAndSetSubs()`
40: @*/
41: PetscErrorCode VecTaggerAndSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
42: {
43: VecTaggerSetSubs_AndOr(tagger, nsubs, subs, mode);
44: return 0;
45: }
47: static PetscErrorCode VecTaggerComputeBoxes_And(VecTagger tagger, Vec vec, PetscInt *numBoxes, VecTaggerBox **boxes, PetscBool *listed)
48: {
49: PetscInt i, bs, nsubs, *numSubBoxes, nboxes;
50: VecTaggerBox **subBoxes;
51: VecTagger *subs;
52: VecTaggerBox *bxs = NULL;
53: PetscBool sublisted;
55: VecTaggerGetBlockSize(tagger, &bs);
56: VecTaggerOrGetSubs(tagger, &nsubs, &subs);
57: PetscMalloc2(nsubs, &numSubBoxes, nsubs, &subBoxes);
58: for (i = 0; i < nsubs; i++) {
59: VecTaggerComputeBoxes(subs[i], vec, &numSubBoxes[i], &subBoxes[i], &sublisted);
60: if (!sublisted) {
61: PetscInt j;
63: for (j = 0; j < i; j++) PetscFree(subBoxes[j]);
64: PetscFree2(numSubBoxes, subBoxes);
65: *listed = PETSC_FALSE;
66: return 0;
67: }
68: }
69: for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^3) check to intersect boxes */
70: VecTaggerBox *isect;
71: PetscInt j, k, l, m, n;
73: n = numSubBoxes[i];
74: if (!n) {
75: nboxes = 0;
76: PetscFree(bxs);
77: break;
78: }
79: if (!i) {
80: PetscMalloc1(n * bs, &bxs);
81: for (j = 0; j < numSubBoxes[i] * bs; j++) bxs[j] = subBoxes[i][j];
82: nboxes = n;
83: PetscFree(subBoxes[i]);
84: continue;
85: }
86: PetscMalloc1(n * nboxes * bs, &isect);
87: for (j = 0, l = 0; j < n; j++) {
88: VecTaggerBox *subBox = &subBoxes[i][j * bs];
90: for (k = 0; k < nboxes; k++) {
91: PetscBool isEmpty;
92: VecTaggerBox *prevBox = &bxs[bs * k];
94: VecTaggerAndOrIntersect_Private(bs, prevBox, subBox, &isect[l * bs], &isEmpty);
95: if (isEmpty) continue;
96: for (m = 0; m < l; m++) {
97: PetscBool isSub = PETSC_FALSE;
99: VecTaggerAndOrIsSubBox_Private(bs, &isect[m * bs], &isect[l * bs], &isSub);
100: if (isSub) break;
101: VecTaggerAndOrIsSubBox_Private(bs, &isect[l * bs], &isect[m * bs], &isSub);
102: if (isSub) {
103: PetscInt r;
105: for (r = 0; r < bs; r++) isect[m * bs + r] = isect[l * bs + r];
106: break;
107: }
108: }
109: if (m == l) l++;
110: }
111: }
112: PetscFree(bxs);
113: bxs = isect;
114: nboxes = l;
115: PetscFree(subBoxes[i]);
116: }
117: PetscFree2(numSubBoxes, subBoxes);
118: *numBoxes = nboxes;
119: *boxes = bxs;
120: if (listed) *listed = PETSC_TRUE;
121: return 0;
122: }
124: static PetscErrorCode VecTaggerComputeIS_And(VecTagger tagger, Vec vec, IS *is, PetscBool *listed)
125: {
126: PetscInt nsubs, i;
127: VecTagger *subs;
128: IS isectIS;
129: PetscBool boxlisted;
131: VecTaggerComputeIS_FromBoxes(tagger, vec, is, &boxlisted);
132: if (boxlisted) {
133: if (listed) *listed = PETSC_TRUE;
134: return 0;
135: }
136: VecTaggerOrGetSubs(tagger, &nsubs, &subs);
137: if (!nsubs) {
138: ISCreateGeneral(PetscObjectComm((PetscObject)vec), 0, NULL, PETSC_OWN_POINTER, is);
139: return 0;
140: }
141: VecTaggerComputeIS(subs[0], vec, &isectIS, &boxlisted);
143: for (i = 1; i < nsubs; i++) {
144: IS subIS, newIsectIS;
146: VecTaggerComputeIS(subs[i], vec, &subIS, &boxlisted);
148: ISIntersect(isectIS, subIS, &newIsectIS);
149: ISDestroy(&isectIS);
150: ISDestroy(&subIS);
151: isectIS = newIsectIS;
152: }
153: *is = isectIS;
154: if (listed) *listed = PETSC_TRUE;
155: return 0;
156: }
158: PETSC_INTERN PetscErrorCode VecTaggerCreate_And(VecTagger tagger)
159: {
160: VecTaggerCreate_AndOr(tagger);
161: tagger->ops->computeboxes = VecTaggerComputeBoxes_And;
162: tagger->ops->computeis = VecTaggerComputeIS_And;
163: return 0;
164: }