Actual source code: or.c
1: #include <petsc/private/vecimpl.h>
2: #include "../src/vec/vec/utils/tagger/impls/andor.h"
4: /*@C
5: VecTaggerOrGetSubs - Get the sub `VecTagger`s whose union defines the outer `VecTagger`
7: Not Collective
9: Input Parameter:
10: . tagger - the `VecTagger` context
12: Output Parameters:
13: + nsubs - the number of sub `VecTagger`s
14: - subs - the sub `VecTagger`s
16: Level: advanced
18: .seealso: `VecTaggerOrSetSubs()`
19: @*/
20: PetscErrorCode VecTaggerOrGetSubs(VecTagger tagger, PetscInt *nsubs, VecTagger **subs)
21: {
22: PetscFunctionBegin;
23: PetscCall(VecTaggerGetSubs_AndOr(tagger, nsubs, subs));
24: PetscFunctionReturn(PETSC_SUCCESS);
25: }
27: /*@C
28: VecTaggerOrSetSubs - Set the sub `VecTagger`s whose union defines the outer `VecTagger`
30: Logically Collective
32: Input Parameters:
33: + tagger - the `VecTagger` context
34: . nsubs - the number of sub `VecTagger`s
35: . subs - the sub `VecTagger`s
36: - mode - the copy mode to use for `subs`
38: Level: advanced
40: .seealso: `VecTaggetOrGetStubs()`
41: @*/
42: PetscErrorCode VecTaggerOrSetSubs(VecTagger tagger, PetscInt nsubs, VecTagger *subs, PetscCopyMode mode)
43: {
44: PetscFunctionBegin;
45: PetscCall(VecTaggerSetSubs_AndOr(tagger, nsubs, subs, mode));
46: PetscFunctionReturn(PETSC_SUCCESS);
47: }
49: static PetscErrorCode VecTaggerComputeBoxes_Or(VecTagger tagger, Vec vec, PetscInt *numBoxes, VecTaggerBox **boxes, PetscBool *listed)
50: {
51: PetscInt i, bs, nsubs, *numSubBoxes, nboxes, total;
52: VecTaggerBox **subBoxes;
53: VecTagger *subs;
54: VecTaggerBox *bxs;
55: PetscBool boxlisted;
57: PetscFunctionBegin;
58: PetscCall(VecTaggerGetBlockSize(tagger, &bs));
59: PetscCall(VecTaggerOrGetSubs(tagger, &nsubs, &subs));
60: PetscCall(PetscMalloc2(nsubs, &numSubBoxes, nsubs, &subBoxes));
61: for (i = 0, total = 0; i < nsubs; i++) {
62: PetscCall(VecTaggerComputeBoxes(subs[i], vec, &numSubBoxes[i], &subBoxes[i], &boxlisted));
63: if (!boxlisted) { /* no support, clean up and exit */
64: PetscInt j;
66: for (j = 0; j < i; j++) PetscCall(PetscFree(subBoxes[j]));
67: PetscCall(PetscFree2(numSubBoxes, subBoxes));
68: if (listed) *listed = PETSC_FALSE;
69: }
70: total += numSubBoxes[i];
71: }
72: PetscCall(PetscMalloc1(bs * total, &bxs));
73: for (i = 0, nboxes = 0; i < nsubs; i++) { /* stupid O(N^2) check to remove subboxes */
74: PetscInt j;
76: for (j = 0; j < numSubBoxes[i]; j++) {
77: PetscInt k;
78: VecTaggerBox *subBox = &subBoxes[i][j * bs];
80: for (k = 0; k < nboxes; k++) {
81: PetscBool isSub = PETSC_FALSE;
83: VecTaggerBox *prevBox = &bxs[bs * k];
84: PetscCall(VecTaggerAndOrIsSubBox_Private(bs, prevBox, subBox, &isSub));
85: if (isSub) break;
86: PetscCall(VecTaggerAndOrIsSubBox_Private(bs, subBox, prevBox, &isSub));
87: if (isSub) {
88: PetscInt l;
90: for (l = 0; l < bs; l++) prevBox[l] = subBox[l];
91: break;
92: }
93: }
94: if (k < nboxes) continue;
95: for (k = 0; k < bs; k++) bxs[nboxes * bs + k] = subBox[k];
96: nboxes++;
97: }
98: PetscCall(PetscFree(subBoxes[i]));
99: }
100: PetscCall(PetscFree2(numSubBoxes, subBoxes));
101: *numBoxes = nboxes;
102: *boxes = bxs;
103: if (listed) *listed = PETSC_TRUE;
104: PetscFunctionReturn(PETSC_SUCCESS);
105: }
107: static PetscErrorCode VecTaggerComputeIS_Or(VecTagger tagger, Vec vec, IS *is, PetscBool *listed)
108: {
109: PetscInt nsubs, i;
110: VecTagger *subs;
111: IS unionIS;
112: PetscBool boxlisted;
114: PetscFunctionBegin;
115: PetscCall(VecTaggerComputeIS_FromBoxes(tagger, vec, is, &boxlisted));
116: if (boxlisted) {
117: if (listed) *listed = PETSC_TRUE;
118: PetscFunctionReturn(PETSC_SUCCESS);
119: }
120: PetscCall(VecTaggerOrGetSubs(tagger, &nsubs, &subs));
121: PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)vec), 0, NULL, PETSC_OWN_POINTER, &unionIS));
122: for (i = 0; i < nsubs; i++) {
123: IS subIS, newUnionIS;
125: PetscCall(VecTaggerComputeIS(subs[i], vec, &subIS, &boxlisted));
126: PetscCheck(boxlisted, PetscObjectComm((PetscObject)tagger), PETSC_ERR_SUP, "Tagger cannot VecTaggerComputeIS()");
127: PetscCall(ISExpand(unionIS, subIS, &newUnionIS));
128: PetscCall(ISSort(newUnionIS));
129: PetscCall(ISDestroy(&unionIS));
130: unionIS = newUnionIS;
131: PetscCall(ISDestroy(&subIS));
132: }
133: *is = unionIS;
134: if (listed) *listed = PETSC_TRUE;
135: PetscFunctionReturn(PETSC_SUCCESS);
136: }
138: PETSC_INTERN PetscErrorCode VecTaggerCreate_Or(VecTagger tagger)
139: {
140: PetscFunctionBegin;
141: PetscCall(VecTaggerCreate_AndOr(tagger));
142: tagger->ops->computeboxes = VecTaggerComputeBoxes_Or;
143: tagger->ops->computeis = VecTaggerComputeIS_Or;
144: PetscFunctionReturn(PETSC_SUCCESS);
145: }