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++) {
64: PetscFree(subBoxes[j]);
65: }
66: PetscFree2(numSubBoxes,subBoxes);
67: *listed = PETSC_FALSE;
68: return 0;
69: }
70: }
71: for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^3) check to intersect boxes */
72: VecTaggerBox *isect;
73: PetscInt j, k, l, m, n;
75: n = numSubBoxes[i];
76: if (!n) {
77: nboxes = 0;
78: PetscFree(bxs);
79: break;
80: }
81: if (!i) {
82: PetscMalloc1(n * bs, &bxs);
83: for (j = 0; j < numSubBoxes[i] * bs; j++) bxs[j] = subBoxes[i][j];
84: nboxes = n;
85: PetscFree(subBoxes[i]);
86: continue;
87: }
88: PetscMalloc1(n * nboxes * bs,&isect);
89: for (j = 0, l = 0; j < n; j++) {
90: VecTaggerBox *subBox = &subBoxes[i][j*bs];
92: for (k = 0; k < nboxes; k++) {
93: PetscBool isEmpty;
94: VecTaggerBox *prevBox = &bxs[bs*k];
96: VecTaggerAndOrIntersect_Private(bs,prevBox,subBox,&isect[l * bs],&isEmpty);
97: if (isEmpty) continue;
98: for (m = 0; m < l; m++) {
99: PetscBool isSub = PETSC_FALSE;
101: VecTaggerAndOrIsSubBox_Private(bs,&isect[m*bs],&isect[l*bs],&isSub);
102: if (isSub) break;
103: VecTaggerAndOrIsSubBox_Private(bs,&isect[l*bs],&isect[m*bs],&isSub);
104: if (isSub) {
105: PetscInt r;
107: for (r = 0; r < bs; r++) isect[m*bs + r] = isect[l * bs + r];
108: break;
109: }
110: }
111: if (m == l) l++;
112: }
113: }
114: PetscFree(bxs);
115: bxs = isect;
116: nboxes = l;
117: PetscFree(subBoxes[i]);
118: }
119: PetscFree2(numSubBoxes,subBoxes);
120: *numBoxes = nboxes;
121: *boxes = bxs;
122: if (listed) *listed = PETSC_TRUE;
123: return 0;
124: }
126: static PetscErrorCode VecTaggerComputeIS_And(VecTagger tagger, Vec vec, IS *is,PetscBool *listed)
127: {
128: PetscInt nsubs, i;
129: VecTagger *subs;
130: IS isectIS;
131: PetscBool boxlisted;
133: VecTaggerComputeIS_FromBoxes(tagger,vec,is,&boxlisted);
134: if (boxlisted) {
135: if (listed) *listed = PETSC_TRUE;
136: return 0;
137: }
138: VecTaggerOrGetSubs(tagger,&nsubs,&subs);
139: if (!nsubs) {
140: ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,is);
141: return 0;
142: }
143: VecTaggerComputeIS(subs[0],vec,&isectIS,&boxlisted);
145: for (i = 1; i < nsubs; i++) {
146: IS subIS, newIsectIS;
148: VecTaggerComputeIS(subs[i],vec,&subIS,&boxlisted);
150: ISIntersect(isectIS,subIS,&newIsectIS);
151: ISDestroy(&isectIS);
152: ISDestroy(&subIS);
153: isectIS = newIsectIS;
154: }
155: *is = isectIS;
156: if (listed) *listed = PETSC_TRUE;
157: return 0;
158: }
160: PETSC_INTERN PetscErrorCode VecTaggerCreate_And(VecTagger tagger)
161: {
162: VecTaggerCreate_AndOr(tagger);
163: tagger->ops->computeboxes = VecTaggerComputeBoxes_And;
164: tagger->ops->computeis = VecTaggerComputeIS_And;
165: return 0;
166: }