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++) PetscFree(subBoxes[j]);
64: PetscFree2(numSubBoxes, subBoxes);
65: if (listed) *listed = PETSC_FALSE;
66: }
67: total += numSubBoxes[i];
68: }
69: PetscMalloc1(bs * total, &bxs);
70: for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^2) check to remove subboxes */
71: PetscInt j;
73: for (j = 0; j < numSubBoxes[i]; j++) {
74: PetscInt k;
75: VecTaggerBox *subBox = &subBoxes[i][j * bs];
77: for (k = 0; k < nboxes; k++) {
78: PetscBool isSub = PETSC_FALSE;
80: VecTaggerBox *prevBox = &bxs[bs * k];
81: VecTaggerAndOrIsSubBox_Private(bs, prevBox, subBox, &isSub);
82: if (isSub) break;
83: VecTaggerAndOrIsSubBox_Private(bs, subBox, prevBox, &isSub);
84: if (isSub) {
85: PetscInt l;
87: for (l = 0; l < bs; l++) prevBox[l] = subBox[l];
88: break;
89: }
90: }
91: if (k < nboxes) continue;
92: for (k = 0; k < bs; k++) bxs[nboxes * bs + k] = subBox[k];
93: nboxes++;
94: }
95: PetscFree(subBoxes[i]);
96: }
97: PetscFree2(numSubBoxes, subBoxes);
98: *numBoxes = nboxes;
99: *boxes = bxs;
100: if (listed) *listed = PETSC_TRUE;
101: return 0;
102: }
104: static PetscErrorCode VecTaggerComputeIS_Or(VecTagger tagger, Vec vec, IS *is, PetscBool *listed)
105: {
106: PetscInt nsubs, i;
107: VecTagger *subs;
108: IS unionIS;
109: PetscBool boxlisted;
111: VecTaggerComputeIS_FromBoxes(tagger, vec, is, &boxlisted);
112: if (boxlisted) {
113: if (listed) *listed = PETSC_TRUE;
114: return 0;
115: }
116: VecTaggerOrGetSubs(tagger, &nsubs, &subs);
117: ISCreateGeneral(PetscObjectComm((PetscObject)vec), 0, NULL, PETSC_OWN_POINTER, &unionIS);
118: for (i = 0; i < nsubs; i++) {
119: IS subIS, newUnionIS;
121: VecTaggerComputeIS(subs[i], vec, &subIS, &boxlisted);
123: ISExpand(unionIS, subIS, &newUnionIS);
124: ISSort(newUnionIS);
125: ISDestroy(&unionIS);
126: unionIS = newUnionIS;
127: ISDestroy(&subIS);
128: }
129: *is = unionIS;
130: if (listed) *listed = PETSC_TRUE;
131: return 0;
132: }
134: PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
135: {
136: VecTaggerCreate_AndOr(tagger);
137: tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
138: tagger->ops->computeis = VecTaggerComputeIS_Or;
139: return 0;
140: }