Actual source code: and.c
petsc-3.12.0 2019-09-29
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 Arguments:
11: . tagger - the VecTagger context
13: Output Arguments:
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: {
26: VecTaggerGetSubs_AndOr(tagger,nsubs,subs);
27: return(0);
28: }
30: /*@C
31: VecTaggerAndSetSubs - Set the sub VecTaggers whose intersection defines the outer VecTagger
33: Logically collective
35: Input Arguments:
36: + tagger - the VecTagger context
37: . nsubs - the number of sub VecTaggers
38: - subs - the sub VecTaggers
40: Level: advanced
42: .seealso: VecTaggerAndSetSubs()
43: @*/
44: PetscErrorCode VecTaggerAndSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
45: {
49: VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);
50: return(0);
51: }
53: static PetscErrorCode VecTaggerComputeBoxes_And(VecTagger tagger,Vec vec,PetscInt *numBoxes,VecTaggerBox **boxes)
54: {
55: PetscInt i, bs, nsubs, *numSubBoxes, nboxes;
56: VecTaggerBox **subBoxes;
57: VecTagger *subs;
58: VecTaggerBox *bxs = NULL;
59: PetscErrorCode ierr;
62: VecTaggerGetBlockSize(tagger,&bs);
63: VecTaggerOrGetSubs(tagger,&nsubs,&subs);
64: PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);
65: for (i = 0; i < nsubs; i++) {
66: PetscErrorCode ierr2;
68: ierr2 = VecTaggerComputeBoxes(subs[i],vec,&numSubBoxes[i],&subBoxes[i]);
69: if (ierr2 == PETSC_ERR_SUP) { /* no support, clean up and exit */
70: PetscInt j;
72: for (j = 0; j < i; j++) {
73: PetscFree(subBoxes[j]);
74: }
75: PetscFree2(numSubBoxes,subBoxes);
76: SETERRQ(PetscObjectComm((PetscObject)tagger),PETSC_ERR_SUP,"Sub tagger does not support box computation");
77: } else {
78: CHKERRQ(ierr2);
79: }
80: }
81: for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^3) check to intersect boxes */
82: VecTaggerBox *isect;
83: PetscInt j, k, l, m, n;
85: n = numSubBoxes[i];
86: if (!n) {
87: nboxes = 0;
88: PetscFree(bxs);
89: break;
90: }
91: if (!i) {
92: PetscMalloc1(n * bs, &bxs);
93: for (j = 0; j < numSubBoxes[i] * bs; j++) bxs[j] = subBoxes[i][j];
94: nboxes = n;
95: PetscFree(subBoxes[i]);
96: continue;
97: }
98: PetscMalloc1(n * nboxes * bs,&isect);
99: for (j = 0, l = 0; j < n; j++) {
100: VecTaggerBox *subBox = &subBoxes[i][j*bs];
102: for (k = 0; k < nboxes; k++) {
103: PetscBool isEmpty;
104: VecTaggerBox *prevBox = &bxs[bs*k];
106: VecTaggerAndOrIntersect_Private(bs,prevBox,subBox,&isect[l * bs],&isEmpty);
107: if (isEmpty) continue;
108: for (m = 0; m < l; m++) {
109: PetscBool isSub = PETSC_FALSE;
111: VecTaggerAndOrIsSubBox_Private(bs,&isect[m*bs],&isect[l*bs],&isSub);
112: if (isSub) break;
113: VecTaggerAndOrIsSubBox_Private(bs,&isect[l*bs],&isect[m*bs],&isSub);
114: if (isSub) {
115: PetscInt r;
117: for (r = 0; r < bs; r++) isect[m*bs + r] = isect[l * bs + r];
118: break;
119: }
120: }
121: if (m == l) l++;
122: }
123: }
124: PetscFree(bxs);
125: bxs = isect;
126: nboxes = l;
127: PetscFree(subBoxes[i]);
128: }
129: PetscFree2(numSubBoxes,subBoxes);
130: *numBoxes = nboxes;
131: *boxes = bxs;
132: return(0);
133: }
135: static PetscErrorCode VecTaggerComputeIS_And(VecTagger tagger, Vec vec, IS *is)
136: {
137: PetscInt nsubs, i;
138: VecTagger *subs;
139: IS isectIS;
140: PetscErrorCode ierr, ierr2;
143: ierr2 = VecTaggerComputeIS_FromBoxes(tagger,vec,is);
144: if (ierr2 != PETSC_ERR_SUP) {
145: CHKERRQ(ierr2);
146: return(0);
147: }
148: VecTaggerOrGetSubs(tagger,&nsubs,&subs);
149: if (!nsubs) {
150: ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,is);
151: return(0);
152: }
153: VecTaggerComputeIS(subs[0],vec,&isectIS);
154: for (i = 1; i < nsubs; i++) {
155: IS subIS, newIsectIS;
157: VecTaggerComputeIS(subs[i],vec,&subIS);
158: ISIntersect(isectIS,subIS,&newIsectIS);
159: ISDestroy(&isectIS);
160: ISDestroy(&subIS);
161: isectIS = newIsectIS;
162: }
163: *is = isectIS;
164: return(0);
165: }
167: PETSC_INTERN PetscErrorCode VecTaggerCreate_And(VecTagger tagger)
168: {
172: VecTaggerCreate_AndOr(tagger);
173: tagger->ops->computeboxes = VecTaggerComputeBoxes_And;
174: tagger->ops->computeis = VecTaggerComputeIS_And;
175: return(0);
176: }