Actual source code: or.c
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 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: VecTaggerOrSetSubs()
20: @*/
21: PetscErrorCode VecTaggerOrGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
22: {
23: VecTaggerGetSubs_AndOr(tagger,nsubs,subs);
24: return 0;
25: }
27: /*@C
28: VecTaggerOrSetSubs - Set the sub VecTaggers whose union 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: VecTaggerOrSetSubs()
40: @*/
41: PetscErrorCode VecTaggerOrSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
42: {
43: VecTaggerSetSubs_AndOr(tagger,nsubs,subs,mode);
44: return 0;
45: }
47: static PetscErrorCode VecTaggerComputeBoxes_Or(VecTagger tagger,Vec vec,PetscInt *numBoxes,VecTaggerBox **boxes,PetscBool *listed)
48: {
49: PetscInt i, bs, nsubs, *numSubBoxes, nboxes, total;
50: VecTaggerBox **subBoxes;
51: VecTagger *subs;
52: VecTaggerBox *bxs;
53: PetscBool boxlisted;
55: VecTaggerGetBlockSize(tagger,&bs);
56: VecTaggerOrGetSubs(tagger,&nsubs,&subs);
57: PetscMalloc2(nsubs,&numSubBoxes,nsubs,&subBoxes);
58: for (i = 0, total = 0; i < nsubs; i++) {
59: VecTaggerComputeBoxes(subs[i],vec,&numSubBoxes[i],&subBoxes[i],&boxlisted);
60: if (!boxlisted) { /* no support, clean up and exit */
61: PetscInt j;
63: for (j = 0; j < i; j++) {
64: PetscFree(subBoxes[j]);
65: }
66: PetscFree2(numSubBoxes,subBoxes);
67: if (listed) *listed = PETSC_FALSE;
68: }
69: total += numSubBoxes[i];
70: }
71: PetscMalloc1(bs * total, &bxs);
72: for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^2) check to remove subboxes */
73: PetscInt j;
75: for (j = 0; j < numSubBoxes[i]; j++) {
76: PetscInt k;
77: VecTaggerBox *subBox = &subBoxes[i][j*bs];
79: for (k = 0; k < nboxes; k++) {
80: PetscBool isSub = PETSC_FALSE;
82: VecTaggerBox *prevBox = &bxs[bs * k];
83: VecTaggerAndOrIsSubBox_Private(bs,prevBox,subBox,&isSub);
84: if (isSub) break;
85: VecTaggerAndOrIsSubBox_Private(bs,subBox,prevBox,&isSub);
86: if (isSub) {
87: PetscInt l;
89: for (l = 0; l < bs; l++) prevBox[l] = subBox[l];
90: break;
91: }
92: }
93: if (k < nboxes) continue;
94: for (k = 0; k < bs; k++) bxs[nboxes * bs + k] = subBox[k];
95: nboxes++;
96: }
97: PetscFree(subBoxes[i]);
98: }
99: PetscFree2(numSubBoxes,subBoxes);
100: *numBoxes = nboxes;
101: *boxes = bxs;
102: if (listed) *listed = PETSC_TRUE;
103: return 0;
104: }
106: static PetscErrorCode VecTaggerComputeIS_Or(VecTagger tagger, Vec vec, IS *is,PetscBool *listed)
107: {
108: PetscInt nsubs, i;
109: VecTagger *subs;
110: IS unionIS;
111: PetscBool boxlisted;
113: VecTaggerComputeIS_FromBoxes(tagger,vec,is,&boxlisted);
114: if (boxlisted) {
115: if (listed) *listed = PETSC_TRUE;
116: return 0;
117: }
118: VecTaggerOrGetSubs(tagger,&nsubs,&subs);
119: ISCreateGeneral(PetscObjectComm((PetscObject)vec),0,NULL,PETSC_OWN_POINTER,&unionIS);
120: for (i = 0; i < nsubs; i++) {
121: IS subIS, newUnionIS;
123: VecTaggerComputeIS(subs[i],vec,&subIS,&boxlisted);
125: ISExpand(unionIS,subIS,&newUnionIS);
126: ISSort(newUnionIS);
127: ISDestroy(&unionIS);
128: unionIS = newUnionIS;
129: ISDestroy(&subIS);
130: }
131: *is = unionIS;
132: if (listed) *listed = PETSC_TRUE;
133: return 0;
134: }
136: PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
137: {
138: VecTaggerCreate_AndOr(tagger);
139: tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
140: tagger->ops->computeis = VecTaggerComputeIS_Or;
141: return 0;
142: }