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   VecTaggerOrGetSubs - Get the sub VecTaggers whose union 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: VecTaggerOrSetSubs()
20 @*/
VecTaggerOrGetSubs(VecTagger tagger,PetscInt * nsubs,VecTagger ** subs)21 PetscErrorCode VecTaggerOrGetSubs(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   VecTaggerOrSetSubs - Set the sub VecTaggers whose union 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: VecTaggerOrSetSubs()
43 @*/
VecTaggerOrSetSubs(VecTagger tagger,PetscInt nsubs,VecTagger * subs,PetscCopyMode mode)44 PetscErrorCode VecTaggerOrSetSubs(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_Or(VecTagger tagger,Vec vec,PetscInt * numBoxes,VecTaggerBox ** boxes)53 static PetscErrorCode VecTaggerComputeBoxes_Or(VecTagger tagger,Vec vec,PetscInt *numBoxes,VecTaggerBox **boxes)
54 {
55   PetscInt        i, bs, nsubs, *numSubBoxes, nboxes, total;
56   VecTaggerBox    **subBoxes;
57   VecTagger       *subs;
58   VecTaggerBox    *bxs;
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, total = 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     total += numSubBoxes[i];
81   }
82   ierr = PetscMalloc1(bs * total, &bxs);CHKERRQ(ierr);
83   for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^2) check to remove subboxes */
84     PetscInt j;
85 
86     for (j = 0; j < numSubBoxes[i]; j++) {
87       PetscInt     k;
88       VecTaggerBox *subBox = &subBoxes[i][j*bs];
89 
90       for (k = 0; k < nboxes; k++) {
91         PetscBool   isSub = PETSC_FALSE;
92 
93         VecTaggerBox *prevBox = &bxs[bs * k];
94         ierr = VecTaggerAndOrIsSubBox_Private(bs,prevBox,subBox,&isSub);CHKERRQ(ierr);
95         if (isSub) break;
96         ierr = VecTaggerAndOrIsSubBox_Private(bs,subBox,prevBox,&isSub);CHKERRQ(ierr);
97         if (isSub) {
98           PetscInt l;
99 
100           for (l = 0; l < bs; l++) prevBox[l] = subBox[l];
101           break;
102         }
103       }
104       if (k < nboxes) continue;
105       for (k = 0; k < bs; k++) bxs[nboxes * bs + k] = subBox[k];
106       nboxes++;
107     }
108     ierr = PetscFree(subBoxes[i]);CHKERRQ(ierr);
109   }
110   ierr = PetscFree2(numSubBoxes,subBoxes);CHKERRQ(ierr);
111   *numBoxes = nboxes;
112   *boxes = bxs;
113   PetscFunctionReturn(0);
114 }
115 
VecTaggerComputeIS_Or(VecTagger tagger,Vec vec,IS * is)116 static PetscErrorCode VecTaggerComputeIS_Or(VecTagger tagger, Vec vec, IS *is)
117 {
118   PetscInt       nsubs, i;
119   VecTagger      *subs;
120   IS             unionIS;
121   PetscErrorCode ierr, ierr2;
122 
123   PetscFunctionBegin;
124   ierr2 = VecTaggerComputeIS_FromBoxes(tagger,vec,is);
125   if (ierr2 != PETSC_ERR_SUP) {
126     CHKERRQ(ierr2);
127     PetscFunctionReturn(0);
128   }
129   ierr = VecTaggerOrGetSubs(tagger,&nsubs,&subs);CHKERRQ(ierr);
130   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,&unionIS);CHKERRQ(ierr);
131   for (i = 0; i < nsubs; i++) {
132     IS subIS, newUnionIS;
133 
134     ierr = VecTaggerComputeIS(subs[i],vec,&subIS);CHKERRQ(ierr);
135     ierr = ISExpand(unionIS,subIS,&newUnionIS);CHKERRQ(ierr);
136     ierr = ISSort(newUnionIS);CHKERRQ(ierr);
137     ierr = ISDestroy(&unionIS);CHKERRQ(ierr);
138     unionIS = newUnionIS;
139     ierr = ISDestroy(&subIS);CHKERRQ(ierr);
140   }
141   *is = unionIS;
142   PetscFunctionReturn(0);
143 }
144 
VecTaggerCreate_Or(VecTagger tagger)145 PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
146 {
147   PetscErrorCode ierr;
148 
149   PetscFunctionBegin;
150   ierr = VecTaggerCreate_AndOr(tagger);CHKERRQ(ierr);
151   tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
152   tagger->ops->computeis        = VecTaggerComputeIS_Or;
153   PetscFunctionReturn(0);
154 }
155