1 
2 #include <petsc/private/vecimpl.h> /*I "petscvec.h" I*/
3 #include "../src/vec/vec/utils/tagger/impls/andor.h"
4 
5 /*@C
6   VecTaggerAndGetSubs - Get the sub VecTaggers whose intersection defines the outer VecTagger
7 
8   Not collective
9 
10   Input Arguments:
11 . tagger - the VecTagger context
12 
13   Output Arguments:
14 + nsubs - the number of sub VecTaggers
15 - subs - the sub VecTaggers
16 
17   Level: advanced
18 
19 .seealso: VecTaggerAndSetSubs()
20 @*/
VecTaggerAndGetSubs(VecTagger tagger,PetscInt * nsubs,VecTagger ** subs)21 PetscErrorCode VecTaggerAndGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
22 {
23   PetscErrorCode ierr;
24 
25   PetscFunctionBegin;
26   ierr = VecTaggerGetSubs_AndOr(tagger,nsubs,subs);CHKERRQ(ierr);
27   PetscFunctionReturn(0);
28 }
29 
30 /*@C
31   VecTaggerAndSetSubs - Set the sub VecTaggers whose intersection defines the outer VecTagger
32 
33   Logically collective
34 
35   Input Arguments:
36 + tagger - the VecTagger context
37 . nsubs - the number of sub VecTaggers
38 - subs - the sub VecTaggers
39 
40   Level: advanced
41 
42 .seealso: VecTaggerAndSetSubs()
43 @*/
VecTaggerAndSetSubs(VecTagger tagger,PetscInt nsubs,VecTagger * subs,PetscCopyMode mode)44 PetscErrorCode VecTaggerAndSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
45 {
46   PetscErrorCode ierr;
47 
48   PetscFunctionBegin;
49   ierr = VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);CHKERRQ(ierr);
50   PetscFunctionReturn(0);
51 }
52 
VecTaggerComputeBoxes_And(VecTagger tagger,Vec vec,PetscInt * numBoxes,VecTaggerBox ** boxes)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;
60 
61   PetscFunctionBegin;
62   ierr = VecTaggerGetBlockSize(tagger,&bs);CHKERRQ(ierr);
63   ierr = VecTaggerOrGetSubs(tagger,&nsubs,&subs);CHKERRQ(ierr);
64   ierr = PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);CHKERRQ(ierr);
65   for (i = 0; i < nsubs; i++) {
66     PetscErrorCode ierr2;
67 
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;
71 
72       for (j = 0; j < i; j++) {
73         ierr = PetscFree(subBoxes[j]);CHKERRQ(ierr);
74       }
75       ierr = PetscFree2(numSubBoxes,subBoxes);CHKERRQ(ierr);
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;
84 
85     n = numSubBoxes[i];
86     if (!n) {
87       nboxes = 0;
88       ierr = PetscFree(bxs);CHKERRQ(ierr);
89       break;
90     }
91     if (!i) {
92       ierr = PetscMalloc1(n * bs, &bxs);CHKERRQ(ierr);
93       for (j = 0; j < numSubBoxes[i] * bs; j++) bxs[j] = subBoxes[i][j];
94       nboxes = n;
95       ierr = PetscFree(subBoxes[i]);CHKERRQ(ierr);
96       continue;
97     }
98     ierr = PetscMalloc1(n * nboxes * bs,&isect);CHKERRQ(ierr);
99     for (j = 0, l = 0; j < n; j++) {
100       VecTaggerBox *subBox = &subBoxes[i][j*bs];
101 
102       for (k = 0; k < nboxes; k++) {
103         PetscBool    isEmpty;
104         VecTaggerBox *prevBox = &bxs[bs*k];
105 
106         ierr = VecTaggerAndOrIntersect_Private(bs,prevBox,subBox,&isect[l * bs],&isEmpty);CHKERRQ(ierr);
107         if (isEmpty) continue;
108         for (m = 0; m < l; m++) {
109           PetscBool isSub = PETSC_FALSE;
110 
111           ierr = VecTaggerAndOrIsSubBox_Private(bs,&isect[m*bs],&isect[l*bs],&isSub);CHKERRQ(ierr);
112           if (isSub) break;
113           ierr = VecTaggerAndOrIsSubBox_Private(bs,&isect[l*bs],&isect[m*bs],&isSub);CHKERRQ(ierr);
114           if (isSub) {
115             PetscInt r;
116 
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     ierr = PetscFree(bxs);CHKERRQ(ierr);
125     bxs = isect;
126     nboxes = l;
127     ierr = PetscFree(subBoxes[i]);CHKERRQ(ierr);
128   }
129   ierr = PetscFree2(numSubBoxes,subBoxes);CHKERRQ(ierr);
130   *numBoxes = nboxes;
131   *boxes = bxs;
132   PetscFunctionReturn(0);
133 }
134 
VecTaggerComputeIS_And(VecTagger tagger,Vec vec,IS * is)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;
141 
142   PetscFunctionBegin;
143   ierr2 = VecTaggerComputeIS_FromBoxes(tagger,vec,is);
144   if (ierr2 != PETSC_ERR_SUP) {
145     CHKERRQ(ierr2);
146     PetscFunctionReturn(0);
147   }
148   ierr = VecTaggerOrGetSubs(tagger,&nsubs,&subs);CHKERRQ(ierr);
149   if (!nsubs) {
150     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,is);CHKERRQ(ierr);
151     PetscFunctionReturn(0);
152   }
153   ierr = VecTaggerComputeIS(subs[0],vec,&isectIS);CHKERRQ(ierr);
154   for (i = 1; i < nsubs; i++) {
155     IS subIS, newIsectIS;
156 
157     ierr = VecTaggerComputeIS(subs[i],vec,&subIS);CHKERRQ(ierr);
158     ierr = ISIntersect(isectIS,subIS,&newIsectIS);CHKERRQ(ierr);
159     ierr = ISDestroy(&isectIS);CHKERRQ(ierr);
160     ierr = ISDestroy(&subIS);CHKERRQ(ierr);
161     isectIS = newIsectIS;
162   }
163   *is = isectIS;
164   PetscFunctionReturn(0);
165 }
166 
VecTaggerCreate_And(VecTagger tagger)167 PETSC_INTERN PetscErrorCode VecTaggerCreate_And(VecTagger tagger)
168 {
169   PetscErrorCode ierr;
170 
171   PetscFunctionBegin;
172   ierr = VecTaggerCreate_AndOr(tagger);CHKERRQ(ierr);
173   tagger->ops->computeboxes = VecTaggerComputeBoxes_And;
174   tagger->ops->computeis    = VecTaggerComputeIS_And;
175   PetscFunctionReturn(0);
176 }
177