Actual source code: or.c
petsc-3.11.0 2019-03-29
2: #include <petsc/private/vecimpl.h>
3: #include "../src/vec/vec/utils/tagger/impls/andor.h"
5: /*@C
6: VecTaggerOrGetSubs - Get the sub VecTaggers whose union 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: VecTaggerOrSetSubs()
20: @*/
21: PetscErrorCode VecTaggerOrGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
22: {
26: VecTaggerGetSubs_AndOr(tagger,nsubs,subs);
27: return(0);
28: }
30: /*@C
31: VecTaggerOrSetSubs - Set the sub VecTaggers whose union 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: VecTaggerOrSetSubs()
43: @*/
44: PetscErrorCode VecTaggerOrSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
45: {
49: VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);
50: return(0);
51: }
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;
62: VecTaggerGetBlockSize(tagger,&bs);
63: VecTaggerOrGetSubs(tagger,&nsubs,&subs);
64: PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);
65: for (i = 0, total = 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: total += numSubBoxes[i];
81: }
82: PetscMalloc1(bs * total, &bxs);
83: for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^2) check to remove subboxes */
84: PetscInt j;
86: for (j = 0; j < numSubBoxes[i]; j++) {
87: PetscInt k;
88: VecTaggerBox *subBox = &subBoxes[i][j*bs];
90: for (k = 0; k < nboxes; k++) {
91: PetscBool isSub = PETSC_FALSE;
93: VecTaggerBox *prevBox = &bxs[bs * k];
94: VecTaggerAndOrIsSubBox_Private(bs,prevBox,subBox,&isSub);
95: if (isSub) break;
96: VecTaggerAndOrIsSubBox_Private(bs,subBox,prevBox,&isSub);
97: if (isSub) {
98: PetscInt l;
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: PetscFree(subBoxes[i]);
109: }
110: PetscFree2(numSubBoxes,subBoxes);
111: *numBoxes = nboxes;
112: *boxes = bxs;
113: return(0);
114: }
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;
124: ierr2 = VecTaggerComputeIS_FromBoxes(tagger,vec,is);
125: if (ierr2 != PETSC_ERR_SUP) {
126: CHKERRQ(ierr2);
127: return(0);
128: }
129: VecTaggerOrGetSubs(tagger,&nsubs,&subs);
130: ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,&unionIS);
131: for (i = 0; i < nsubs; i++) {
132: IS subIS, newUnionIS;
134: VecTaggerComputeIS(subs[i],vec,&subIS);
135: ISExpand(unionIS,subIS,&newUnionIS);
136: ISSort(newUnionIS);
137: ISDestroy(&unionIS);
138: unionIS = newUnionIS;
139: ISDestroy(&subIS);
140: }
141: *is = unionIS;
142: return(0);
143: }
145: PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
146: {
150: VecTaggerCreate_AndOr(tagger);
151: tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
152: tagger->ops->computeis = VecTaggerComputeIS_Or;
153: return(0);
154: }