15fdea053SToby Isaac #include <petscdm.h>
2c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/
3ea844a1aSMatthew Knepley #include <petsc/private/sectionimpl.h> /*I "petscsection.h" I*/
4c58f1c22SToby Isaac #include <petscsf.h>
5ea844a1aSMatthew Knepley #include <petscsection.h>
6c58f1c22SToby Isaac
79f6c5813SMatthew G. Knepley PetscFunctionList DMLabelList = NULL;
89f6c5813SMatthew G. Knepley PetscBool DMLabelRegisterAllCalled = PETSC_FALSE;
99f6c5813SMatthew G. Knepley
10cc4c1da9SBarry Smith /*@
1120f4b53cSBarry Smith DMLabelCreate - Create a `DMLabel` object, which is a multimap
12c58f1c22SToby Isaac
135b5e7992SMatthew G. Knepley Collective
145b5e7992SMatthew G. Knepley
1560225df5SJacob Faibussowitsch Input Parameters:
1620f4b53cSBarry Smith + comm - The communicator, usually `PETSC_COMM_SELF`
17d67d17b1SMatthew G. Knepley - name - The label name
18c58f1c22SToby Isaac
1960225df5SJacob Faibussowitsch Output Parameter:
2020f4b53cSBarry Smith . label - The `DMLabel`
21c58f1c22SToby Isaac
22c58f1c22SToby Isaac Level: beginner
23c58f1c22SToby Isaac
2405ab7a9fSVaclav Hapla Notes:
2520f4b53cSBarry Smith The label name is actually usually the `PetscObject` name.
2620f4b53cSBarry Smith One can get/set it with `PetscObjectGetName()`/`PetscObjectSetName()`.
2705ab7a9fSVaclav Hapla
2820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDestroy()`
29c58f1c22SToby Isaac @*/
DMLabelCreate(MPI_Comm comm,const char name[],DMLabel * label)30d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreate(MPI_Comm comm, const char name[], DMLabel *label)
31d71ae5a4SJacob Faibussowitsch {
32c58f1c22SToby Isaac PetscFunctionBegin;
334f572ea9SToby Isaac PetscAssertPointer(label, 3);
349566063dSJacob Faibussowitsch PetscCall(DMInitializePackage());
35c58f1c22SToby Isaac
369566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(*label, DMLABEL_CLASSID, "DMLabel", "DMLabel", "DM", comm, DMLabelDestroy, DMLabelView));
37c58f1c22SToby Isaac (*label)->numStrata = 0;
385aa44df4SToby Isaac (*label)->defaultValue = -1;
39c58f1c22SToby Isaac (*label)->stratumValues = NULL;
40ad8374ffSToby Isaac (*label)->validIS = NULL;
41c58f1c22SToby Isaac (*label)->stratumSizes = NULL;
42c58f1c22SToby Isaac (*label)->points = NULL;
43c58f1c22SToby Isaac (*label)->ht = NULL;
44c58f1c22SToby Isaac (*label)->pStart = -1;
45c58f1c22SToby Isaac (*label)->pEnd = -1;
46c58f1c22SToby Isaac (*label)->bt = NULL;
479566063dSJacob Faibussowitsch PetscCall(PetscHMapICreate(&(*label)->hmap));
489566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*label, name));
499f6c5813SMatthew G. Knepley PetscCall(DMLabelSetType(*label, DMLABELCONCRETE));
503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
519f6c5813SMatthew G. Knepley }
529f6c5813SMatthew G. Knepley
53cc4c1da9SBarry Smith /*@
549f6c5813SMatthew G. Knepley DMLabelSetUp - SetUp a `DMLabel` object
559f6c5813SMatthew G. Knepley
569f6c5813SMatthew G. Knepley Collective
579f6c5813SMatthew G. Knepley
5860225df5SJacob Faibussowitsch Input Parameters:
599f6c5813SMatthew G. Knepley . label - The `DMLabel`
609f6c5813SMatthew G. Knepley
619f6c5813SMatthew G. Knepley Level: intermediate
629f6c5813SMatthew G. Knepley
6320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()`
649f6c5813SMatthew G. Knepley @*/
DMLabelSetUp(DMLabel label)659f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetUp(DMLabel label)
669f6c5813SMatthew G. Knepley {
679f6c5813SMatthew G. Knepley PetscFunctionBegin;
689f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
699f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, setup);
703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
71c58f1c22SToby Isaac }
72c58f1c22SToby Isaac
73c58f1c22SToby Isaac /*
74c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format
75c58f1c22SToby Isaac
765b5e7992SMatthew G. Knepley Not collective
775b5e7992SMatthew G. Knepley
78c58f1c22SToby Isaac Input parameter:
7920f4b53cSBarry Smith + label - The `DMLabel`
80c58f1c22SToby Isaac - v - The stratum value
81c58f1c22SToby Isaac
82c58f1c22SToby Isaac Output parameter:
8320f4b53cSBarry Smith . label - The `DMLabel` with stratum in sorted list format
84c58f1c22SToby Isaac
85c58f1c22SToby Isaac Level: developer
86c58f1c22SToby Isaac
8720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`
88c58f1c22SToby Isaac */
DMLabelMakeValid_Private(DMLabel label,PetscInt v)89d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v)
90d71ae5a4SJacob Faibussowitsch {
91277ea44aSLisandro Dalcin IS is;
92b9907514SLisandro Dalcin PetscInt off = 0, *pointArray, p;
93c58f1c22SToby Isaac
94c58f1c22SToby Isaac PetscFunctionBegin;
954d86920dSPierre Jolivet if ((PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) || label->readonly) PetscFunctionReturn(PETSC_SUCCESS);
961dca8a05SBarry Smith PetscCheck(v >= 0 && v < label->numStrata, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %" PetscInt_FMT " in DMLabelMakeValid_Private", v);
979566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v]));
989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->stratumSizes[v], &pointArray));
999566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(label->ht[v], &off, pointArray));
1009566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v]));
1019566063dSJacob Faibussowitsch PetscCall(PetscSortInt(label->stratumSizes[v], pointArray));
102c58f1c22SToby Isaac if (label->bt) {
103c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) {
104ad8374ffSToby Isaac const PetscInt point = pointArray[p];
10563a3b9bcSJacob Faibussowitsch PetscCheck(!(point < label->pStart) && !(point >= label->pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->pStart, label->pEnd);
1069566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart));
107c58f1c22SToby Isaac }
108c58f1c22SToby Isaac }
109ba2698f1SMatthew G. Knepley if (label->stratumSizes[v] > 0 && pointArray[label->stratumSizes[v] - 1] == pointArray[0] + label->stratumSizes[v] - 1) {
1109566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, label->stratumSizes[v], pointArray[0], 1, &is));
1119566063dSJacob Faibussowitsch PetscCall(PetscFree(pointArray));
112ba2698f1SMatthew G. Knepley } else {
1139566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is));
114ba2698f1SMatthew G. Knepley }
115f622de60SMatthew G. Knepley PetscCall(ISSetInfo(is, IS_SORTED, IS_LOCAL, PETSC_TRUE, PETSC_TRUE));
1169566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)is, "indices"));
117277ea44aSLisandro Dalcin label->points[v] = is;
118ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE;
1199566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label));
1203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
121c58f1c22SToby Isaac }
122c58f1c22SToby Isaac
123c58f1c22SToby Isaac /*
124c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format
125c58f1c22SToby Isaac
12620f4b53cSBarry Smith Not Collective
1275b5e7992SMatthew G. Knepley
128c58f1c22SToby Isaac Input parameter:
12920f4b53cSBarry Smith . label - The `DMLabel`
130c58f1c22SToby Isaac
131c58f1c22SToby Isaac Output parameter:
13220f4b53cSBarry Smith . label - The `DMLabel` with all strata in sorted list format
133c58f1c22SToby Isaac
134c58f1c22SToby Isaac Level: developer
135c58f1c22SToby Isaac
13620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`
137c58f1c22SToby Isaac */
DMLabelMakeAllValid_Private(DMLabel label)138d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label)
139d71ae5a4SJacob Faibussowitsch {
140c58f1c22SToby Isaac PetscInt v;
141c58f1c22SToby Isaac
142c58f1c22SToby Isaac PetscFunctionBegin;
14348a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeValid_Private(label, v));
1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
145c58f1c22SToby Isaac }
146c58f1c22SToby Isaac
147c58f1c22SToby Isaac /*
148c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format
149c58f1c22SToby Isaac
15020f4b53cSBarry Smith Not Collective
1515b5e7992SMatthew G. Knepley
152c58f1c22SToby Isaac Input parameter:
15320f4b53cSBarry Smith + label - The `DMLabel`
154c58f1c22SToby Isaac - v - The stratum value
155c58f1c22SToby Isaac
156c58f1c22SToby Isaac Output parameter:
15720f4b53cSBarry Smith . label - The `DMLabel` with stratum in hash format
158c58f1c22SToby Isaac
159c58f1c22SToby Isaac Level: developer
160c58f1c22SToby Isaac
16120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`
162c58f1c22SToby Isaac */
DMLabelMakeInvalid_Private(DMLabel label,PetscInt v)163d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v)
164d71ae5a4SJacob Faibussowitsch {
165c58f1c22SToby Isaac PetscInt p;
166ad8374ffSToby Isaac const PetscInt *points;
167c58f1c22SToby Isaac
168c58f1c22SToby Isaac PetscFunctionBegin;
1694d86920dSPierre Jolivet if ((PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) || label->readonly) PetscFunctionReturn(PETSC_SUCCESS);
1701dca8a05SBarry Smith PetscCheck(v >= 0 && v < label->numStrata, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %" PetscInt_FMT " in DMLabelMakeInvalid_Private", v);
171ad8374ffSToby Isaac if (label->points[v]) {
1729566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points));
17348a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p]));
1749566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points));
175f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v]));
176ad8374ffSToby Isaac }
177ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE;
1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
179c58f1c22SToby Isaac }
180c58f1c22SToby Isaac
DMLabelMakeAllInvalid_Internal(DMLabel label)181d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelMakeAllInvalid_Internal(DMLabel label)
182d71ae5a4SJacob Faibussowitsch {
183695799ffSMatthew G. Knepley PetscInt v;
184695799ffSMatthew G. Knepley
185695799ffSMatthew G. Knepley PetscFunctionBegin;
18648a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeInvalid_Private(label, v));
1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
188695799ffSMatthew G. Knepley }
189695799ffSMatthew G. Knepley
190b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD)
191b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16
192b9907514SLisandro Dalcin #endif
193b9907514SLisandro Dalcin
DMLabelLookupStratum(DMLabel label,PetscInt value,PetscInt * index)1949f6c5813SMatthew G. Knepley PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index)
195d71ae5a4SJacob Faibussowitsch {
1960c3c4a36SLisandro Dalcin PetscInt v;
1970e79e033SBarry Smith
1980c3c4a36SLisandro Dalcin PetscFunctionBegin;
1990e79e033SBarry Smith *index = -1;
2009f6c5813SMatthew G. Knepley if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD || label->readonly) {
201b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v)
2029371c9d4SSatish Balay if (label->stratumValues[v] == value) {
2039371c9d4SSatish Balay *index = v;
2049371c9d4SSatish Balay break;
2059371c9d4SSatish Balay }
206b9907514SLisandro Dalcin } else {
2079566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index));
2080e79e033SBarry Smith }
2099f6c5813SMatthew G. Knepley if (PetscDefined(USE_DEBUG) && !label->readonly) { /* Check strata hash map consistency */
21090e9b2aeSLisandro Dalcin PetscInt len, loc = -1;
2119566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len));
21208401ef6SPierre Jolivet PetscCheck(len == label->numStrata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size");
21390e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) {
2149566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc));
21590e9b2aeSLisandro Dalcin } else {
21690e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v)
2179371c9d4SSatish Balay if (label->stratumValues[v] == value) {
2189371c9d4SSatish Balay loc = v;
2199371c9d4SSatish Balay break;
2209371c9d4SSatish Balay }
22190e9b2aeSLisandro Dalcin }
22208401ef6SPierre Jolivet PetscCheck(loc == *index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup");
22390e9b2aeSLisandro Dalcin }
2243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2250c3c4a36SLisandro Dalcin }
2260c3c4a36SLisandro Dalcin
DMLabelNewStratum(DMLabel label,PetscInt value,PetscInt * index)227d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index)
228d71ae5a4SJacob Faibussowitsch {
229b9907514SLisandro Dalcin PetscInt v;
230b9907514SLisandro Dalcin PetscInt *tmpV;
231b9907514SLisandro Dalcin PetscInt *tmpS;
232b9907514SLisandro Dalcin PetscHSetI *tmpH, ht;
233b9907514SLisandro Dalcin IS *tmpP, is;
234c58f1c22SToby Isaac PetscBool *tmpB;
235b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap;
236c58f1c22SToby Isaac
237c58f1c22SToby Isaac PetscFunctionBegin;
238b9907514SLisandro Dalcin v = label->numStrata;
239b9907514SLisandro Dalcin tmpV = label->stratumValues;
240b9907514SLisandro Dalcin tmpS = label->stratumSizes;
241b9907514SLisandro Dalcin tmpH = label->ht;
242b9907514SLisandro Dalcin tmpP = label->points;
243b9907514SLisandro Dalcin tmpB = label->validIS;
2448e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */
2458e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV;
2468e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS;
2478e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH;
2488e1f8cf0SLisandro Dalcin IS *oldP = tmpP;
2498e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB;
2509566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpV), &tmpV));
2519566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpS), &tmpS));
2529f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpH), &tmpH));
2539f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpP), &tmpP));
2549566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpB), &tmpB));
2559566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v));
2569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v));
2579566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v));
2589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v));
2599566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v));
2609566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV));
2619566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS));
2629566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH));
2639566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP));
2649566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB));
2658e1f8cf0SLisandro Dalcin }
266b9907514SLisandro Dalcin label->numStrata = v + 1;
267c58f1c22SToby Isaac label->stratumValues = tmpV;
268c58f1c22SToby Isaac label->stratumSizes = tmpS;
269c58f1c22SToby Isaac label->ht = tmpH;
270c58f1c22SToby Isaac label->points = tmpP;
271ad8374ffSToby Isaac label->validIS = tmpB;
2729566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht));
2739566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is));
2749566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v));
275b9907514SLisandro Dalcin tmpV[v] = value;
276b9907514SLisandro Dalcin tmpS[v] = 0;
277b9907514SLisandro Dalcin tmpH[v] = ht;
278b9907514SLisandro Dalcin tmpP[v] = is;
279b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE;
2809566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label));
2810c3c4a36SLisandro Dalcin *index = v;
2823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2830c3c4a36SLisandro Dalcin }
2840c3c4a36SLisandro Dalcin
DMLabelLookupAddStratum(DMLabel label,PetscInt value,PetscInt * index)285d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index)
286d71ae5a4SJacob Faibussowitsch {
287b9907514SLisandro Dalcin PetscFunctionBegin;
2889566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index));
2899566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index));
2903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
291b9907514SLisandro Dalcin }
292b9907514SLisandro Dalcin
DMLabelGetStratumSize_Private(DMLabel label,PetscInt v,PetscInt * size)2939f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size)
294d71ae5a4SJacob Faibussowitsch {
2959e63cc69SVaclav Hapla PetscFunctionBegin;
2969e63cc69SVaclav Hapla *size = 0;
2973ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS);
2989f6c5813SMatthew G. Knepley if (label->readonly || label->validIS[v]) {
2999e63cc69SVaclav Hapla *size = label->stratumSizes[v];
3009e63cc69SVaclav Hapla } else {
3019566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size));
3029e63cc69SVaclav Hapla }
3033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3049e63cc69SVaclav Hapla }
3059e63cc69SVaclav Hapla
306b9907514SLisandro Dalcin /*@
30720f4b53cSBarry Smith DMLabelAddStratum - Adds a new stratum value in a `DMLabel`
308b9907514SLisandro Dalcin
309d8d19677SJose E. Roman Input Parameters:
31020f4b53cSBarry Smith + label - The `DMLabel`
311b9907514SLisandro Dalcin - value - The stratum value
312b9907514SLisandro Dalcin
313b9907514SLisandro Dalcin Level: beginner
314b9907514SLisandro Dalcin
31520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()`
316b9907514SLisandro Dalcin @*/
DMLabelAddStratum(DMLabel label,PetscInt value)317d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value)
318d71ae5a4SJacob Faibussowitsch {
3190c3c4a36SLisandro Dalcin PetscInt v;
3200c3c4a36SLisandro Dalcin
3210c3c4a36SLisandro Dalcin PetscFunctionBegin;
322d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
3239f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
3249566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v));
3253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
326b9907514SLisandro Dalcin }
327b9907514SLisandro Dalcin
328b9907514SLisandro Dalcin /*@
32920f4b53cSBarry Smith DMLabelAddStrata - Adds new stratum values in a `DMLabel`
330b9907514SLisandro Dalcin
33120f4b53cSBarry Smith Not Collective
3325b5e7992SMatthew G. Knepley
333d8d19677SJose E. Roman Input Parameters:
33420f4b53cSBarry Smith + label - The `DMLabel`
335b9907514SLisandro Dalcin . numStrata - The number of stratum values
336b9907514SLisandro Dalcin - stratumValues - The stratum values
337b9907514SLisandro Dalcin
338b9907514SLisandro Dalcin Level: beginner
339b9907514SLisandro Dalcin
34020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()`
341b9907514SLisandro Dalcin @*/
DMLabelAddStrata(DMLabel label,PetscInt numStrata,const PetscInt stratumValues[])342d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[])
343d71ae5a4SJacob Faibussowitsch {
344b9907514SLisandro Dalcin PetscInt *values, v;
345b9907514SLisandro Dalcin
346b9907514SLisandro Dalcin PetscFunctionBegin;
347b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
3484f572ea9SToby Isaac if (numStrata) PetscAssertPointer(stratumValues, 3);
3499f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
3509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &values));
3519566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(values, stratumValues, numStrata));
3529566063dSJacob Faibussowitsch PetscCall(PetscSortRemoveDupsInt(&numStrata, values));
353b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */
354b9907514SLisandro Dalcin PetscInt *tmpV;
355b9907514SLisandro Dalcin PetscInt *tmpS;
356b9907514SLisandro Dalcin PetscHSetI *tmpH, ht;
357b9907514SLisandro Dalcin IS *tmpP, is;
358b9907514SLisandro Dalcin PetscBool *tmpB;
359b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap;
360b9907514SLisandro Dalcin
3619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpV));
3629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpS));
3639f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpH));
3649f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpP));
3659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpB));
366b9907514SLisandro Dalcin label->numStrata = numStrata;
367b9907514SLisandro Dalcin label->stratumValues = tmpV;
368b9907514SLisandro Dalcin label->stratumSizes = tmpS;
369b9907514SLisandro Dalcin label->ht = tmpH;
370b9907514SLisandro Dalcin label->points = tmpP;
371b9907514SLisandro Dalcin label->validIS = tmpB;
372b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) {
3739566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht));
3749566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is));
3759566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, values[v], v));
376b9907514SLisandro Dalcin tmpV[v] = values[v];
377b9907514SLisandro Dalcin tmpS[v] = 0;
378b9907514SLisandro Dalcin tmpH[v] = ht;
379b9907514SLisandro Dalcin tmpP[v] = is;
380b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE;
381b9907514SLisandro Dalcin }
3829566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label));
383b9907514SLisandro Dalcin } else {
38448a46eb9SPierre Jolivet for (v = 0; v < numStrata; ++v) PetscCall(DMLabelAddStratum(label, values[v]));
385b9907514SLisandro Dalcin }
3869566063dSJacob Faibussowitsch PetscCall(PetscFree(values));
3873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
388b9907514SLisandro Dalcin }
389b9907514SLisandro Dalcin
390b9907514SLisandro Dalcin /*@
39120f4b53cSBarry Smith DMLabelAddStrataIS - Adds new stratum values in a `DMLabel`
392b9907514SLisandro Dalcin
39320f4b53cSBarry Smith Not Collective
3945b5e7992SMatthew G. Knepley
395d8d19677SJose E. Roman Input Parameters:
39620f4b53cSBarry Smith + label - The `DMLabel`
397b9907514SLisandro Dalcin - valueIS - Index set with stratum values
398b9907514SLisandro Dalcin
399b9907514SLisandro Dalcin Level: beginner
400b9907514SLisandro Dalcin
40120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()`
402b9907514SLisandro Dalcin @*/
DMLabelAddStrataIS(DMLabel label,IS valueIS)403d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS)
404d71ae5a4SJacob Faibussowitsch {
405b9907514SLisandro Dalcin PetscInt numStrata;
406b9907514SLisandro Dalcin const PetscInt *stratumValues;
407b9907514SLisandro Dalcin
408b9907514SLisandro Dalcin PetscFunctionBegin;
409b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
410b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2);
4119f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
4129566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata));
4139566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues));
4149566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues));
4153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
416c58f1c22SToby Isaac }
417c58f1c22SToby Isaac
DMLabelView_Concrete_Ascii(DMLabel label,PetscViewer viewer)4189f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelView_Concrete_Ascii(DMLabel label, PetscViewer viewer)
419d71ae5a4SJacob Faibussowitsch {
420c58f1c22SToby Isaac PetscInt v;
421c58f1c22SToby Isaac PetscMPIInt rank;
422c58f1c22SToby Isaac
423c58f1c22SToby Isaac PetscFunctionBegin;
4249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
4259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer));
426c58f1c22SToby Isaac if (label) {
427d67d17b1SMatthew G. Knepley const char *name;
428d67d17b1SMatthew G. Knepley
4299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name));
4309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name));
43163a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd));
432c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) {
433c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v];
434ad8374ffSToby Isaac const PetscInt *points;
435c58f1c22SToby Isaac PetscInt p;
436c58f1c22SToby Isaac
4379566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points));
43848a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value));
4399566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points));
440c58f1c22SToby Isaac }
441c58f1c22SToby Isaac }
4429566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer));
4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer));
4443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
445c58f1c22SToby Isaac }
446c58f1c22SToby Isaac
DMLabelView_Concrete(DMLabel label,PetscViewer viewer)44766976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelView_Concrete(DMLabel label, PetscViewer viewer)
4489f6c5813SMatthew G. Knepley {
4499f196a02SMartin Diehl PetscBool isascii;
4509f6c5813SMatthew G. Knepley
4519f6c5813SMatthew G. Knepley PetscFunctionBegin;
4529f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
4539f196a02SMartin Diehl if (isascii) PetscCall(DMLabelView_Concrete_Ascii(label, viewer));
4543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4559f6c5813SMatthew G. Knepley }
4569f6c5813SMatthew G. Knepley
457ffeef943SBarry Smith /*@
458c58f1c22SToby Isaac DMLabelView - View the label
459c58f1c22SToby Isaac
46020f4b53cSBarry Smith Collective
4615b5e7992SMatthew G. Knepley
462c58f1c22SToby Isaac Input Parameters:
46320f4b53cSBarry Smith + label - The `DMLabel`
46420f4b53cSBarry Smith - viewer - The `PetscViewer`
465c58f1c22SToby Isaac
466c58f1c22SToby Isaac Level: intermediate
467c58f1c22SToby Isaac
46820f4b53cSBarry Smith .seealso: `DMLabel`, `PetscViewer`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()`
469c58f1c22SToby Isaac @*/
DMLabelView(DMLabel label,PetscViewer viewer)470d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer)
471d71ae5a4SJacob Faibussowitsch {
472c58f1c22SToby Isaac PetscFunctionBegin;
473d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
4749566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer));
475c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
4769f6c5813SMatthew G. Knepley PetscCall(DMLabelMakeAllValid_Private(label));
4779f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, view, viewer);
4783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
479c58f1c22SToby Isaac }
480c58f1c22SToby Isaac
48184f0b6dfSMatthew G. Knepley /*@
4824b793533SStefano Zampini DMLabelViewFromOptions - View a `DMLabel` in a particular way based on a request in the options database
4834b793533SStefano Zampini
4844b793533SStefano Zampini Collective
4854b793533SStefano Zampini
4864b793533SStefano Zampini Input Parameters:
4874b793533SStefano Zampini + label - the `DMLabel` object
4884b793533SStefano Zampini . obj - optional object that provides the prefix for the options database (if `NULL` then the prefix in `obj` is used)
4894b793533SStefano Zampini - name - option string that is used to activate viewing
4904b793533SStefano Zampini
4914b793533SStefano Zampini Level: intermediate
4924b793533SStefano Zampini
4934b793533SStefano Zampini Note:
4944b793533SStefano Zampini See `PetscObjectViewFromOptions()` for a list of values that can be provided in the options database to determine how the `DMLabel` is viewed
4954b793533SStefano Zampini
4964b793533SStefano Zampini .seealso: [](ch_dmbase), `DMLabel`, `DMLabelView()`, `PetscObjectViewFromOptions()`, `DMLabelCreate()`
4974b793533SStefano Zampini @*/
DMLabelViewFromOptions(DMLabel label,PeOp PetscObject obj,const char name[])4984b793533SStefano Zampini PetscErrorCode DMLabelViewFromOptions(DMLabel label, PeOp PetscObject obj, const char name[])
4994b793533SStefano Zampini {
5004b793533SStefano Zampini PetscFunctionBegin;
5014b793533SStefano Zampini PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
5024b793533SStefano Zampini PetscCall(PetscObjectViewFromOptions((PetscObject)label, obj, name));
5034b793533SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
5044b793533SStefano Zampini }
5054b793533SStefano Zampini
5064b793533SStefano Zampini /*@
50720f4b53cSBarry Smith DMLabelReset - Destroys internal data structures in a `DMLabel`
508d67d17b1SMatthew G. Knepley
50920f4b53cSBarry Smith Not Collective
5105b5e7992SMatthew G. Knepley
511d67d17b1SMatthew G. Knepley Input Parameter:
51220f4b53cSBarry Smith . label - The `DMLabel`
513d67d17b1SMatthew G. Knepley
514d67d17b1SMatthew G. Knepley Level: beginner
515d67d17b1SMatthew G. Knepley
51620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDestroy()`, `DMLabelCreate()`
517d67d17b1SMatthew G. Knepley @*/
DMLabelReset(DMLabel label)518d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelReset(DMLabel label)
519d71ae5a4SJacob Faibussowitsch {
520d67d17b1SMatthew G. Knepley PetscInt v;
521d67d17b1SMatthew G. Knepley
522d67d17b1SMatthew G. Knepley PetscFunctionBegin;
523d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
524d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) {
5259f6c5813SMatthew G. Knepley if (label->ht[v]) PetscCall(PetscHSetIDestroy(&label->ht[v]));
5269566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v]));
527d67d17b1SMatthew G. Knepley }
528b9907514SLisandro Dalcin label->numStrata = 0;
5299566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues));
5309566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes));
5319566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht));
5329566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points));
5339566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS));
5349566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap));
535b9907514SLisandro Dalcin label->pStart = -1;
536b9907514SLisandro Dalcin label->pEnd = -1;
5379566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt));
5383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
539d67d17b1SMatthew G. Knepley }
540d67d17b1SMatthew G. Knepley
541d67d17b1SMatthew G. Knepley /*@
54220f4b53cSBarry Smith DMLabelDestroy - Destroys a `DMLabel`
54384f0b6dfSMatthew G. Knepley
54420f4b53cSBarry Smith Collective
5455b5e7992SMatthew G. Knepley
54684f0b6dfSMatthew G. Knepley Input Parameter:
54720f4b53cSBarry Smith . label - The `DMLabel`
54884f0b6dfSMatthew G. Knepley
54984f0b6dfSMatthew G. Knepley Level: beginner
55084f0b6dfSMatthew G. Knepley
55120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelReset()`, `DMLabelCreate()`
55284f0b6dfSMatthew G. Knepley @*/
DMLabelDestroy(DMLabel * label)553d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroy(DMLabel *label)
554d71ae5a4SJacob Faibussowitsch {
555c58f1c22SToby Isaac PetscFunctionBegin;
5563ba16761SJacob Faibussowitsch if (!*label) PetscFunctionReturn(PETSC_SUCCESS);
557f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 1);
558f4f49eeaSPierre Jolivet if (--((PetscObject)*label)->refct > 0) {
5599371c9d4SSatish Balay *label = NULL;
5603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5619371c9d4SSatish Balay }
5629566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label));
5639566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap));
5649566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label));
5653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
566c58f1c22SToby Isaac }
567c58f1c22SToby Isaac
DMLabelDuplicate_Concrete(DMLabel label,DMLabel * labelnew)56866976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDuplicate_Concrete(DMLabel label, DMLabel *labelnew)
5699f6c5813SMatthew G. Knepley {
5709f6c5813SMatthew G. Knepley PetscFunctionBegin;
5719f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) {
5729f6c5813SMatthew G. Knepley PetscCall(PetscHSetICreate(&(*labelnew)->ht[v]));
573f4f49eeaSPierre Jolivet PetscCall(PetscObjectReference((PetscObject)label->points[v]));
5749f6c5813SMatthew G. Knepley (*labelnew)->points[v] = label->points[v];
5759f6c5813SMatthew G. Knepley }
5769f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap));
5779f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDuplicate(label->hmap, &(*labelnew)->hmap));
5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5799f6c5813SMatthew G. Knepley }
5809f6c5813SMatthew G. Knepley
58184f0b6dfSMatthew G. Knepley /*@
58220f4b53cSBarry Smith DMLabelDuplicate - Duplicates a `DMLabel`
58384f0b6dfSMatthew G. Knepley
58420f4b53cSBarry Smith Collective
5855b5e7992SMatthew G. Knepley
58684f0b6dfSMatthew G. Knepley Input Parameter:
58720f4b53cSBarry Smith . label - The `DMLabel`
58884f0b6dfSMatthew G. Knepley
58984f0b6dfSMatthew G. Knepley Output Parameter:
59020f4b53cSBarry Smith . labelnew - new label
59184f0b6dfSMatthew G. Knepley
59284f0b6dfSMatthew G. Knepley Level: intermediate
59384f0b6dfSMatthew G. Knepley
59420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()`
59584f0b6dfSMatthew G. Knepley @*/
DMLabelDuplicate(DMLabel label,DMLabel * labelnew)596d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew)
597d71ae5a4SJacob Faibussowitsch {
598d67d17b1SMatthew G. Knepley const char *name;
599c58f1c22SToby Isaac
600c58f1c22SToby Isaac PetscFunctionBegin;
601d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
6029566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label));
6039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name));
6049566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)label), name, labelnew));
605c58f1c22SToby Isaac
606c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata;
6075aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue;
6088dcf10e8SMatthew G. Knepley (*labelnew)->readonly = label->readonly;
6099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues));
6109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes));
6119f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->ht));
6129f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->points));
6139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS));
6149f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) {
615c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v];
616c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v];
617b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE;
618c58f1c22SToby Isaac }
619c58f1c22SToby Isaac (*labelnew)->pStart = -1;
620c58f1c22SToby Isaac (*labelnew)->pEnd = -1;
621c58f1c22SToby Isaac (*labelnew)->bt = NULL;
6229f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, duplicate, labelnew);
6233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
624c58f1c22SToby Isaac }
625c58f1c22SToby Isaac
626609dae6eSVaclav Hapla /*@C
62720f4b53cSBarry Smith DMLabelCompare - Compare two `DMLabel` objects
628609dae6eSVaclav Hapla
62920f4b53cSBarry Smith Collective; No Fortran Support
630609dae6eSVaclav Hapla
631609dae6eSVaclav Hapla Input Parameters:
632f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels
63320f4b53cSBarry Smith . l0 - First `DMLabel`
63420f4b53cSBarry Smith - l1 - Second `DMLabel`
635609dae6eSVaclav Hapla
636a4e35b19SJacob Faibussowitsch Output Parameters:
6375efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal
6385efe38ccSVaclav Hapla - message - (Optional) Message describing the difference
639609dae6eSVaclav Hapla
640609dae6eSVaclav Hapla Level: intermediate
641609dae6eSVaclav Hapla
642609dae6eSVaclav Hapla Notes:
6435efe38ccSVaclav Hapla The output flag equal is the same on all processes.
64420f4b53cSBarry Smith If it is passed as `NULL` and difference is found, an error is thrown on all processes.
64520f4b53cSBarry Smith Make sure to pass `NULL` on all processes.
646609dae6eSVaclav Hapla
6475efe38ccSVaclav Hapla The output message is set independently on each rank.
64820f4b53cSBarry Smith It is set to `NULL` if no difference was found on the current rank. It must be freed by user.
64920f4b53cSBarry Smith If message is passed as `NULL` and difference is found, the difference description is printed to stderr in synchronized manner.
65020f4b53cSBarry Smith Make sure to pass `NULL` on all processes.
651609dae6eSVaclav Hapla
652609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points.
653609dae6eSVaclav Hapla
65420f4b53cSBarry Smith The communicator needs to be specified because currently `DMLabel` can live on `PETSC_COMM_SELF` even if the underlying `DM` is parallel.
6555efe38ccSVaclav Hapla
656a3b724e8SBarry Smith Developer Note:
657a3b724e8SBarry Smith Fortran stub cannot be generated automatically because `message` must be freed with `PetscFree()`
658a3b724e8SBarry Smith
65920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()`
660609dae6eSVaclav Hapla @*/
DMLabelCompare(MPI_Comm comm,DMLabel l0,DMLabel l1,PetscBool * equal,char ** message)661d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message)
662d71ae5a4SJacob Faibussowitsch {
663609dae6eSVaclav Hapla const char *name0, *name1;
664609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = "";
6655efe38ccSVaclav Hapla PetscBool eq;
6665efe38ccSVaclav Hapla PetscMPIInt rank;
667609dae6eSVaclav Hapla
668609dae6eSVaclav Hapla PetscFunctionBegin;
6695efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2);
6705efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3);
6714f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 4);
6724f572ea9SToby Isaac if (message) PetscAssertPointer(message, 5);
6739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
6749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0));
6759566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1));
676609dae6eSVaclav Hapla {
677609dae6eSVaclav Hapla PetscInt v0, v1;
678609dae6eSVaclav Hapla
6799566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0));
6809566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1));
6815efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1);
68248a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Default value of DMLabel l0 \"%s\" = %" PetscInt_FMT " != %" PetscInt_FMT " = Default value of DMLabel l1 \"%s\"", name0, v0, v1, name1));
6835440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPI_C_BOOL, MPI_LAND, comm));
6845efe38ccSVaclav Hapla if (!eq) goto finish;
685609dae6eSVaclav Hapla }
686609dae6eSVaclav Hapla {
687609dae6eSVaclav Hapla IS is0, is1;
688609dae6eSVaclav Hapla
6899566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0));
6909566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1));
6919566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq));
6929566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0));
6939566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1));
69448a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1));
6955440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPI_C_BOOL, MPI_LAND, comm));
6965efe38ccSVaclav Hapla if (!eq) goto finish;
697609dae6eSVaclav Hapla }
698609dae6eSVaclav Hapla {
699609dae6eSVaclav Hapla PetscInt i, nValues;
700609dae6eSVaclav Hapla
7019566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues));
702609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) {
703609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i];
704609dae6eSVaclav Hapla PetscInt n;
705609dae6eSVaclav Hapla IS is0, is1;
706609dae6eSVaclav Hapla
7079566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n));
708609dae6eSVaclav Hapla if (!n) continue;
7099566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0));
7109566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1));
7119566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq));
7129566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0));
7139566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1));
7145efe38ccSVaclav Hapla if (!eq) {
71563a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum #%" PetscInt_FMT " with value %" PetscInt_FMT " contains different points in DMLabel l0 \"%s\" and DMLabel l1 \"%s\"", i, v, name0, name1));
7165efe38ccSVaclav Hapla break;
717609dae6eSVaclav Hapla }
718609dae6eSVaclav Hapla }
7195440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPI_C_BOOL, MPI_LAND, comm));
720609dae6eSVaclav Hapla }
721609dae6eSVaclav Hapla finish:
7225efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */
723609dae6eSVaclav Hapla if (message) {
724609dae6eSVaclav Hapla *message = NULL;
72548a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message));
7265efe38ccSVaclav Hapla } else {
72748a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg));
7289566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR));
7295efe38ccSVaclav Hapla }
7305efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */
7315efe38ccSVaclav Hapla if (equal) *equal = eq;
73263a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1);
7333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
734609dae6eSVaclav Hapla }
735609dae6eSVaclav Hapla
736c6a43d28SMatthew G. Knepley /*@
737c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds
738c6a43d28SMatthew G. Knepley
73920f4b53cSBarry Smith Not Collective
7405b5e7992SMatthew G. Knepley
741c6a43d28SMatthew G. Knepley Input Parameter:
74220f4b53cSBarry Smith . label - The `DMLabel`
743c6a43d28SMatthew G. Knepley
744c6a43d28SMatthew G. Knepley Level: intermediate
745c6a43d28SMatthew G. Knepley
74620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()`
747c6a43d28SMatthew G. Knepley @*/
DMLabelComputeIndex(DMLabel label)748d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label)
749d71ae5a4SJacob Faibussowitsch {
7501690c2aeSBarry Smith PetscInt pStart = PETSC_INT_MAX, pEnd = -1, v;
751c6a43d28SMatthew G. Knepley
752c6a43d28SMatthew G. Knepley PetscFunctionBegin;
753c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
7549566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label));
755c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) {
756c6a43d28SMatthew G. Knepley const PetscInt *points;
757c6a43d28SMatthew G. Knepley PetscInt i;
758c6a43d28SMatthew G. Knepley
7599566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points));
760c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) {
761c6a43d28SMatthew G. Knepley const PetscInt point = points[i];
762c6a43d28SMatthew G. Knepley
763c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart);
764c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd);
765c6a43d28SMatthew G. Knepley }
7669566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points));
767c6a43d28SMatthew G. Knepley }
7681690c2aeSBarry Smith label->pStart = pStart == PETSC_INT_MAX ? -1 : pStart;
769c6a43d28SMatthew G. Knepley label->pEnd = pEnd;
7709566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd));
7713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
772c6a43d28SMatthew G. Knepley }
773c6a43d28SMatthew G. Knepley
774c6a43d28SMatthew G. Knepley /*@
775c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination
776c6a43d28SMatthew G. Knepley
77720f4b53cSBarry Smith Not Collective
7785b5e7992SMatthew G. Knepley
779c6a43d28SMatthew G. Knepley Input Parameters:
78020f4b53cSBarry Smith + label - The `DMLabel`
781c6a43d28SMatthew G. Knepley . pStart - The smallest point
782c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1
783c6a43d28SMatthew G. Knepley
784c6a43d28SMatthew G. Knepley Level: intermediate
785c6a43d28SMatthew G. Knepley
78620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()`
787c6a43d28SMatthew G. Knepley @*/
DMLabelCreateIndex(DMLabel label,PetscInt pStart,PetscInt pEnd)788d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd)
789d71ae5a4SJacob Faibussowitsch {
790c58f1c22SToby Isaac PetscInt v;
791c58f1c22SToby Isaac
792c58f1c22SToby Isaac PetscFunctionBegin;
793d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
7949566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label));
7959566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label));
796c58f1c22SToby Isaac label->pStart = pStart;
797c58f1c22SToby Isaac label->pEnd = pEnd;
798c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */
7999566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt));
800c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) {
8019f6c5813SMatthew G. Knepley IS pointIS;
802ad8374ffSToby Isaac const PetscInt *points;
803c58f1c22SToby Isaac PetscInt i;
804c58f1c22SToby Isaac
8059f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS);
8069f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points));
807c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) {
808ad8374ffSToby Isaac const PetscInt point = points[i];
809c58f1c22SToby Isaac
8109f6c5813SMatthew G. Knepley PetscCheck(!(point < pStart) && !(point >= pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " in stratum %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->stratumValues[v], pStart, pEnd);
8119566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart));
812c58f1c22SToby Isaac }
8139566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points));
8149f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS));
815c58f1c22SToby Isaac }
8163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
817c58f1c22SToby Isaac }
818c58f1c22SToby Isaac
819c6a43d28SMatthew G. Knepley /*@
820c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure
821c6a43d28SMatthew G. Knepley
82220f4b53cSBarry Smith Not Collective
8235b5e7992SMatthew G. Knepley
824c6a43d28SMatthew G. Knepley Input Parameter:
82520f4b53cSBarry Smith . label - the `DMLabel`
826c6a43d28SMatthew G. Knepley
827c6a43d28SMatthew G. Knepley Level: intermediate
828c6a43d28SMatthew G. Knepley
82920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()`
830c6a43d28SMatthew G. Knepley @*/
DMLabelDestroyIndex(DMLabel label)831d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label)
832d71ae5a4SJacob Faibussowitsch {
833c58f1c22SToby Isaac PetscFunctionBegin;
834d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
835c58f1c22SToby Isaac label->pStart = -1;
836c58f1c22SToby Isaac label->pEnd = -1;
8379566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt));
8383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
839c58f1c22SToby Isaac }
840c58f1c22SToby Isaac
841c58f1c22SToby Isaac /*@
842c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label
843c6a43d28SMatthew G. Knepley
84420f4b53cSBarry Smith Not Collective
8455b5e7992SMatthew G. Knepley
846c6a43d28SMatthew G. Knepley Input Parameter:
84720f4b53cSBarry Smith . label - the `DMLabel`
848c6a43d28SMatthew G. Knepley
849c6a43d28SMatthew G. Knepley Output Parameters:
850c6a43d28SMatthew G. Knepley + pStart - The smallest point
851c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1
852c6a43d28SMatthew G. Knepley
853c6a43d28SMatthew G. Knepley Level: intermediate
854c6a43d28SMatthew G. Knepley
85520f4b53cSBarry Smith Note:
85620f4b53cSBarry Smith This will compute an index for the label if one does not exist.
85720f4b53cSBarry Smith
85820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()`
859c6a43d28SMatthew G. Knepley @*/
DMLabelGetBounds(DMLabel label,PetscInt * pStart,PetscInt * pEnd)860d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd)
861d71ae5a4SJacob Faibussowitsch {
862c6a43d28SMatthew G. Knepley PetscFunctionBegin;
863c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
8649566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label));
865c6a43d28SMatthew G. Knepley if (pStart) {
8664f572ea9SToby Isaac PetscAssertPointer(pStart, 2);
867c6a43d28SMatthew G. Knepley *pStart = label->pStart;
868c6a43d28SMatthew G. Knepley }
869c6a43d28SMatthew G. Knepley if (pEnd) {
8704f572ea9SToby Isaac PetscAssertPointer(pEnd, 3);
871c6a43d28SMatthew G. Knepley *pEnd = label->pEnd;
872c6a43d28SMatthew G. Knepley }
8733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
874c6a43d28SMatthew G. Knepley }
875c6a43d28SMatthew G. Knepley
876c6a43d28SMatthew G. Knepley /*@
877c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point
878c58f1c22SToby Isaac
87920f4b53cSBarry Smith Not Collective
8805b5e7992SMatthew G. Knepley
881c58f1c22SToby Isaac Input Parameters:
88220f4b53cSBarry Smith + label - the `DMLabel`
883c58f1c22SToby Isaac - value - the value
884c58f1c22SToby Isaac
885c58f1c22SToby Isaac Output Parameter:
886c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point
887c58f1c22SToby Isaac
888c58f1c22SToby Isaac Level: developer
889c58f1c22SToby Isaac
89020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()`
891c58f1c22SToby Isaac @*/
DMLabelHasValue(DMLabel label,PetscInt value,PetscBool * contains)892d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains)
893d71ae5a4SJacob Faibussowitsch {
894c58f1c22SToby Isaac PetscInt v;
895c58f1c22SToby Isaac
896c58f1c22SToby Isaac PetscFunctionBegin;
897d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
8984f572ea9SToby Isaac PetscAssertPointer(contains, 3);
8999566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
9000c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE;
9013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
902c58f1c22SToby Isaac }
903c58f1c22SToby Isaac
904c58f1c22SToby Isaac /*@
905c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point
906c58f1c22SToby Isaac
90720f4b53cSBarry Smith Not Collective
9085b5e7992SMatthew G. Knepley
909c58f1c22SToby Isaac Input Parameters:
91020f4b53cSBarry Smith + label - the `DMLabel`
911c58f1c22SToby Isaac - point - the point
912c58f1c22SToby Isaac
913c58f1c22SToby Isaac Output Parameter:
914c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value
915c58f1c22SToby Isaac
916c58f1c22SToby Isaac Level: developer
917c58f1c22SToby Isaac
91820f4b53cSBarry Smith Note:
91920f4b53cSBarry Smith The user must call `DMLabelCreateIndex()` before this function.
92020f4b53cSBarry Smith
92120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()`
922c58f1c22SToby Isaac @*/
DMLabelHasPoint(DMLabel label,PetscInt point,PetscBool * contains)923d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains)
924d71ae5a4SJacob Faibussowitsch {
925f1d0ab6dSZach Atkins PetscInt pStart, pEnd;
926f1d0ab6dSZach Atkins
927c58f1c22SToby Isaac PetscFunctionBeginHot;
928d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
9294f572ea9SToby Isaac PetscAssertPointer(contains, 3);
930f1d0ab6dSZach Atkins /* DMLabelGetBounds() calls DMLabelCreateIndex() only if needed */
931f1d0ab6dSZach Atkins PetscCall(DMLabelGetBounds(label, &pStart, &pEnd));
9329566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label));
933f1d0ab6dSZach Atkins *contains = point >= pStart && point < pEnd && (PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE);
9343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
935c58f1c22SToby Isaac }
936c58f1c22SToby Isaac
937c58f1c22SToby Isaac /*@
938c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point
939c58f1c22SToby Isaac
94020f4b53cSBarry Smith Not Collective
9415b5e7992SMatthew G. Knepley
942c58f1c22SToby Isaac Input Parameters:
94320f4b53cSBarry Smith + label - the `DMLabel`
944c58f1c22SToby Isaac . value - the stratum value
945c58f1c22SToby Isaac - point - the point
946c58f1c22SToby Isaac
947c58f1c22SToby Isaac Output Parameter:
948c58f1c22SToby Isaac . contains - true if the stratum contains the point
949c58f1c22SToby Isaac
950c58f1c22SToby Isaac Level: intermediate
951c58f1c22SToby Isaac
95220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`
953c58f1c22SToby Isaac @*/
DMLabelStratumHasPoint(DMLabel label,PetscInt value,PetscInt point,PetscBool * contains)954d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains)
955d71ae5a4SJacob Faibussowitsch {
9560c3c4a36SLisandro Dalcin PetscFunctionBeginHot;
957d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
9584f572ea9SToby Isaac PetscAssertPointer(contains, 4);
959cffad2c9SToby Isaac if (value == label->defaultValue) {
960cffad2c9SToby Isaac PetscInt pointVal;
9610c3c4a36SLisandro Dalcin
962cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal));
963cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value);
964cffad2c9SToby Isaac } else {
965cffad2c9SToby Isaac PetscInt v;
966cffad2c9SToby Isaac
967cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v));
968cffad2c9SToby Isaac if (v >= 0) {
9699f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) {
9709f6c5813SMatthew G. Knepley IS is;
971c58f1c22SToby Isaac PetscInt i;
972c58f1c22SToby Isaac
9739f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is);
9742b4d18a0SMatthew G. Knepley PetscCall(ISLocate(is, point, &i));
9759f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is));
976cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0);
977c58f1c22SToby Isaac } else {
978cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains));
979cffad2c9SToby Isaac }
980cffad2c9SToby Isaac } else { // value is not present
981cffad2c9SToby Isaac *contains = PETSC_FALSE;
982cffad2c9SToby Isaac }
983c58f1c22SToby Isaac }
9843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
985c58f1c22SToby Isaac }
986c58f1c22SToby Isaac
98784f0b6dfSMatthew G. Knepley /*@
98820f4b53cSBarry Smith DMLabelGetDefaultValue - Get the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value.
9895aa44df4SToby Isaac When a label is created, it is initialized to -1.
9905aa44df4SToby Isaac
99120f4b53cSBarry Smith Not Collective
9925b5e7992SMatthew G. Knepley
99360225df5SJacob Faibussowitsch Input Parameter:
99420f4b53cSBarry Smith . label - a `DMLabel` object
9955aa44df4SToby Isaac
99660225df5SJacob Faibussowitsch Output Parameter:
9975aa44df4SToby Isaac . defaultValue - the default value
9985aa44df4SToby Isaac
9995aa44df4SToby Isaac Level: beginner
10005aa44df4SToby Isaac
100120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()`
100284f0b6dfSMatthew G. Knepley @*/
DMLabelGetDefaultValue(DMLabel label,PetscInt * defaultValue)1003d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue)
1004d71ae5a4SJacob Faibussowitsch {
10055aa44df4SToby Isaac PetscFunctionBegin;
1006d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
10075aa44df4SToby Isaac *defaultValue = label->defaultValue;
10083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
10095aa44df4SToby Isaac }
10105aa44df4SToby Isaac
101184f0b6dfSMatthew G. Knepley /*@
101220f4b53cSBarry Smith DMLabelSetDefaultValue - Set the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value.
10135aa44df4SToby Isaac When a label is created, it is initialized to -1.
10145aa44df4SToby Isaac
101520f4b53cSBarry Smith Not Collective
10165b5e7992SMatthew G. Knepley
101760225df5SJacob Faibussowitsch Input Parameter:
101820f4b53cSBarry Smith . label - a `DMLabel` object
10195aa44df4SToby Isaac
102060225df5SJacob Faibussowitsch Output Parameter:
10215aa44df4SToby Isaac . defaultValue - the default value
10225aa44df4SToby Isaac
10235aa44df4SToby Isaac Level: beginner
10245aa44df4SToby Isaac
102520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()`
102684f0b6dfSMatthew G. Knepley @*/
DMLabelSetDefaultValue(DMLabel label,PetscInt defaultValue)1027d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue)
1028d71ae5a4SJacob Faibussowitsch {
10295aa44df4SToby Isaac PetscFunctionBegin;
1030d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
10315aa44df4SToby Isaac label->defaultValue = defaultValue;
10323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
10335aa44df4SToby Isaac }
10345aa44df4SToby Isaac
1035c58f1c22SToby Isaac /*@
103620f4b53cSBarry Smith DMLabelGetValue - Return the value a label assigns to a point, or the label's default value (which is initially -1, and can be changed with
103720f4b53cSBarry Smith `DMLabelSetDefaultValue()`)
1038c58f1c22SToby Isaac
103920f4b53cSBarry Smith Not Collective
10405b5e7992SMatthew G. Knepley
1041c58f1c22SToby Isaac Input Parameters:
104220f4b53cSBarry Smith + label - the `DMLabel`
1043c58f1c22SToby Isaac - point - the point
1044c58f1c22SToby Isaac
1045c58f1c22SToby Isaac Output Parameter:
10468e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default)
1047c58f1c22SToby Isaac
1048c58f1c22SToby Isaac Level: intermediate
1049c58f1c22SToby Isaac
105020f4b53cSBarry Smith Note:
105120f4b53cSBarry Smith A label may assign multiple values to a point. No guarantees are made about which value is returned in that case.
105220f4b53cSBarry Smith Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum.
105320f4b53cSBarry Smith
105420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()`
1055c58f1c22SToby Isaac @*/
DMLabelGetValue(DMLabel label,PetscInt point,PetscInt * value)1056d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value)
1057d71ae5a4SJacob Faibussowitsch {
1058c58f1c22SToby Isaac PetscInt v;
1059c58f1c22SToby Isaac
10600c3c4a36SLisandro Dalcin PetscFunctionBeginHot;
1061d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
10624f572ea9SToby Isaac PetscAssertPointer(value, 3);
10635aa44df4SToby Isaac *value = label->defaultValue;
1064c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) {
10659f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) {
10669f6c5813SMatthew G. Knepley IS is;
1067c58f1c22SToby Isaac PetscInt i;
1068c58f1c22SToby Isaac
10699f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is);
10702b4d18a0SMatthew G. Knepley PetscCall(ISLocate(label->points[v], point, &i));
10719f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is));
1072c58f1c22SToby Isaac if (i >= 0) {
1073c58f1c22SToby Isaac *value = label->stratumValues[v];
1074c58f1c22SToby Isaac break;
1075c58f1c22SToby Isaac }
1076c58f1c22SToby Isaac } else {
1077c58f1c22SToby Isaac PetscBool has;
1078c58f1c22SToby Isaac
10799566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has));
1080c58f1c22SToby Isaac if (has) {
1081c58f1c22SToby Isaac *value = label->stratumValues[v];
1082c58f1c22SToby Isaac break;
1083c58f1c22SToby Isaac }
1084c58f1c22SToby Isaac }
1085c58f1c22SToby Isaac }
10863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1087c58f1c22SToby Isaac }
1088c58f1c22SToby Isaac
1089c58f1c22SToby Isaac /*@
109020f4b53cSBarry Smith DMLabelSetValue - Set the value a label assigns to a point. If the value is the same as the label's default value (which is initially -1, and can
109120f4b53cSBarry Smith be changed with `DMLabelSetDefaultValue()` to something different), then this function will do nothing.
1092c58f1c22SToby Isaac
109320f4b53cSBarry Smith Not Collective
10945b5e7992SMatthew G. Knepley
1095c58f1c22SToby Isaac Input Parameters:
109620f4b53cSBarry Smith + label - the `DMLabel`
1097c58f1c22SToby Isaac . point - the point
1098c58f1c22SToby Isaac - value - The point value
1099c58f1c22SToby Isaac
1100c58f1c22SToby Isaac Level: intermediate
1101c58f1c22SToby Isaac
110220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()`
1103c58f1c22SToby Isaac @*/
DMLabelSetValue(DMLabel label,PetscInt point,PetscInt value)1104d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value)
1105d71ae5a4SJacob Faibussowitsch {
1106c58f1c22SToby Isaac PetscInt v;
1107c58f1c22SToby Isaac
1108c58f1c22SToby Isaac PetscFunctionBegin;
1109d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
11100c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */
11113ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS);
11129f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
11139566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v));
1114c58f1c22SToby Isaac /* Set key */
11159566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v));
11169566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point));
11173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1118c58f1c22SToby Isaac }
1119c58f1c22SToby Isaac
1120c58f1c22SToby Isaac /*@
1121c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point
1122c58f1c22SToby Isaac
112320f4b53cSBarry Smith Not Collective
11245b5e7992SMatthew G. Knepley
1125c58f1c22SToby Isaac Input Parameters:
112620f4b53cSBarry Smith + label - the `DMLabel`
1127c58f1c22SToby Isaac . point - the point
1128c58f1c22SToby Isaac - value - The point value
1129c58f1c22SToby Isaac
1130c58f1c22SToby Isaac Level: intermediate
1131c58f1c22SToby Isaac
113220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`
1133c58f1c22SToby Isaac @*/
DMLabelClearValue(DMLabel label,PetscInt point,PetscInt value)1134d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value)
1135d71ae5a4SJacob Faibussowitsch {
1136ad8374ffSToby Isaac PetscInt v;
1137c58f1c22SToby Isaac
1138c58f1c22SToby Isaac PetscFunctionBegin;
1139d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
11409f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
1141c58f1c22SToby Isaac /* Find label value */
11429566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
11433ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS);
11440c3c4a36SLisandro Dalcin
1145f1d0ab6dSZach Atkins if (label->bt && point >= label->pStart && point < label->pEnd) PetscCall(PetscBTClear(label->bt, point - label->pStart));
11460c3c4a36SLisandro Dalcin
11470c3c4a36SLisandro Dalcin /* Delete key */
11489566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v));
11499566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point));
11503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1151c58f1c22SToby Isaac }
1152c58f1c22SToby Isaac
1153c58f1c22SToby Isaac /*@
115420f4b53cSBarry Smith DMLabelInsertIS - Set all points in the `IS` to a value
1155c58f1c22SToby Isaac
115620f4b53cSBarry Smith Not Collective
11575b5e7992SMatthew G. Knepley
1158c58f1c22SToby Isaac Input Parameters:
115920f4b53cSBarry Smith + label - the `DMLabel`
11602fe279fdSBarry Smith . is - the point `IS`
1161c58f1c22SToby Isaac - value - The point value
1162c58f1c22SToby Isaac
1163c58f1c22SToby Isaac Level: intermediate
1164c58f1c22SToby Isaac
116520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
1166c58f1c22SToby Isaac @*/
DMLabelInsertIS(DMLabel label,IS is,PetscInt value)1167d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value)
1168d71ae5a4SJacob Faibussowitsch {
11690c3c4a36SLisandro Dalcin PetscInt v, n, p;
1170c58f1c22SToby Isaac const PetscInt *points;
1171c58f1c22SToby Isaac
1172c58f1c22SToby Isaac PetscFunctionBegin;
1173d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1174c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2);
11750c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */
11763ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS);
11779f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
11789566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v));
11790c3c4a36SLisandro Dalcin /* Set keys */
11809566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v));
11819566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n));
11829566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points));
11839566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p]));
11849566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points));
11853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1186c58f1c22SToby Isaac }
1187c58f1c22SToby Isaac
118884f0b6dfSMatthew G. Knepley /*@
118920f4b53cSBarry Smith DMLabelGetNumValues - Get the number of values that the `DMLabel` takes
119084f0b6dfSMatthew G. Knepley
119120f4b53cSBarry Smith Not Collective
11925b5e7992SMatthew G. Knepley
119384f0b6dfSMatthew G. Knepley Input Parameter:
119420f4b53cSBarry Smith . label - the `DMLabel`
119584f0b6dfSMatthew G. Knepley
119601d2d390SJose E. Roman Output Parameter:
119784f0b6dfSMatthew G. Knepley . numValues - the number of values
119884f0b6dfSMatthew G. Knepley
119984f0b6dfSMatthew G. Knepley Level: intermediate
120084f0b6dfSMatthew G. Knepley
120120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
120284f0b6dfSMatthew G. Knepley @*/
DMLabelGetNumValues(DMLabel label,PetscInt * numValues)1203d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues)
1204d71ae5a4SJacob Faibussowitsch {
1205c58f1c22SToby Isaac PetscFunctionBegin;
1206d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
12074f572ea9SToby Isaac PetscAssertPointer(numValues, 2);
1208c58f1c22SToby Isaac *numValues = label->numStrata;
12093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1210c58f1c22SToby Isaac }
1211c58f1c22SToby Isaac
121284f0b6dfSMatthew G. Knepley /*@
121320f4b53cSBarry Smith DMLabelGetValueIS - Get an `IS` of all values that the `DMlabel` takes
121484f0b6dfSMatthew G. Knepley
121520f4b53cSBarry Smith Not Collective
12165b5e7992SMatthew G. Knepley
121784f0b6dfSMatthew G. Knepley Input Parameter:
121820f4b53cSBarry Smith . label - the `DMLabel`
121984f0b6dfSMatthew G. Knepley
122001d2d390SJose E. Roman Output Parameter:
122160225df5SJacob Faibussowitsch . values - the value `IS`
122284f0b6dfSMatthew G. Knepley
122384f0b6dfSMatthew G. Knepley Level: intermediate
122484f0b6dfSMatthew G. Knepley
12251d04cbbeSVaclav Hapla Notes:
1226*f59a9984SJames Wright The `values` should be destroyed when no longer needed.
1227*f59a9984SJames Wright
122820f4b53cSBarry Smith Strata which are allocated but empty [`DMLabelGetStratumSize()` yields 0] are counted.
1229*f59a9984SJames Wright
123020f4b53cSBarry Smith If you need to count only nonempty strata, use `DMLabelGetNonEmptyStratumValuesIS()`.
12311d04cbbeSVaclav Hapla
1232*f59a9984SJames Wright .seealso: `DMLabel`, `DM`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetValueISGlobal()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
123384f0b6dfSMatthew G. Knepley @*/
DMLabelGetValueIS(DMLabel label,IS * values)1234d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values)
1235d71ae5a4SJacob Faibussowitsch {
1236c58f1c22SToby Isaac PetscFunctionBegin;
1237d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
12384f572ea9SToby Isaac PetscAssertPointer(values, 2);
12399566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values));
12403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1241c58f1c22SToby Isaac }
1242c58f1c22SToby Isaac
124384f0b6dfSMatthew G. Knepley /*@
12448696263dSMatthew G. Knepley DMLabelGetValueBounds - Return the smallest and largest value in the label
12458696263dSMatthew G. Knepley
12468696263dSMatthew G. Knepley Not Collective
12478696263dSMatthew G. Knepley
12488696263dSMatthew G. Knepley Input Parameter:
12498696263dSMatthew G. Knepley . label - the `DMLabel`
12508696263dSMatthew G. Knepley
12518696263dSMatthew G. Knepley Output Parameters:
12528696263dSMatthew G. Knepley + minValue - The smallest value
12538696263dSMatthew G. Knepley - maxValue - The largest value
12548696263dSMatthew G. Knepley
12558696263dSMatthew G. Knepley Level: intermediate
12568696263dSMatthew G. Knepley
12578696263dSMatthew G. Knepley .seealso: `DMLabel`, `DM`, `DMLabelGetBounds()`, `DMLabelGetValue()`, `DMLabelSetValue()`
12588696263dSMatthew G. Knepley @*/
DMLabelGetValueBounds(DMLabel label,PetscInt * minValue,PetscInt * maxValue)12598696263dSMatthew G. Knepley PetscErrorCode DMLabelGetValueBounds(DMLabel label, PetscInt *minValue, PetscInt *maxValue)
12608696263dSMatthew G. Knepley {
12611690c2aeSBarry Smith PetscInt min = PETSC_INT_MAX, max = PETSC_INT_MIN;
12628696263dSMatthew G. Knepley
12638696263dSMatthew G. Knepley PetscFunctionBegin;
12648696263dSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
12658696263dSMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) {
12668696263dSMatthew G. Knepley min = PetscMin(min, label->stratumValues[v]);
12678696263dSMatthew G. Knepley max = PetscMax(max, label->stratumValues[v]);
12688696263dSMatthew G. Knepley }
12698696263dSMatthew G. Knepley if (minValue) {
12708696263dSMatthew G. Knepley PetscAssertPointer(minValue, 2);
12718696263dSMatthew G. Knepley *minValue = min;
12728696263dSMatthew G. Knepley }
12738696263dSMatthew G. Knepley if (maxValue) {
12748696263dSMatthew G. Knepley PetscAssertPointer(maxValue, 3);
12758696263dSMatthew G. Knepley *maxValue = max;
12768696263dSMatthew G. Knepley }
12778696263dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS);
12788696263dSMatthew G. Knepley }
12798696263dSMatthew G. Knepley
12808696263dSMatthew G. Knepley /*@
128120f4b53cSBarry Smith DMLabelGetNonEmptyStratumValuesIS - Get an `IS` of all values that the `DMlabel` takes
12821d04cbbeSVaclav Hapla
128320f4b53cSBarry Smith Not Collective
12841d04cbbeSVaclav Hapla
12851d04cbbeSVaclav Hapla Input Parameter:
128620f4b53cSBarry Smith . label - the `DMLabel`
12871d04cbbeSVaclav Hapla
1288d5b43468SJose E. Roman Output Parameter:
128960225df5SJacob Faibussowitsch . values - the value `IS`
12901d04cbbeSVaclav Hapla
12911d04cbbeSVaclav Hapla Level: intermediate
12921d04cbbeSVaclav Hapla
12931d04cbbeSVaclav Hapla Notes:
1294*f59a9984SJames Wright The `values` should be destroyed when no longer needed.
1295*f59a9984SJames Wright
129620f4b53cSBarry Smith This is similar to `DMLabelGetValueIS()` but counts only nonempty strata.
12971d04cbbeSVaclav Hapla
1298*f59a9984SJames Wright .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelGetValueISGlobal()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
12991d04cbbeSVaclav Hapla @*/
DMLabelGetNonEmptyStratumValuesIS(DMLabel label,IS * values)1300d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values)
1301d71ae5a4SJacob Faibussowitsch {
13021d04cbbeSVaclav Hapla PetscInt i, j;
13031d04cbbeSVaclav Hapla PetscInt *valuesArr;
13041d04cbbeSVaclav Hapla
13051d04cbbeSVaclav Hapla PetscFunctionBegin;
13061d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
13074f572ea9SToby Isaac PetscAssertPointer(values, 2);
13089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr));
13091d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) {
13101d04cbbeSVaclav Hapla PetscInt n;
13111d04cbbeSVaclav Hapla
13129566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n));
13131d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i];
13141d04cbbeSVaclav Hapla }
13151d04cbbeSVaclav Hapla if (j == label->numStrata) {
13169566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values));
13171d04cbbeSVaclav Hapla } else {
13189566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values));
13191d04cbbeSVaclav Hapla }
13209566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr));
13213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
13221d04cbbeSVaclav Hapla }
13231d04cbbeSVaclav Hapla
13241d04cbbeSVaclav Hapla /*@
1325*f59a9984SJames Wright DMLabelGetValueISGlobal - Get an `IS` of all values that the `DMlabel` takes across all ranks
1326*f59a9984SJames Wright
1327*f59a9984SJames Wright Collective
1328*f59a9984SJames Wright
1329*f59a9984SJames Wright Input Parameter:
1330*f59a9984SJames Wright + comm - MPI communicator to collect values
1331*f59a9984SJames Wright . label - the `DMLabel`, may be `NULL` for ranks in `comm` which do not have the corresponding `DMLabel`
1332*f59a9984SJames Wright - get_nonempty - whether to get nonempty stratum values (akin to `DMLabelGetNonEmptyStratumValuesIS()`)
1333*f59a9984SJames Wright
1334*f59a9984SJames Wright Output Parameter:
1335*f59a9984SJames Wright . values - the value `IS`
1336*f59a9984SJames Wright
1337*f59a9984SJames Wright Level: intermediate
1338*f59a9984SJames Wright
1339*f59a9984SJames Wright Notes:
1340*f59a9984SJames Wright The `values` should be destroyed when no longer needed.
1341*f59a9984SJames Wright
1342*f59a9984SJames Wright This is similar to `DMLabelGetValueIS()` and `DMLabelGetNonEmptyStratumValuesIS()`, but gets the (nonempty) values across all ranks in `comm`.
1343*f59a9984SJames Wright
1344*f59a9984SJames Wright .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
1345*f59a9984SJames Wright @*/
DMLabelGetValueISGlobal(MPI_Comm comm,DMLabel label,PetscBool get_nonempty,IS * values)1346*f59a9984SJames Wright PetscErrorCode DMLabelGetValueISGlobal(MPI_Comm comm, DMLabel label, PetscBool get_nonempty, IS *values)
1347*f59a9984SJames Wright {
1348*f59a9984SJames Wright PetscInt num_values_local = 0, num_values_global, minmax_values[2], minmax_values_loc[2] = {PETSC_INT_MAX, PETSC_INT_MIN};
1349*f59a9984SJames Wright IS is_values = NULL;
1350*f59a9984SJames Wright const PetscInt *values_local = NULL;
1351*f59a9984SJames Wright PetscInt *values_global;
1352*f59a9984SJames Wright
1353*f59a9984SJames Wright PetscFunctionBegin;
1354*f59a9984SJames Wright if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2);
1355*f59a9984SJames Wright if (PetscDefined(USE_DEBUG)) {
1356*f59a9984SJames Wright // Shenanigans because PetscValidLogicalCollectiveBool must have a PetscObject to get a MPI_Comm from, but there is no such object in this function (generally, DMLabel is only PETSC_COMM_SELF)
1357*f59a9984SJames Wright IS dummy;
1358*f59a9984SJames Wright PetscCall(ISCreate(comm, &dummy));
1359*f59a9984SJames Wright PetscValidLogicalCollectiveBool(dummy, get_nonempty, 3);
1360*f59a9984SJames Wright PetscCall(ISDestroy(&dummy));
1361*f59a9984SJames Wright }
1362*f59a9984SJames Wright PetscAssertPointer(values, 4);
1363*f59a9984SJames Wright
1364*f59a9984SJames Wright if (label) {
1365*f59a9984SJames Wright if (get_nonempty) PetscCall(DMLabelGetNonEmptyStratumValuesIS(label, &is_values));
1366*f59a9984SJames Wright else PetscCall(DMLabelGetValueIS(label, &is_values));
1367*f59a9984SJames Wright PetscCall(ISGetIndices(is_values, &values_local));
1368*f59a9984SJames Wright PetscCall(ISGetLocalSize(is_values, &num_values_local));
1369*f59a9984SJames Wright }
1370*f59a9984SJames Wright for (PetscInt i = 0; i < num_values_local; i++) {
1371*f59a9984SJames Wright minmax_values_loc[0] = PetscMin(minmax_values_loc[0], values_local[i]);
1372*f59a9984SJames Wright minmax_values_loc[1] = PetscMax(minmax_values_loc[1], values_local[i]);
1373*f59a9984SJames Wright }
1374*f59a9984SJames Wright
1375*f59a9984SJames Wright PetscCall(PetscGlobalMinMaxInt(comm, minmax_values_loc, minmax_values));
1376*f59a9984SJames Wright PetscInt value_range = minmax_values[1] - minmax_values[0] + 1;
1377*f59a9984SJames Wright PetscBT local_values_bt, global_values_bt;
1378*f59a9984SJames Wright
1379*f59a9984SJames Wright // Create a "ballot" where each rank marks which values they have into the PetscBT.
1380*f59a9984SJames Wright // An Allreduce using bitwise-OR over the ranks then communicates which values are owned by a rank in comm
1381*f59a9984SJames Wright PetscCall(PetscBTCreate(value_range, &local_values_bt));
1382*f59a9984SJames Wright PetscCall(PetscBTCreate(value_range, &global_values_bt));
1383*f59a9984SJames Wright for (PetscInt i = 0; i < num_values_local; i++) PetscCall(PetscBTSet(local_values_bt, values_local[i] - minmax_values[0]));
1384*f59a9984SJames Wright PetscCallMPI(MPIU_Allreduce(local_values_bt, global_values_bt, PetscBTLength(value_range), MPI_CHAR, MPI_BOR, comm));
1385*f59a9984SJames Wright PetscCall(PetscBTDestroy(&local_values_bt));
1386*f59a9984SJames Wright {
1387*f59a9984SJames Wright PetscCount num_values_global_count;
1388*f59a9984SJames Wright num_values_global_count = PetscBTCountSet(global_values_bt, value_range);
1389*f59a9984SJames Wright PetscCall(PetscIntCast(num_values_global_count, &num_values_global));
1390*f59a9984SJames Wright }
1391*f59a9984SJames Wright
1392*f59a9984SJames Wright PetscCall(PetscMalloc1(num_values_global, &values_global));
1393*f59a9984SJames Wright for (PetscInt i = 0, a = 0; i < value_range; i++) {
1394*f59a9984SJames Wright if (PetscBTLookup(global_values_bt, i)) {
1395*f59a9984SJames Wright values_global[a] = i + minmax_values[0];
1396*f59a9984SJames Wright a++;
1397*f59a9984SJames Wright }
1398*f59a9984SJames Wright }
1399*f59a9984SJames Wright PetscCall(ISCreateGeneral(PETSC_COMM_SELF, num_values_global, values_global, PETSC_OWN_POINTER, values));
1400*f59a9984SJames Wright
1401*f59a9984SJames Wright PetscCall(PetscBTDestroy(&global_values_bt));
1402*f59a9984SJames Wright if (is_values) {
1403*f59a9984SJames Wright PetscCall(ISRestoreIndices(is_values, &values_local));
1404*f59a9984SJames Wright PetscCall(ISDestroy(&is_values));
1405*f59a9984SJames Wright }
1406*f59a9984SJames Wright PetscFunctionReturn(PETSC_SUCCESS);
1407*f59a9984SJames Wright }
1408*f59a9984SJames Wright
1409*f59a9984SJames Wright /*@
141020f4b53cSBarry Smith DMLabelGetValueIndex - Get the index of a given value in the list of values for the `DMlabel`, or -1 if it is not present
1411d123abd9SMatthew G. Knepley
141220f4b53cSBarry Smith Not Collective
1413d123abd9SMatthew G. Knepley
1414d123abd9SMatthew G. Knepley Input Parameters:
141520f4b53cSBarry Smith + label - the `DMLabel`
141697bb3fdcSJose E. Roman - value - the value
1417d123abd9SMatthew G. Knepley
141801d2d390SJose E. Roman Output Parameter:
1419d123abd9SMatthew G. Knepley . index - the index of value in the list of values
1420d123abd9SMatthew G. Knepley
1421d123abd9SMatthew G. Knepley Level: intermediate
1422d123abd9SMatthew G. Knepley
142320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
1424d123abd9SMatthew G. Knepley @*/
DMLabelGetValueIndex(DMLabel label,PetscInt value,PetscInt * index)1425d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index)
1426d71ae5a4SJacob Faibussowitsch {
1427d123abd9SMatthew G. Knepley PetscInt v;
1428d123abd9SMatthew G. Knepley
1429d123abd9SMatthew G. Knepley PetscFunctionBegin;
1430d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
14314f572ea9SToby Isaac PetscAssertPointer(index, 3);
1432d123abd9SMatthew G. Knepley /* Do not assume they are sorted */
14339371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v)
14349371c9d4SSatish Balay if (label->stratumValues[v] == value) break;
1435d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1;
1436d123abd9SMatthew G. Knepley else *index = v;
14373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1438d123abd9SMatthew G. Knepley }
1439d123abd9SMatthew G. Knepley
1440d123abd9SMatthew G. Knepley /*@
144184f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value
144284f0b6dfSMatthew G. Knepley
144320f4b53cSBarry Smith Not Collective
14445b5e7992SMatthew G. Knepley
144584f0b6dfSMatthew G. Knepley Input Parameters:
144620f4b53cSBarry Smith + label - the `DMLabel`
144784f0b6dfSMatthew G. Knepley - value - the stratum value
144884f0b6dfSMatthew G. Knepley
144901d2d390SJose E. Roman Output Parameter:
145084f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist
145184f0b6dfSMatthew G. Knepley
145284f0b6dfSMatthew G. Knepley Level: intermediate
145384f0b6dfSMatthew G. Knepley
145420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
145584f0b6dfSMatthew G. Knepley @*/
DMLabelHasStratum(DMLabel label,PetscInt value,PetscBool * exists)1456d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists)
1457d71ae5a4SJacob Faibussowitsch {
1458fada774cSMatthew G. Knepley PetscInt v;
1459fada774cSMatthew G. Knepley
1460fada774cSMatthew G. Knepley PetscFunctionBegin;
1461d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
14624f572ea9SToby Isaac PetscAssertPointer(exists, 3);
14639566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
14640c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE;
14653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1466fada774cSMatthew G. Knepley }
1467fada774cSMatthew G. Knepley
146884f0b6dfSMatthew G. Knepley /*@
146984f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum
147084f0b6dfSMatthew G. Knepley
147120f4b53cSBarry Smith Not Collective
14725b5e7992SMatthew G. Knepley
147384f0b6dfSMatthew G. Knepley Input Parameters:
147420f4b53cSBarry Smith + label - the `DMLabel`
147584f0b6dfSMatthew G. Knepley - value - the stratum value
147684f0b6dfSMatthew G. Knepley
147701d2d390SJose E. Roman Output Parameter:
147884f0b6dfSMatthew G. Knepley . size - The number of points in the stratum
147984f0b6dfSMatthew G. Knepley
148084f0b6dfSMatthew G. Knepley Level: intermediate
148184f0b6dfSMatthew G. Knepley
148220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
148384f0b6dfSMatthew G. Knepley @*/
DMLabelGetStratumSize(DMLabel label,PetscInt value,PetscInt * size)1484d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size)
1485d71ae5a4SJacob Faibussowitsch {
1486c58f1c22SToby Isaac PetscInt v;
1487c58f1c22SToby Isaac
1488c58f1c22SToby Isaac PetscFunctionBegin;
1489d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
14904f572ea9SToby Isaac PetscAssertPointer(size, 3);
14919566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
14929566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size));
14933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1494c58f1c22SToby Isaac }
1495c58f1c22SToby Isaac
149684f0b6dfSMatthew G. Knepley /*@
149784f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum
149884f0b6dfSMatthew G. Knepley
149920f4b53cSBarry Smith Not Collective
15005b5e7992SMatthew G. Knepley
150184f0b6dfSMatthew G. Knepley Input Parameters:
150220f4b53cSBarry Smith + label - the `DMLabel`
150384f0b6dfSMatthew G. Knepley - value - the stratum value
150484f0b6dfSMatthew G. Knepley
150501d2d390SJose E. Roman Output Parameters:
150684f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum
150784f0b6dfSMatthew G. Knepley - end - the largest point in the stratum
150884f0b6dfSMatthew G. Knepley
150984f0b6dfSMatthew G. Knepley Level: intermediate
151084f0b6dfSMatthew G. Knepley
151120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
151284f0b6dfSMatthew G. Knepley @*/
DMLabelGetStratumBounds(DMLabel label,PetscInt value,PetscInt * start,PetscInt * end)1513d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end)
1514d71ae5a4SJacob Faibussowitsch {
15159f6c5813SMatthew G. Knepley IS is;
15160c3c4a36SLisandro Dalcin PetscInt v, min, max;
1517c58f1c22SToby Isaac
1518c58f1c22SToby Isaac PetscFunctionBegin;
1519d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
15209371c9d4SSatish Balay if (start) {
15214f572ea9SToby Isaac PetscAssertPointer(start, 3);
15229371c9d4SSatish Balay *start = -1;
15239371c9d4SSatish Balay }
15249371c9d4SSatish Balay if (end) {
15254f572ea9SToby Isaac PetscAssertPointer(end, 4);
15269371c9d4SSatish Balay *end = -1;
15279371c9d4SSatish Balay }
15289566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
15293ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS);
15309566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v));
15313ba16761SJacob Faibussowitsch if (label->stratumSizes[v] <= 0) PetscFunctionReturn(PETSC_SUCCESS);
15329f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is);
15339f6c5813SMatthew G. Knepley PetscCall(ISGetMinMax(is, &min, &max));
15349f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is));
1535d6cb179aSToby Isaac if (start) *start = min;
1536d6cb179aSToby Isaac if (end) *end = max + 1;
15373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1538c58f1c22SToby Isaac }
1539c58f1c22SToby Isaac
DMLabelGetStratumIS_Concrete(DMLabel label,PetscInt v,IS * pointIS)154066976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelGetStratumIS_Concrete(DMLabel label, PetscInt v, IS *pointIS)
15419f6c5813SMatthew G. Knepley {
15429f6c5813SMatthew G. Knepley PetscFunctionBegin;
15439f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)label->points[v]));
15449f6c5813SMatthew G. Knepley *pointIS = label->points[v];
15453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
15469f6c5813SMatthew G. Knepley }
15479f6c5813SMatthew G. Knepley
154884f0b6dfSMatthew G. Knepley /*@
154920f4b53cSBarry Smith DMLabelGetStratumIS - Get an `IS` with the stratum points
155084f0b6dfSMatthew G. Knepley
155120f4b53cSBarry Smith Not Collective
15525b5e7992SMatthew G. Knepley
155384f0b6dfSMatthew G. Knepley Input Parameters:
155420f4b53cSBarry Smith + label - the `DMLabel`
155584f0b6dfSMatthew G. Knepley - value - the stratum value
155684f0b6dfSMatthew G. Knepley
155701d2d390SJose E. Roman Output Parameter:
155884f0b6dfSMatthew G. Knepley . points - The stratum points
155984f0b6dfSMatthew G. Knepley
156084f0b6dfSMatthew G. Knepley Level: intermediate
156184f0b6dfSMatthew G. Knepley
1562593ce467SVaclav Hapla Notes:
156320f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed.
156420f4b53cSBarry Smith Returns `NULL` if the stratum is empty.
1565593ce467SVaclav Hapla
156620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
156784f0b6dfSMatthew G. Knepley @*/
DMLabelGetStratumIS(DMLabel label,PetscInt value,IS * points)1568d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points)
1569d71ae5a4SJacob Faibussowitsch {
1570c58f1c22SToby Isaac PetscInt v;
1571c58f1c22SToby Isaac
1572c58f1c22SToby Isaac PetscFunctionBegin;
1573d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
15744f572ea9SToby Isaac PetscAssertPointer(points, 3);
1575c58f1c22SToby Isaac *points = NULL;
15769566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
15773ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS);
15789566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v));
15799f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, points);
15803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1581c58f1c22SToby Isaac }
1582c58f1c22SToby Isaac
158384f0b6dfSMatthew G. Knepley /*@
158420f4b53cSBarry Smith DMLabelSetStratumIS - Set the stratum points using an `IS`
158584f0b6dfSMatthew G. Knepley
158620f4b53cSBarry Smith Not Collective
15875b5e7992SMatthew G. Knepley
158884f0b6dfSMatthew G. Knepley Input Parameters:
158920f4b53cSBarry Smith + label - the `DMLabel`
159084f0b6dfSMatthew G. Knepley . value - the stratum value
159160225df5SJacob Faibussowitsch - is - The stratum points
159284f0b6dfSMatthew G. Knepley
159384f0b6dfSMatthew G. Knepley Level: intermediate
159484f0b6dfSMatthew G. Knepley
159520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
159684f0b6dfSMatthew G. Knepley @*/
DMLabelSetStratumIS(DMLabel label,PetscInt value,IS is)1597d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is)
1598d71ae5a4SJacob Faibussowitsch {
15990c3c4a36SLisandro Dalcin PetscInt v;
16004de306b1SToby Isaac
16014de306b1SToby Isaac PetscFunctionBegin;
1602d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1603d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3);
16049f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
16059566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v));
16063ba16761SJacob Faibussowitsch if (is == label->points[v]) PetscFunctionReturn(PETSC_SUCCESS);
16079566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value));
1608f4f49eeaSPierre Jolivet PetscCall(ISGetLocalSize(is, &label->stratumSizes[v]));
16099566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is));
1610f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v]));
16110c3c4a36SLisandro Dalcin label->points[v] = is;
16120c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE;
16139566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label));
16144de306b1SToby Isaac if (label->bt) {
16154de306b1SToby Isaac const PetscInt *points;
16164de306b1SToby Isaac PetscInt p;
16174de306b1SToby Isaac
16189566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points));
16194de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) {
16204de306b1SToby Isaac const PetscInt point = points[p];
16214de306b1SToby Isaac
162263a3b9bcSJacob Faibussowitsch PetscCheck(!(point < label->pStart) && !(point >= label->pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->pStart, label->pEnd);
16239566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart));
16244de306b1SToby Isaac }
16254de306b1SToby Isaac }
16263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
16274de306b1SToby Isaac }
16284de306b1SToby Isaac
162984f0b6dfSMatthew G. Knepley /*@
163084f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum
16314de306b1SToby Isaac
163220f4b53cSBarry Smith Not Collective
16335b5e7992SMatthew G. Knepley
163484f0b6dfSMatthew G. Knepley Input Parameters:
163520f4b53cSBarry Smith + label - the `DMLabel`
163684f0b6dfSMatthew G. Knepley - value - the stratum value
163784f0b6dfSMatthew G. Knepley
163884f0b6dfSMatthew G. Knepley Level: intermediate
163984f0b6dfSMatthew G. Knepley
164020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
164184f0b6dfSMatthew G. Knepley @*/
DMLabelClearStratum(DMLabel label,PetscInt value)1642d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value)
1643d71ae5a4SJacob Faibussowitsch {
1644c58f1c22SToby Isaac PetscInt v;
1645c58f1c22SToby Isaac
1646c58f1c22SToby Isaac PetscFunctionBegin;
1647d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
16489f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
16499566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
16503ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS);
16514de306b1SToby Isaac if (label->validIS[v]) {
16524de306b1SToby Isaac if (label->bt) {
1653c58f1c22SToby Isaac PetscInt i;
1654ad8374ffSToby Isaac const PetscInt *points;
1655c58f1c22SToby Isaac
16569566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points));
1657c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) {
1658ad8374ffSToby Isaac const PetscInt point = points[i];
1659c58f1c22SToby Isaac
1660f1d0ab6dSZach Atkins if (point >= label->pStart && point < label->pEnd) PetscCall(PetscBTClear(label->bt, point - label->pStart));
1661c58f1c22SToby Isaac }
16629566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points));
1663c58f1c22SToby Isaac }
1664c58f1c22SToby Isaac label->stratumSizes[v] = 0;
16659566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v]));
16669566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v]));
16679566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices"));
16689566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label));
1669c58f1c22SToby Isaac } else {
16709566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v]));
1671c58f1c22SToby Isaac }
16723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1673c58f1c22SToby Isaac }
1674c58f1c22SToby Isaac
167584f0b6dfSMatthew G. Knepley /*@
1676412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value
1677412e9a14SMatthew G. Knepley
167820f4b53cSBarry Smith Not Collective
1679412e9a14SMatthew G. Knepley
1680412e9a14SMatthew G. Knepley Input Parameters:
168120f4b53cSBarry Smith + label - The `DMLabel`
1682412e9a14SMatthew G. Knepley . value - The label value for all points
1683412e9a14SMatthew G. Knepley . pStart - The first point
1684412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points
1685412e9a14SMatthew G. Knepley
1686412e9a14SMatthew G. Knepley Level: intermediate
1687412e9a14SMatthew G. Knepley
168820f4b53cSBarry Smith Note:
168920f4b53cSBarry Smith The marks points are [`pStart`, `pEnd`), and only the bounds are stored.
169020f4b53cSBarry Smith
169120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()`
1692412e9a14SMatthew G. Knepley @*/
DMLabelSetStratumBounds(DMLabel label,PetscInt value,PetscInt pStart,PetscInt pEnd)1693d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd)
1694d71ae5a4SJacob Faibussowitsch {
1695412e9a14SMatthew G. Knepley IS pIS;
1696412e9a14SMatthew G. Knepley
1697412e9a14SMatthew G. Knepley PetscFunctionBegin;
16989566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS));
16999566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS));
17009566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS));
17013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1702412e9a14SMatthew G. Knepley }
1703412e9a14SMatthew G. Knepley
1704412e9a14SMatthew G. Knepley /*@
1705d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum
1706d123abd9SMatthew G. Knepley
170720f4b53cSBarry Smith Not Collective
1708d123abd9SMatthew G. Knepley
1709d123abd9SMatthew G. Knepley Input Parameters:
171020f4b53cSBarry Smith + label - The `DMLabel`
1711d123abd9SMatthew G. Knepley . value - The label value
1712d123abd9SMatthew G. Knepley - p - A point with this value
1713d123abd9SMatthew G. Knepley
1714d123abd9SMatthew G. Knepley Output Parameter:
1715d123abd9SMatthew G. Knepley . index - The index of this point in the stratum, or -1 if the point is not in the stratum or the stratum does not exist
1716d123abd9SMatthew G. Knepley
1717d123abd9SMatthew G. Knepley Level: intermediate
1718d123abd9SMatthew G. Knepley
171920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()`
1720d123abd9SMatthew G. Knepley @*/
DMLabelGetStratumPointIndex(DMLabel label,PetscInt value,PetscInt p,PetscInt * index)1721d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index)
1722d71ae5a4SJacob Faibussowitsch {
17239f6c5813SMatthew G. Knepley IS pointIS;
1724d123abd9SMatthew G. Knepley PetscInt v;
1725d123abd9SMatthew G. Knepley
1726d123abd9SMatthew G. Knepley PetscFunctionBegin;
1727d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
17284f572ea9SToby Isaac PetscAssertPointer(index, 4);
1729d123abd9SMatthew G. Knepley *index = -1;
17309566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v));
17313ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS);
17329566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v));
17339f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS);
1734f622de60SMatthew G. Knepley PetscCall(ISLocate(pointIS, p, index));
17359f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS));
17363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1737d123abd9SMatthew G. Knepley }
1738d123abd9SMatthew G. Knepley
1739d123abd9SMatthew G. Knepley /*@
174020f4b53cSBarry Smith DMLabelFilter - Remove all points outside of [`start`, `end`)
174184f0b6dfSMatthew G. Knepley
174220f4b53cSBarry Smith Not Collective
17435b5e7992SMatthew G. Knepley
174484f0b6dfSMatthew G. Knepley Input Parameters:
174520f4b53cSBarry Smith + label - the `DMLabel`
174622cd2cdaSVaclav Hapla . start - the first point kept
174722cd2cdaSVaclav Hapla - end - one more than the last point kept
174884f0b6dfSMatthew G. Knepley
174984f0b6dfSMatthew G. Knepley Level: intermediate
175084f0b6dfSMatthew G. Knepley
175120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
175284f0b6dfSMatthew G. Knepley @*/
DMLabelFilter(DMLabel label,PetscInt start,PetscInt end)1753d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end)
1754d71ae5a4SJacob Faibussowitsch {
1755c58f1c22SToby Isaac PetscInt v;
1756c58f1c22SToby Isaac
1757c58f1c22SToby Isaac PetscFunctionBegin;
1758d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
17599f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
17609566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label));
17619566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label));
17629f6c5813SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) {
17639f6c5813SMatthew G. Knepley PetscCall(ISGeneralFilter(label->points[v], start, end));
17649f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(label->points[v], &label->stratumSizes[v]));
17659f6c5813SMatthew G. Knepley }
17669566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end));
17673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1768c58f1c22SToby Isaac }
1769c58f1c22SToby Isaac
177084f0b6dfSMatthew G. Knepley /*@
177184f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points
177284f0b6dfSMatthew G. Knepley
177320f4b53cSBarry Smith Not Collective
17745b5e7992SMatthew G. Knepley
177584f0b6dfSMatthew G. Knepley Input Parameters:
177620f4b53cSBarry Smith + label - the `DMLabel`
177784f0b6dfSMatthew G. Knepley - permutation - the point permutation
177884f0b6dfSMatthew G. Knepley
177984f0b6dfSMatthew G. Knepley Output Parameter:
178060225df5SJacob Faibussowitsch . labelNew - the new label containing the permuted points
178184f0b6dfSMatthew G. Knepley
178284f0b6dfSMatthew G. Knepley Level: intermediate
178384f0b6dfSMatthew G. Knepley
178420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
178584f0b6dfSMatthew G. Knepley @*/
DMLabelPermute(DMLabel label,IS permutation,DMLabel * labelNew)1786d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew)
1787d71ae5a4SJacob Faibussowitsch {
1788c58f1c22SToby Isaac const PetscInt *perm;
1789c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q;
1790c58f1c22SToby Isaac
1791c58f1c22SToby Isaac PetscFunctionBegin;
1792d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1793d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2);
17949f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
17959566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label));
17969566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew));
17979566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues));
17989566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints));
17999566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm));
1800c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) {
1801c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v];
1802ad8374ffSToby Isaac const PetscInt *points;
1803ad8374ffSToby Isaac PetscInt *pointsNew;
1804c58f1c22SToby Isaac
18059566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points));
18069f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(size, &pointsNew));
1807c58f1c22SToby Isaac for (q = 0; q < size; ++q) {
1808ad8374ffSToby Isaac const PetscInt point = points[q];
1809c58f1c22SToby Isaac
181063a3b9bcSJacob Faibussowitsch PetscCheck(!(point < 0) && !(point >= numPoints), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ") for the remapping", point, numPoints);
1811ad8374ffSToby Isaac pointsNew[q] = perm[point];
1812c58f1c22SToby Isaac }
18139566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points));
18149566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew));
181557508eceSPierre Jolivet PetscCall(ISDestroy(&(*labelNew)->points[v]));
1816fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) {
18179566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v])));
18189566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew));
1819fa8e8ae5SToby Isaac } else {
18209566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v])));
1821fa8e8ae5SToby Isaac }
18229566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices"));
1823c58f1c22SToby Isaac }
18249566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm));
1825c58f1c22SToby Isaac if (label->bt) {
18269566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt));
18279566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd));
1828c58f1c22SToby Isaac }
18293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1830c58f1c22SToby Isaac }
1831c58f1c22SToby Isaac
18325552b385SBrandon /*@
18335552b385SBrandon DMLabelPermuteValues - Permute the values in a label
18345552b385SBrandon
18355552b385SBrandon Not collective
18365552b385SBrandon
18375552b385SBrandon Input Parameters:
18385552b385SBrandon + label - the `DMLabel`
18395552b385SBrandon - permutation - the value permutation, permutation[old value] = new value
18405552b385SBrandon
18415552b385SBrandon Output Parameter:
18425552b385SBrandon . label - the `DMLabel` now with permuted values
18435552b385SBrandon
18445552b385SBrandon Note:
18455552b385SBrandon The modification is done in-place
18465552b385SBrandon
18475552b385SBrandon Level: intermediate
18485552b385SBrandon
18495552b385SBrandon .seealso: `DMLabelRewriteValues()`, `DMLabel`, `DM`, `DMLabelPermute()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
18505552b385SBrandon @*/
DMLabelPermuteValues(DMLabel label,IS permutation)18515552b385SBrandon PetscErrorCode DMLabelPermuteValues(DMLabel label, IS permutation)
18525552b385SBrandon {
18535552b385SBrandon PetscInt Nv, Np;
18545552b385SBrandon
18555552b385SBrandon PetscFunctionBegin;
18565552b385SBrandon PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
18575552b385SBrandon PetscValidHeaderSpecific(permutation, IS_CLASSID, 2);
18585552b385SBrandon PetscCall(DMLabelGetNumValues(label, &Nv));
18595552b385SBrandon PetscCall(ISGetLocalSize(permutation, &Np));
18605552b385SBrandon PetscCheck(Np == Nv, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_SIZ, "Permutation has size %" PetscInt_FMT " != %" PetscInt_FMT " number of label values", Np, Nv);
18615552b385SBrandon if (PetscDefined(USE_DEBUG)) {
18625552b385SBrandon PetscBool flg;
18635552b385SBrandon PetscCall(ISGetInfo(permutation, IS_PERMUTATION, IS_LOCAL, PETSC_TRUE, &flg));
18645552b385SBrandon PetscCheck(flg, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "IS is not a permutation");
18655552b385SBrandon }
18665552b385SBrandon PetscCall(DMLabelRewriteValues(label, permutation));
18675552b385SBrandon PetscFunctionReturn(PETSC_SUCCESS);
18685552b385SBrandon }
18695552b385SBrandon
18705552b385SBrandon /*@
18715552b385SBrandon DMLabelRewriteValues - Permute the values in a label, but some may be omitted
18725552b385SBrandon
18735552b385SBrandon Not collective
18745552b385SBrandon
18755552b385SBrandon Input Parameters:
18765552b385SBrandon + label - the `DMLabel`
18775552b385SBrandon - permutation - the value permutation, permutation[old value] = new value, but some maybe omitted
18785552b385SBrandon
18795552b385SBrandon Output Parameter:
18805552b385SBrandon . label - the `DMLabel` now with permuted values
18815552b385SBrandon
18825552b385SBrandon Note:
18835552b385SBrandon The modification is done in-place
18845552b385SBrandon
18855552b385SBrandon Level: intermediate
18865552b385SBrandon
18875552b385SBrandon .seealso: `DMLabelPermuteValues()`, `DMLabel`, `DM`, `DMLabelPermute()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
18885552b385SBrandon @*/
DMLabelRewriteValues(DMLabel label,IS permutation)18895552b385SBrandon PetscErrorCode DMLabelRewriteValues(DMLabel label, IS permutation)
18905552b385SBrandon {
18915552b385SBrandon const PetscInt *perm;
18925552b385SBrandon PetscInt Nv, Np;
18935552b385SBrandon
18945552b385SBrandon PetscFunctionBegin;
18955552b385SBrandon PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
18965552b385SBrandon PetscValidHeaderSpecific(permutation, IS_CLASSID, 2);
18975552b385SBrandon PetscCall(DMLabelMakeAllValid_Private(label));
18985552b385SBrandon PetscCall(DMLabelGetNumValues(label, &Nv));
18995552b385SBrandon PetscCall(ISGetLocalSize(permutation, &Np));
19005552b385SBrandon PetscCheck(Np >= Nv, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_SIZ, "Permutation has size %" PetscInt_FMT " < %" PetscInt_FMT " number of label values", Np, Nv);
19015552b385SBrandon PetscCall(ISGetIndices(permutation, &perm));
19025552b385SBrandon for (PetscInt v = 0; v < Nv; ++v) label->stratumValues[v] = perm[label->stratumValues[v]];
19035552b385SBrandon PetscCall(ISRestoreIndices(permutation, &perm));
19045552b385SBrandon PetscFunctionReturn(PETSC_SUCCESS);
19055552b385SBrandon }
19065552b385SBrandon
DMLabelDistribute_Internal(DMLabel label,PetscSF sf,PetscSection * leafSection,PetscInt ** leafStrata)190766976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata)
1908d71ae5a4SJacob Faibussowitsch {
190926c55118SMichael Lange MPI_Comm comm;
1910eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size;
191126c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx;
191226c55118SMichael Lange PetscSection rootSection;
191326c55118SMichael Lange PetscSF labelSF;
191426c55118SMichael Lange
191526c55118SMichael Lange PetscFunctionBegin;
19169566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label));
19179566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm));
191826c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF
191926c55118SMichael Lange and distribute point-wise stratum values to leaves. */
19209566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL));
19219566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection));
19229566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots));
192326c55118SMichael Lange if (label) {
192426c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) {
1925ad8374ffSToby Isaac const PetscInt *points;
1926ad8374ffSToby Isaac
19279566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points));
192848a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1));
19299566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points));
193026c55118SMichael Lange }
193126c55118SMichael Lange }
19329566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection));
193326c55118SMichael Lange /* Create a point-wise array of stratum values */
19349566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size));
19359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata));
19369566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx));
193726c55118SMichael Lange if (label) {
193826c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) {
1939ad8374ffSToby Isaac const PetscInt *points;
1940ad8374ffSToby Isaac
19419566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points));
194226c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) {
1943ad8374ffSToby Isaac const PetscInt p = points[l];
19449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset));
194526c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s];
194626c55118SMichael Lange }
19479566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points));
194826c55118SMichael Lange }
194926c55118SMichael Lange }
195026c55118SMichael Lange /* Build SF that maps label points to remote processes */
19519566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection));
19529566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection));
19539566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF));
19549566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets));
195526c55118SMichael Lange /* Send the strata for each point over the derived SF */
19569566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size));
19579566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata));
19589566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE));
19599566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE));
196026c55118SMichael Lange /* Clean up */
19619566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata));
19629566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx));
19639566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection));
19649566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF));
19653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
196626c55118SMichael Lange }
196726c55118SMichael Lange
196884f0b6dfSMatthew G. Knepley /*@
196920f4b53cSBarry Smith DMLabelDistribute - Create a new label pushed forward over the `PetscSF`
197084f0b6dfSMatthew G. Knepley
197120f4b53cSBarry Smith Collective
19725b5e7992SMatthew G. Knepley
197384f0b6dfSMatthew G. Knepley Input Parameters:
197420f4b53cSBarry Smith + label - the `DMLabel`
197584f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution
197684f0b6dfSMatthew G. Knepley
197784f0b6dfSMatthew G. Knepley Output Parameter:
197860225df5SJacob Faibussowitsch . labelNew - the new redistributed label
197984f0b6dfSMatthew G. Knepley
198084f0b6dfSMatthew G. Knepley Level: intermediate
198184f0b6dfSMatthew G. Knepley
198220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()`
198384f0b6dfSMatthew G. Knepley @*/
DMLabelDistribute(DMLabel label,PetscSF sf,DMLabel * labelNew)1984d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew)
1985d71ae5a4SJacob Faibussowitsch {
1986c58f1c22SToby Isaac MPI_Comm comm;
198726c55118SMichael Lange PetscSection leafSection;
198826c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum;
198926c55118SMichael Lange PetscInt *leafStrata, *strataIdx;
1990ad8374ffSToby Isaac PetscInt **points;
1991d67d17b1SMatthew G. Knepley const char *lname = NULL;
1992c58f1c22SToby Isaac char *name;
1993835f2295SStefano Zampini PetscMPIInt nameSize;
1994e8f14785SLisandro Dalcin PetscHSetI stratumHash;
1995c58f1c22SToby Isaac size_t len = 0;
199626c55118SMichael Lange PetscMPIInt rank;
1997c58f1c22SToby Isaac
1998c58f1c22SToby Isaac PetscFunctionBegin;
1999d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
2000f018e600SMatthew G. Knepley if (label) {
2001f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
20029f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
20039566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label));
2004f018e600SMatthew G. Knepley }
20059566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm));
20069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
2007c58f1c22SToby Isaac /* Bcast name */
2008dd400576SPatrick Sanan if (rank == 0) {
20099566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname));
20109566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len));
2011d67d17b1SMatthew G. Knepley }
2012835f2295SStefano Zampini PetscCall(PetscMPIIntCast(len, &nameSize));
2013835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(&nameSize, 1, MPI_INT, 0, comm));
20149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name));
20159566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1));
2016835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm));
20179566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew));
20189566063dSJacob Faibussowitsch PetscCall(PetscFree(name));
201977d236dfSMichael Lange /* Bcast defaultValue */
2020dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue;
20219566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm));
202226c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */
20239566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata));
20245cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/
20259566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash));
20269566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size));
20279566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p]));
20289566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata));
20299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS));
2030ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE;
20319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues));
20325cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */
20335cbdf6fcSMichael Lange offset = 0;
20349566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues));
20359566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues));
203648a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s));
20375cbdf6fcSMichael Lange for (p = 0; p < size; ++p) {
2038231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) {
20399371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) {
20409371c9d4SSatish Balay leafStrata[p] = s;
20419371c9d4SSatish Balay break;
20429371c9d4SSatish Balay }
20435cbdf6fcSMichael Lange }
20445cbdf6fcSMichael Lange }
2045c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */
20469566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes));
20479566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd));
2048c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) {
20499566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof));
20509566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset));
2051ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++;
2052c58f1c22SToby Isaac }
20539566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht));
20549f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->points));
20559f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &points));
2056c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) {
20579566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s]));
2058f4f49eeaSPierre Jolivet PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &points[s]));
2059c58f1c22SToby Isaac }
2060c58f1c22SToby Isaac /* Insert points into new strata */
20619566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx));
20629566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd));
2063c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) {
20649566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof));
20659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset));
2066c58f1c22SToby Isaac for (s = 0; s < dof; s++) {
2067c58f1c22SToby Isaac stratum = leafStrata[offset + s];
2068ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p;
2069c58f1c22SToby Isaac }
2070c58f1c22SToby Isaac }
2071ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) {
2072f4f49eeaSPierre Jolivet PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &points[s][0], PETSC_OWN_POINTER, &((*labelNew)->points[s])));
20739566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices"));
2074ad8374ffSToby Isaac }
20759566063dSJacob Faibussowitsch PetscCall(PetscFree(points));
20769566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash));
20779566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata));
20789566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx));
20799566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection));
20803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2081c58f1c22SToby Isaac }
2082c58f1c22SToby Isaac
20837937d9ceSMichael Lange /*@
20847937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots
20857937d9ceSMichael Lange
208620f4b53cSBarry Smith Collective
20875b5e7992SMatthew G. Knepley
20887937d9ceSMichael Lange Input Parameters:
208920f4b53cSBarry Smith + label - the `DMLabel`
209020f4b53cSBarry Smith - sf - the `PetscSF` communication map
20917937d9ceSMichael Lange
20922fe279fdSBarry Smith Output Parameter:
209320f4b53cSBarry Smith . labelNew - the new `DMLabel` with localised leaf values
20947937d9ceSMichael Lange
20957937d9ceSMichael Lange Level: developer
20967937d9ceSMichael Lange
209720f4b53cSBarry Smith Note:
209820f4b53cSBarry Smith This is the inverse operation to `DMLabelDistribute()`.
20997937d9ceSMichael Lange
210020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()`
21017937d9ceSMichael Lange @*/
DMLabelGather(DMLabel label,PetscSF sf,DMLabel * labelNew)2102d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew)
2103d71ae5a4SJacob Faibussowitsch {
21047937d9ceSMichael Lange MPI_Comm comm;
21057937d9ceSMichael Lange PetscSection rootSection;
21067937d9ceSMichael Lange PetscSF sfLabel;
21077937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints;
21087937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset;
21097937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal;
21107937d9ceSMichael Lange PetscInt *rootStrata;
2111d67d17b1SMatthew G. Knepley const char *lname;
21127937d9ceSMichael Lange char *name;
2113835f2295SStefano Zampini PetscMPIInt nameSize;
21147937d9ceSMichael Lange size_t len = 0;
21159852e123SBarry Smith PetscMPIInt rank, size;
21167937d9ceSMichael Lange
21177937d9ceSMichael Lange PetscFunctionBegin;
2118d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
2119d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
21209f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
21219566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm));
21229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
21239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size));
21247937d9ceSMichael Lange /* Bcast name */
2125dd400576SPatrick Sanan if (rank == 0) {
21269566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname));
21279566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len));
2128d67d17b1SMatthew G. Knepley }
2129835f2295SStefano Zampini PetscCall(PetscMPIIntCast(len, &nameSize));
2130835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(&nameSize, 1, MPI_INT, 0, comm));
21319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name));
21329566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1));
2133835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm));
21349566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew));
21359566063dSJacob Faibussowitsch PetscCall(PetscFree(name));
21367937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build
21377937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf
21387937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */
21399566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL));
21409566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints));
2141dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1;
21427937d9ceSMichael Lange for (p = 0; p < nleaves; p++) {
21438212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p;
21448212dd46SStefano Zampini
21458212dd46SStefano Zampini leafPoints[ilp].index = ilp;
21468212dd46SStefano Zampini leafPoints[ilp].rank = rank;
21477937d9ceSMichael Lange }
21489566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree));
21499566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree));
21507937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p];
21519566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints));
21526497c311SBarry Smith PetscCall(PetscSFGatherBegin(sf, MPIU_SF_NODE, leafPoints, rootPoints));
21536497c311SBarry Smith PetscCall(PetscSFGatherEnd(sf, MPIU_SF_NODE, leafPoints, rootPoints));
21549566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel));
21559566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER));
21567937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */
21579566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata));
21587937d9ceSMichael Lange /* Rebuild the point strata on the receiver */
21597937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) {
21607937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) {
21619566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof));
21629566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset));
21639566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s]));
21647937d9ceSMichael Lange }
21657937d9ceSMichael Lange idx += rootDegree[p];
21667937d9ceSMichael Lange }
21679566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints));
21689566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata));
21699566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection));
21709566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel));
21713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
21727937d9ceSMichael Lange }
21737937d9ceSMichael Lange
DMLabelPropagateInit_Internal(DMLabel label,PetscSF pointSF,PetscInt valArray[])2174d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[])
2175d71ae5a4SJacob Faibussowitsch {
2176d42890abSMatthew G. Knepley const PetscInt *degree;
2177d42890abSMatthew G. Knepley const PetscInt *points;
2178d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal;
2179d42890abSMatthew G. Knepley
2180d42890abSMatthew G. Knepley PetscFunctionBegin;
2181d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal));
2182d42890abSMatthew G. Knepley /* Add in leaves */
2183d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL));
2184d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) {
2185d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val));
2186d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val;
2187d42890abSMatthew G. Knepley }
2188d42890abSMatthew G. Knepley /* Add in shared roots */
2189d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree));
2190d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree));
2191d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) {
2192d42890abSMatthew G. Knepley if (degree[r]) {
2193d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val));
2194d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val;
2195d42890abSMatthew G. Knepley }
2196d42890abSMatthew G. Knepley }
21973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2198d42890abSMatthew G. Knepley }
2199d42890abSMatthew G. Knepley
DMLabelPropagateFini_Internal(DMLabel label,PetscSF pointSF,PetscInt valArray[],PetscErrorCode (* markPoint)(DMLabel,PetscInt,PetscInt,void *),PetscCtx ctx)22002a8381b2SBarry Smith static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), PetscCtx ctx)
2201d71ae5a4SJacob Faibussowitsch {
2202d42890abSMatthew G. Knepley const PetscInt *degree;
2203d42890abSMatthew G. Knepley const PetscInt *points;
2204d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal;
2205d42890abSMatthew G. Knepley
2206d42890abSMatthew G. Knepley PetscFunctionBegin;
2207d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal));
2208d42890abSMatthew G. Knepley /* Read out leaves */
2209d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL));
2210d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) {
2211d42890abSMatthew G. Knepley const PetscInt p = points[l];
2212d42890abSMatthew G. Knepley const PetscInt cval = valArray[p];
2213d42890abSMatthew G. Knepley
2214d42890abSMatthew G. Knepley if (cval != defVal) {
2215d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val));
2216d42890abSMatthew G. Knepley if (val == defVal) {
2217d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval));
221848a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx));
2219d42890abSMatthew G. Knepley }
2220d42890abSMatthew G. Knepley }
2221d42890abSMatthew G. Knepley }
2222d42890abSMatthew G. Knepley /* Read out shared roots */
2223d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree));
2224d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree));
2225d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) {
2226d42890abSMatthew G. Knepley if (degree[r]) {
2227d42890abSMatthew G. Knepley const PetscInt cval = valArray[r];
2228d42890abSMatthew G. Knepley
2229d42890abSMatthew G. Knepley if (cval != defVal) {
2230d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val));
2231d42890abSMatthew G. Knepley if (val == defVal) {
2232d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval));
223348a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx));
2234d42890abSMatthew G. Knepley }
2235d42890abSMatthew G. Knepley }
2236d42890abSMatthew G. Knepley }
2237d42890abSMatthew G. Knepley }
22383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2239d42890abSMatthew G. Knepley }
2240d42890abSMatthew G. Knepley
2241d42890abSMatthew G. Knepley /*@
2242d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation
2243d42890abSMatthew G. Knepley
224420f4b53cSBarry Smith Collective
2245d42890abSMatthew G. Knepley
2246d42890abSMatthew G. Knepley Input Parameters:
224720f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes
224820f4b53cSBarry Smith - sf - The `PetscSF` describing parallel layout of the label points
2249d42890abSMatthew G. Knepley
2250d42890abSMatthew G. Knepley Level: intermediate
2251d42890abSMatthew G. Knepley
225220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateEnd()`, `DMLabelPropagatePush()`
2253d42890abSMatthew G. Knepley @*/
DMLabelPropagateBegin(DMLabel label,PetscSF sf)2254d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf)
2255d71ae5a4SJacob Faibussowitsch {
2256d42890abSMatthew G. Knepley PetscInt Nr, r, defVal;
2257d42890abSMatthew G. Knepley PetscMPIInt size;
2258d42890abSMatthew G. Knepley
2259d42890abSMatthew G. Knepley PetscFunctionBegin;
22609f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
2261d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size));
2262d42890abSMatthew G. Knepley if (size > 1) {
2263d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal));
2264d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL));
2265d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray));
2266d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal;
2267d42890abSMatthew G. Knepley }
22683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2269d42890abSMatthew G. Knepley }
2270d42890abSMatthew G. Knepley
2271d42890abSMatthew G. Knepley /*@
2272d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation
2273d42890abSMatthew G. Knepley
227420f4b53cSBarry Smith Collective
2275d42890abSMatthew G. Knepley
2276d42890abSMatthew G. Knepley Input Parameters:
227720f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes
227860225df5SJacob Faibussowitsch - pointSF - The `PetscSF` describing parallel layout of the label points
2279d42890abSMatthew G. Knepley
2280d42890abSMatthew G. Knepley Level: intermediate
2281d42890abSMatthew G. Knepley
228220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagatePush()`
2283d42890abSMatthew G. Knepley @*/
DMLabelPropagateEnd(DMLabel label,PetscSF pointSF)2284d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF)
2285d71ae5a4SJacob Faibussowitsch {
2286d42890abSMatthew G. Knepley PetscFunctionBegin;
22879f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
2288d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray));
2289d42890abSMatthew G. Knepley label->propArray = NULL;
22903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2291d42890abSMatthew G. Knepley }
2292d42890abSMatthew G. Knepley
2293d42890abSMatthew G. Knepley /*@C
2294d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation
2295d42890abSMatthew G. Knepley
229620f4b53cSBarry Smith Collective
2297d42890abSMatthew G. Knepley
2298d42890abSMatthew G. Knepley Input Parameters:
229920f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes
2300a4e35b19SJacob Faibussowitsch . pointSF - The `PetscSF` describing parallel layout of the label points
230120f4b53cSBarry Smith . markPoint - An optional callback that is called when a point is marked, or `NULL`
230220f4b53cSBarry Smith - ctx - An optional user context for the callback, or `NULL`
2303d42890abSMatthew G. Knepley
230420f4b53cSBarry Smith Calling sequence of `markPoint`:
230520f4b53cSBarry Smith + label - The `DMLabel`
2306d42890abSMatthew G. Knepley . p - The point being marked
2307a4e35b19SJacob Faibussowitsch . val - The label value for `p`
2308d42890abSMatthew G. Knepley - ctx - An optional user context
2309d42890abSMatthew G. Knepley
2310d42890abSMatthew G. Knepley Level: intermediate
2311d42890abSMatthew G. Knepley
231220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()`
2313d42890abSMatthew G. Knepley @*/
DMLabelPropagatePush(DMLabel label,PetscSF pointSF,PetscErrorCode (* markPoint)(DMLabel label,PetscInt p,PetscInt val,PetscCtx ctx),PetscCtx ctx)23142a8381b2SBarry Smith PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel label, PetscInt p, PetscInt val, PetscCtx ctx), PetscCtx ctx)
2315d71ae5a4SJacob Faibussowitsch {
2316c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr;
2317d42890abSMatthew G. Knepley PetscMPIInt size;
2318d42890abSMatthew G. Knepley
2319d42890abSMatthew G. Knepley PetscFunctionBegin;
23209f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered");
2321d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size));
2322c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL));
2323c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) {
2324d42890abSMatthew G. Knepley /* Communicate marked edges
2325d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the
2326d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent.
2327d42890abSMatthew G. Knepley
2328d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF
2329d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has
2330d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway.
2331d42890abSMatthew G. Knepley
2332d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new
2333d42890abSMatthew G. Knepley values will have 1+0=1 and old values will have 1+1=2. Loop over these, resetting the values to 1, and adding any new
2334d42890abSMatthew G. Knepley edge to the queue.
2335d42890abSMatthew G. Knepley */
2336d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray));
2337d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX));
2338d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX));
2339d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE));
2340d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE));
2341d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx));
2342d42890abSMatthew G. Knepley }
23433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2344d42890abSMatthew G. Knepley }
2345d42890abSMatthew G. Knepley
234684f0b6dfSMatthew G. Knepley /*@
234720f4b53cSBarry Smith DMLabelConvertToSection - Make a `PetscSection`/`IS` pair that encodes the label
234884f0b6dfSMatthew G. Knepley
234920f4b53cSBarry Smith Not Collective
23505b5e7992SMatthew G. Knepley
235184f0b6dfSMatthew G. Knepley Input Parameter:
235220f4b53cSBarry Smith . label - the `DMLabel`
235384f0b6dfSMatthew G. Knepley
235484f0b6dfSMatthew G. Knepley Output Parameters:
235584f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum
235620f4b53cSBarry Smith - is - An `IS` containing all the label points
235784f0b6dfSMatthew G. Knepley
235884f0b6dfSMatthew G. Knepley Level: developer
235984f0b6dfSMatthew G. Knepley
236020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()`
236184f0b6dfSMatthew G. Knepley @*/
DMLabelConvertToSection(DMLabel label,PetscSection * section,IS * is)2362d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is)
2363d71ae5a4SJacob Faibussowitsch {
2364c58f1c22SToby Isaac IS vIS;
2365c58f1c22SToby Isaac const PetscInt *values;
2366c58f1c22SToby Isaac PetscInt *points;
2367c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N;
2368c58f1c22SToby Isaac
2369c58f1c22SToby Isaac PetscFunctionBegin;
2370d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
23719566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV));
23729566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS));
23739566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values));
23749371c9d4SSatish Balay if (nV) {
23759371c9d4SSatish Balay vS = values[0];
23769371c9d4SSatish Balay vE = values[0] + 1;
23779371c9d4SSatish Balay }
2378c58f1c22SToby Isaac for (v = 1; v < nV; ++v) {
2379c58f1c22SToby Isaac vS = PetscMin(vS, values[v]);
2380c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1);
2381c58f1c22SToby Isaac }
23829566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section));
23839566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE));
2384c58f1c22SToby Isaac for (v = 0; v < nV; ++v) {
2385c58f1c22SToby Isaac PetscInt n;
2386c58f1c22SToby Isaac
23879566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n));
23889566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n));
2389c58f1c22SToby Isaac }
23909566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section));
23919566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N));
23929566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points));
2393c58f1c22SToby Isaac for (v = 0; v < nV; ++v) {
2394c58f1c22SToby Isaac IS is;
2395c58f1c22SToby Isaac const PetscInt *spoints;
2396c58f1c22SToby Isaac PetscInt dof, off, p;
2397c58f1c22SToby Isaac
23989566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof));
23999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off));
24009566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is));
24019566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints));
2402c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p];
24039566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints));
24049566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is));
2405c58f1c22SToby Isaac }
24069566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values));
24079566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS));
24089566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is));
24093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2410c58f1c22SToby Isaac }
2411c58f1c22SToby Isaac
24129f6c5813SMatthew G. Knepley /*@C
24139f6c5813SMatthew G. Knepley DMLabelRegister - Adds a new label component implementation
24149f6c5813SMatthew G. Knepley
24159f6c5813SMatthew G. Knepley Not Collective
24169f6c5813SMatthew G. Knepley
24179f6c5813SMatthew G. Knepley Input Parameters:
24189f6c5813SMatthew G. Knepley + name - The name of a new user-defined creation routine
24199f6c5813SMatthew G. Knepley - create_func - The creation routine itself
24209f6c5813SMatthew G. Knepley
24219f6c5813SMatthew G. Knepley Notes:
24229f6c5813SMatthew G. Knepley `DMLabelRegister()` may be called multiple times to add several user-defined labels
24239f6c5813SMatthew G. Knepley
242460225df5SJacob Faibussowitsch Example Usage:
24259f6c5813SMatthew G. Knepley .vb
24269f6c5813SMatthew G. Knepley DMLabelRegister("my_label", MyLabelCreate);
24279f6c5813SMatthew G. Knepley .ve
24289f6c5813SMatthew G. Knepley
24299f6c5813SMatthew G. Knepley Then, your label type can be chosen with the procedural interface via
24309f6c5813SMatthew G. Knepley .vb
24319f6c5813SMatthew G. Knepley DMLabelCreate(MPI_Comm, DMLabel *);
24329f6c5813SMatthew G. Knepley DMLabelSetType(DMLabel, "my_label");
24339f6c5813SMatthew G. Knepley .ve
24349f6c5813SMatthew G. Knepley or at runtime via the option
24359f6c5813SMatthew G. Knepley .vb
24369f6c5813SMatthew G. Knepley -dm_label_type my_label
24379f6c5813SMatthew G. Knepley .ve
24389f6c5813SMatthew G. Knepley
24399f6c5813SMatthew G. Knepley Level: advanced
24409f6c5813SMatthew G. Knepley
244160225df5SJacob Faibussowitsch .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelRegisterAll()`, `DMLabelRegisterDestroy()`
24429f6c5813SMatthew G. Knepley @*/
DMLabelRegister(const char name[],PetscErrorCode (* create_func)(DMLabel))24439f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegister(const char name[], PetscErrorCode (*create_func)(DMLabel))
24449f6c5813SMatthew G. Knepley {
24459f6c5813SMatthew G. Knepley PetscFunctionBegin;
24469f6c5813SMatthew G. Knepley PetscCall(DMInitializePackage());
24479f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListAdd(&DMLabelList, name, create_func));
24483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
24499f6c5813SMatthew G. Knepley }
24509f6c5813SMatthew G. Knepley
24519f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel);
24529f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel);
24539f6c5813SMatthew G. Knepley
24549f6c5813SMatthew G. Knepley /*@C
24559f6c5813SMatthew G. Knepley DMLabelRegisterAll - Registers all of the `DMLabel` implementations in the `DM` package.
24569f6c5813SMatthew G. Knepley
24579f6c5813SMatthew G. Knepley Not Collective
24589f6c5813SMatthew G. Knepley
24599f6c5813SMatthew G. Knepley Level: advanced
24609f6c5813SMatthew G. Knepley
246120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMRegisterAll()`, `DMLabelRegisterDestroy()`
24629f6c5813SMatthew G. Knepley @*/
DMLabelRegisterAll(void)24639f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterAll(void)
24649f6c5813SMatthew G. Knepley {
24659f6c5813SMatthew G. Knepley PetscFunctionBegin;
24663ba16761SJacob Faibussowitsch if (DMLabelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
24679f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_TRUE;
24689f6c5813SMatthew G. Knepley
24699f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELCONCRETE, DMLabelCreate_Concrete));
24709f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELEPHEMERAL, DMLabelCreate_Ephemeral));
24713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
24729f6c5813SMatthew G. Knepley }
24739f6c5813SMatthew G. Knepley
24749f6c5813SMatthew G. Knepley /*@C
24759f6c5813SMatthew G. Knepley DMLabelRegisterDestroy - This function destroys the `DMLabel` registry. It is called from `PetscFinalize()`.
24769f6c5813SMatthew G. Knepley
24779f6c5813SMatthew G. Knepley Level: developer
24789f6c5813SMatthew G. Knepley
247920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscInitialize()`
24809f6c5813SMatthew G. Knepley @*/
DMLabelRegisterDestroy(void)24819f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterDestroy(void)
24829f6c5813SMatthew G. Knepley {
24839f6c5813SMatthew G. Knepley PetscFunctionBegin;
24849f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMLabelList));
24859f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_FALSE;
24863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
24879f6c5813SMatthew G. Knepley }
24889f6c5813SMatthew G. Knepley
2489cc4c1da9SBarry Smith /*@
24909f6c5813SMatthew G. Knepley DMLabelSetType - Sets the particular implementation for a label.
24919f6c5813SMatthew G. Knepley
249220f4b53cSBarry Smith Collective
24939f6c5813SMatthew G. Knepley
24949f6c5813SMatthew G. Knepley Input Parameters:
24959f6c5813SMatthew G. Knepley + label - The label
24969f6c5813SMatthew G. Knepley - method - The name of the label type
24979f6c5813SMatthew G. Knepley
24989f6c5813SMatthew G. Knepley Options Database Key:
249920f4b53cSBarry Smith . -dm_label_type <type> - Sets the label type; use -help for a list of available types or see `DMLabelType`
25009f6c5813SMatthew G. Knepley
25019f6c5813SMatthew G. Knepley Level: intermediate
25029f6c5813SMatthew G. Knepley
250320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetType()`, `DMLabelCreate()`
25049f6c5813SMatthew G. Knepley @*/
DMLabelSetType(DMLabel label,DMLabelType method)25059f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetType(DMLabel label, DMLabelType method)
25069f6c5813SMatthew G. Knepley {
25079f6c5813SMatthew G. Knepley PetscErrorCode (*r)(DMLabel);
25089f6c5813SMatthew G. Knepley PetscBool match;
25099f6c5813SMatthew G. Knepley
25109f6c5813SMatthew G. Knepley PetscFunctionBegin;
25119f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
25129f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)label, method, &match));
25133ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS);
25149f6c5813SMatthew G. Knepley
25159f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll());
25169f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListFind(DMLabelList, method, &r));
25179f6c5813SMatthew G. Knepley PetscCheck(r, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMLabel type: %s", method);
25189f6c5813SMatthew G. Knepley
25199f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, destroy);
25209f6c5813SMatthew G. Knepley PetscCall(PetscMemzero(label->ops, sizeof(*label->ops)));
25219f6c5813SMatthew G. Knepley PetscCall(PetscObjectChangeTypeName((PetscObject)label, method));
25229f6c5813SMatthew G. Knepley PetscCall((*r)(label));
25233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
25249f6c5813SMatthew G. Knepley }
25259f6c5813SMatthew G. Knepley
2526cc4c1da9SBarry Smith /*@
25279f6c5813SMatthew G. Knepley DMLabelGetType - Gets the type name (as a string) from the label.
25289f6c5813SMatthew G. Knepley
25299f6c5813SMatthew G. Knepley Not Collective
25309f6c5813SMatthew G. Knepley
25319f6c5813SMatthew G. Knepley Input Parameter:
253220f4b53cSBarry Smith . label - The `DMLabel`
25339f6c5813SMatthew G. Knepley
25349f6c5813SMatthew G. Knepley Output Parameter:
253520f4b53cSBarry Smith . type - The `DMLabel` type name
25369f6c5813SMatthew G. Knepley
25379f6c5813SMatthew G. Knepley Level: intermediate
25389f6c5813SMatthew G. Knepley
253920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetType()`, `DMLabelCreate()`
25409f6c5813SMatthew G. Knepley @*/
DMLabelGetType(DMLabel label,DMLabelType * type)25419f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetType(DMLabel label, DMLabelType *type)
25429f6c5813SMatthew G. Knepley {
25439f6c5813SMatthew G. Knepley PetscFunctionBegin;
25449f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
25454f572ea9SToby Isaac PetscAssertPointer(type, 2);
25469f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll());
25479f6c5813SMatthew G. Knepley *type = ((PetscObject)label)->type_name;
25483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
25499f6c5813SMatthew G. Knepley }
25509f6c5813SMatthew G. Knepley
DMLabelInitialize_Concrete(DMLabel label)25519f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Concrete(DMLabel label)
25529f6c5813SMatthew G. Knepley {
25539f6c5813SMatthew G. Knepley PetscFunctionBegin;
25549f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Concrete;
25559f6c5813SMatthew G. Knepley label->ops->setup = NULL;
25569f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Concrete;
25579f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Concrete;
25583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
25599f6c5813SMatthew G. Knepley }
25609f6c5813SMatthew G. Knepley
DMLabelCreate_Concrete(DMLabel label)25619f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel label)
25629f6c5813SMatthew G. Knepley {
25639f6c5813SMatthew G. Knepley PetscFunctionBegin;
25649f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
25659f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Concrete(label));
25663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
25679f6c5813SMatthew G. Knepley }
25689f6c5813SMatthew G. Knepley
256984f0b6dfSMatthew G. Knepley /*@
2570c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using
257120f4b53cSBarry Smith the local section and an `PetscSF` describing the section point overlap.
2572c58f1c22SToby Isaac
257320f4b53cSBarry Smith Collective
25745b5e7992SMatthew G. Knepley
2575c58f1c22SToby Isaac Input Parameters:
257620f4b53cSBarry Smith + s - The `PetscSection` for the local field layout
257720f4b53cSBarry Smith . sf - The `PetscSF` describing parallel layout of the section points
257820f4b53cSBarry Smith . includeConstraints - By default this is `PETSC_FALSE`, meaning that the global field vector will not possess constrained dofs
2579c58f1c22SToby Isaac . label - The label specifying the points
2580c58f1c22SToby Isaac - labelValue - The label stratum specifying the points
2581c58f1c22SToby Isaac
2582c58f1c22SToby Isaac Output Parameter:
258320f4b53cSBarry Smith . gsection - The `PetscSection` for the global field layout
2584c58f1c22SToby Isaac
2585c58f1c22SToby Isaac Level: developer
2586c58f1c22SToby Isaac
258720f4b53cSBarry Smith Note:
258820f4b53cSBarry Smith This gives negative sizes and offsets to points not owned by this process
258920f4b53cSBarry Smith
259020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionCreate()`
2591c58f1c22SToby Isaac @*/
PetscSectionCreateGlobalSectionLabel(PetscSection s,PetscSF sf,PetscBool includeConstraints,DMLabel label,PetscInt labelValue,PetscSection * gsection)2592d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection)
2593d71ae5a4SJacob Faibussowitsch {
2594c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL;
2595c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots;
2596c58f1c22SToby Isaac
2597c58f1c22SToby Isaac PetscFunctionBegin;
2598d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2599d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
2600d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
26019566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection));
26029566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd));
26039566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd));
26049566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL));
2605c58f1c22SToby Isaac if (nroots >= 0) {
260663a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart);
26079566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg));
2608c58f1c22SToby Isaac if (nroots > pEnd - pStart) {
26099566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff));
2610c58f1c22SToby Isaac } else {
2611c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart];
2612c58f1c22SToby Isaac }
2613c58f1c22SToby Isaac }
2614c58f1c22SToby Isaac /* Mark ghost points with negative dof */
2615c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {
2616c58f1c22SToby Isaac PetscInt value;
2617c58f1c22SToby Isaac
26189566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value));
2619c58f1c22SToby Isaac if (value != labelValue) continue;
26209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof));
26219566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof));
26229566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof));
26239566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof));
2624c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1);
2625c58f1c22SToby Isaac }
26269566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection));
2627c58f1c22SToby Isaac if (nroots >= 0) {
26289566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
26299566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
2630c58f1c22SToby Isaac if (nroots > pEnd - pStart) {
26319371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) {
26329371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p];
26339371c9d4SSatish Balay }
2634c58f1c22SToby Isaac }
2635c58f1c22SToby Isaac }
263635cb6cd3SPierre Jolivet /* Calculate new sizes, get process offset, and calculate point offsets */
2637c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) {
2638c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0;
2639c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off;
2640c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0;
2641c58f1c22SToby Isaac }
26429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s)));
2643c58f1c22SToby Isaac globalOff -= off;
2644c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) {
2645c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff;
2646c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1);
2647c58f1c22SToby Isaac }
2648c58f1c22SToby Isaac /* Put in negative offsets for ghost points */
2649c58f1c22SToby Isaac if (nroots >= 0) {
26509566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
26519566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE));
2652c58f1c22SToby Isaac if (nroots > pEnd - pStart) {
26539371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) {
26549371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p];
26559371c9d4SSatish Balay }
2656c58f1c22SToby Isaac }
2657c58f1c22SToby Isaac }
26589566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff));
26599566063dSJacob Faibussowitsch PetscCall(PetscFree(neg));
26603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2661c58f1c22SToby Isaac }
2662c58f1c22SToby Isaac
26639371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label {
26645fdea053SToby Isaac DMLabel label;
26655fdea053SToby Isaac PetscCopyMode *modes;
26665fdea053SToby Isaac PetscInt *sizes;
26675fdea053SToby Isaac const PetscInt ***perms;
26685fdea053SToby Isaac const PetscScalar ***rots;
26695fdea053SToby Isaac PetscInt (*minMaxOrients)[2];
26705fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */
26715fdea053SToby Isaac } PetscSectionSym_Label;
26725fdea053SToby Isaac
PetscSectionSymLabelReset(PetscSectionSym sym)2673d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym)
2674d71ae5a4SJacob Faibussowitsch {
26755fdea053SToby Isaac PetscInt i, j;
26765fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data;
26775fdea053SToby Isaac
26785fdea053SToby Isaac PetscFunctionBegin;
26795fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) {
26805fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) {
26815fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) {
26829566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j]));
26839566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j]));
26845fdea053SToby Isaac }
26855fdea053SToby Isaac if (sl->perms[i]) {
26865fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]];
26875fdea053SToby Isaac
26889566063dSJacob Faibussowitsch PetscCall(PetscFree(perms));
26895fdea053SToby Isaac }
26905fdea053SToby Isaac if (sl->rots[i]) {
26915fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]];
26925fdea053SToby Isaac
26939566063dSJacob Faibussowitsch PetscCall(PetscFree(rots));
26945fdea053SToby Isaac }
26955fdea053SToby Isaac }
26965fdea053SToby Isaac }
26979566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients));
26989566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label));
26995fdea053SToby Isaac sl->numStrata = 0;
27003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
27015fdea053SToby Isaac }
27025fdea053SToby Isaac
PetscSectionSymDestroy_Label(PetscSectionSym sym)2703d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym)
2704d71ae5a4SJacob Faibussowitsch {
27055fdea053SToby Isaac PetscFunctionBegin;
27069566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym));
27079566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data));
27083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
27095fdea053SToby Isaac }
27105fdea053SToby Isaac
PetscSectionSymView_Label(PetscSectionSym sym,PetscViewer viewer)2711d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer)
2712d71ae5a4SJacob Faibussowitsch {
27135fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data;
27145fdea053SToby Isaac PetscBool isAscii;
27155fdea053SToby Isaac DMLabel label = sl->label;
2716d67d17b1SMatthew G. Knepley const char *name;
27175fdea053SToby Isaac
27185fdea053SToby Isaac PetscFunctionBegin;
27199566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii));
27205fdea053SToby Isaac if (isAscii) {
27215fdea053SToby Isaac PetscInt i, j, k;
27225fdea053SToby Isaac PetscViewerFormat format;
27235fdea053SToby Isaac
27249566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format));
27255fdea053SToby Isaac if (label) {
27269566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format));
27275fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
27289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
27299566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer));
27309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
27315fdea053SToby Isaac } else {
27329566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name));
27339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name));
27345fdea053SToby Isaac }
27355fdea053SToby Isaac } else {
27369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n"));
27375fdea053SToby Isaac }
27389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
27395fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) {
27405fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue;
27415fdea053SToby Isaac
27425fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) {
274363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i]));
27445fdea053SToby Isaac } else {
274563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i]));
27469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
274763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1]));
27485fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
27499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
27505fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) {
27515fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) {
275263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j));
27535fdea053SToby Isaac } else {
27545fdea053SToby Isaac PetscInt tab;
27555fdea053SToby Isaac
275663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j));
27579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
27589566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab));
27595fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) {
27609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:"));
27619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0));
276263a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k]));
27639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
27649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab));
27655fdea053SToby Isaac }
27665fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) {
27679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: "));
27689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0));
27695fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX)
277063a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g+i*%+g", (double)PetscRealPart(sl->rots[i][j][k]), (double)PetscImaginaryPart(sl->rots[i][j][k])));
27715fdea053SToby Isaac #else
277263a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k]));
27735fdea053SToby Isaac #endif
27749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
27759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab));
27765fdea053SToby Isaac }
27779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
27785fdea053SToby Isaac }
27795fdea053SToby Isaac }
27809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
27815fdea053SToby Isaac }
27829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
27835fdea053SToby Isaac }
27845fdea053SToby Isaac }
27859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
27865fdea053SToby Isaac }
27873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
27885fdea053SToby Isaac }
27895fdea053SToby Isaac
27905fdea053SToby Isaac /*@
27915fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries
27925fdea053SToby Isaac
279320f4b53cSBarry Smith Logically
27945fdea053SToby Isaac
279560225df5SJacob Faibussowitsch Input Parameters:
27965fdea053SToby Isaac + sym - the section symmetries
279720f4b53cSBarry Smith - label - the `DMLabel` describing the types of points
27985fdea053SToby Isaac
27995fdea053SToby Isaac Level: developer:
28005fdea053SToby Isaac
280120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()`
28025fdea053SToby Isaac @*/
PetscSectionSymLabelSetLabel(PetscSectionSym sym,DMLabel label)2803d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label)
2804d71ae5a4SJacob Faibussowitsch {
28055fdea053SToby Isaac PetscSectionSym_Label *sl;
28065fdea053SToby Isaac
28075fdea053SToby Isaac PetscFunctionBegin;
28085fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
28095fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data;
28109566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym));
28115fdea053SToby Isaac if (label) {
28125fdea053SToby Isaac sl->label = label;
28139566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label));
28149566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata));
28159566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(sl->numStrata + 1, &sl->modes, sl->numStrata + 1, &sl->sizes, sl->numStrata + 1, &sl->perms, sl->numStrata + 1, &sl->rots, sl->numStrata + 1, &sl->minMaxOrients));
28169566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode)));
28179566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt)));
28189566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **)));
28199566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **)));
28209566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2])));
28215fdea053SToby Isaac }
28223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
28235fdea053SToby Isaac }
28245fdea053SToby Isaac
28255fdea053SToby Isaac /*@C
2826b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum
2827b004864fSMatthew G. Knepley
282820f4b53cSBarry Smith Logically Collective
2829b004864fSMatthew G. Knepley
2830b004864fSMatthew G. Knepley Input Parameters:
2831b004864fSMatthew G. Knepley + sym - the section symmetries
2832b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for
2833b004864fSMatthew G. Knepley
2834b004864fSMatthew G. Knepley Output Parameters:
283520f4b53cSBarry Smith + size - the number of dofs for points in the `stratum` of the label
283620f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum`
283720f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a ppoint in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`))
283820f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity
283920f4b53cSBarry Smith - rots - `NULL` if there are no rotations, or (`maxOrient` - `minOrient`) sets of rotations, one for each orientation. A `NULL` set of orientations is the identity
2840b004864fSMatthew G. Knepley
2841b004864fSMatthew G. Knepley Level: developer
2842b004864fSMatthew G. Knepley
284320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()`
2844b004864fSMatthew G. Knepley @*/
PetscSectionSymLabelGetStratum(PetscSectionSym sym,PetscInt stratum,PetscInt * size,PetscInt * minOrient,PetscInt * maxOrient,const PetscInt *** perms,const PetscScalar *** rots)2845d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots)
2846d71ae5a4SJacob Faibussowitsch {
2847b004864fSMatthew G. Knepley PetscSectionSym_Label *sl;
2848b004864fSMatthew G. Knepley const char *name;
2849b004864fSMatthew G. Knepley PetscInt i;
2850b004864fSMatthew G. Knepley
2851b004864fSMatthew G. Knepley PetscFunctionBegin;
2852b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
2853b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data;
2854b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet");
2855b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) {
2856b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue;
2857b004864fSMatthew G. Knepley
2858b004864fSMatthew G. Knepley if (stratum == value) break;
2859b004864fSMatthew G. Knepley }
28609566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name));
2861b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name);
28629371c9d4SSatish Balay if (size) {
28634f572ea9SToby Isaac PetscAssertPointer(size, 3);
28649371c9d4SSatish Balay *size = sl->sizes[i];
28659371c9d4SSatish Balay }
28669371c9d4SSatish Balay if (minOrient) {
28674f572ea9SToby Isaac PetscAssertPointer(minOrient, 4);
28689371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0];
28699371c9d4SSatish Balay }
28709371c9d4SSatish Balay if (maxOrient) {
28714f572ea9SToby Isaac PetscAssertPointer(maxOrient, 5);
28729371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1];
28739371c9d4SSatish Balay }
28749371c9d4SSatish Balay if (perms) {
28754f572ea9SToby Isaac PetscAssertPointer(perms, 6);
28768e3a54c0SPierre Jolivet *perms = PetscSafePointerPlusOffset(sl->perms[i], sl->minMaxOrients[i][0]);
28779371c9d4SSatish Balay }
28789371c9d4SSatish Balay if (rots) {
28794f572ea9SToby Isaac PetscAssertPointer(rots, 7);
28808e3a54c0SPierre Jolivet *rots = PetscSafePointerPlusOffset(sl->rots[i], sl->minMaxOrients[i][0]);
28819371c9d4SSatish Balay }
28823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2883b004864fSMatthew G. Knepley }
2884b004864fSMatthew G. Knepley
2885b004864fSMatthew G. Knepley /*@C
28865fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum
28875fdea053SToby Isaac
288820f4b53cSBarry Smith Logically
28895fdea053SToby Isaac
28905fdea053SToby Isaac Input Parameters:
28915b5e7992SMatthew G. Knepley + sym - the section symmetries
28925fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for
289320f4b53cSBarry Smith . size - the number of dofs for points in the `stratum` of the label
289420f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum`
289520f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a point in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`))
289620f4b53cSBarry Smith . mode - how `sym` should copy the `perms` and `rots` arrays
289720f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity
289820f4b53cSBarry Smith - rots - `NULL` if there are no rotations, or (`maxOrient` - `minOrient`) sets of rotations, one for each orientation. A `NULL` set of orientations is the identity
28995fdea053SToby Isaac
29005fdea053SToby Isaac Level: developer
29015fdea053SToby Isaac
290220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()`
29035fdea053SToby Isaac @*/
PetscSectionSymLabelSetStratum(PetscSectionSym sym,PetscInt stratum,PetscInt size,PetscInt minOrient,PetscInt maxOrient,PetscCopyMode mode,const PetscInt ** perms,const PetscScalar ** rots)2904d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots)
2905d71ae5a4SJacob Faibussowitsch {
29065fdea053SToby Isaac PetscSectionSym_Label *sl;
2907d67d17b1SMatthew G. Knepley const char *name;
2908d67d17b1SMatthew G. Knepley PetscInt i, j, k;
29095fdea053SToby Isaac
29105fdea053SToby Isaac PetscFunctionBegin;
29115fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1);
29125fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data;
2913b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet");
29145fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) {
29155fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue;
29165fdea053SToby Isaac
29175fdea053SToby Isaac if (stratum == value) break;
29185fdea053SToby Isaac }
29199566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name));
292063a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name);
29215fdea053SToby Isaac sl->sizes[i] = size;
29225fdea053SToby Isaac sl->modes[i] = mode;
29235fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient;
29245fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient;
29255fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) {
29265fdea053SToby Isaac if (perms) {
29275fdea053SToby Isaac PetscInt **ownPerms;
29285fdea053SToby Isaac
29299566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms));
29305fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) {
29315fdea053SToby Isaac if (perms[j]) {
29329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j]));
2933ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k];
29345fdea053SToby Isaac }
29355fdea053SToby Isaac }
29365fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient];
29375fdea053SToby Isaac }
29385fdea053SToby Isaac if (rots) {
29395fdea053SToby Isaac PetscScalar **ownRots;
29405fdea053SToby Isaac
29419566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots));
29425fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) {
29435fdea053SToby Isaac if (rots[j]) {
29449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j]));
2945ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k];
29465fdea053SToby Isaac }
29475fdea053SToby Isaac }
29485fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient];
29495fdea053SToby Isaac }
29505fdea053SToby Isaac } else {
29518e3a54c0SPierre Jolivet sl->perms[i] = PetscSafePointerPlusOffset(perms, -minOrient);
29528e3a54c0SPierre Jolivet sl->rots[i] = PetscSafePointerPlusOffset(rots, -minOrient);
29535fdea053SToby Isaac }
29543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
29555fdea053SToby Isaac }
29565fdea053SToby Isaac
PetscSectionSymGetPoints_Label(PetscSectionSym sym,PetscSection section,PetscInt numPoints,const PetscInt * points,const PetscInt ** perms,const PetscScalar ** rots)2957d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots)
2958d71ae5a4SJacob Faibussowitsch {
29595fdea053SToby Isaac PetscInt i, j, numStrata;
29605fdea053SToby Isaac PetscSectionSym_Label *sl;
29615fdea053SToby Isaac DMLabel label;
29625fdea053SToby Isaac
29635fdea053SToby Isaac PetscFunctionBegin;
29645fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data;
29655fdea053SToby Isaac numStrata = sl->numStrata;
29665fdea053SToby Isaac label = sl->label;
29675fdea053SToby Isaac for (i = 0; i < numPoints; i++) {
29685fdea053SToby Isaac PetscInt point = points[2 * i];
29695fdea053SToby Isaac PetscInt ornt = points[2 * i + 1];
29705fdea053SToby Isaac
29715fdea053SToby Isaac for (j = 0; j < numStrata; j++) {
29725fdea053SToby Isaac if (label->validIS[j]) {
29735fdea053SToby Isaac PetscInt k;
29745fdea053SToby Isaac
29752b4d18a0SMatthew G. Knepley PetscCall(ISLocate(label->points[j], point, &k));
29765fdea053SToby Isaac if (k >= 0) break;
29775fdea053SToby Isaac } else {
29785fdea053SToby Isaac PetscBool has;
29795fdea053SToby Isaac
29809566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has));
29815fdea053SToby Isaac if (has) break;
29825fdea053SToby Isaac }
29835fdea053SToby Isaac }
29849371c9d4SSatish Balay PetscCheck(!(sl->minMaxOrients[j][1] > sl->minMaxOrients[j][0]) || !(ornt < sl->minMaxOrients[j][0] || ornt >= sl->minMaxOrients[j][1]), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "point %" PetscInt_FMT " orientation %" PetscInt_FMT " not in range [%" PetscInt_FMT ", %" PetscInt_FMT ") for stratum %" PetscInt_FMT, point, ornt, sl->minMaxOrients[j][0], sl->minMaxOrients[j][1],
29859371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue);
2986ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;
2987ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL;
29885fdea053SToby Isaac }
29893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
29905fdea053SToby Isaac }
29915fdea053SToby Isaac
PetscSectionSymCopy_Label(PetscSectionSym sym,PetscSectionSym nsym)2992d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym)
2993d71ae5a4SJacob Faibussowitsch {
2994b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data;
2995b004864fSMatthew G. Knepley IS valIS;
2996b004864fSMatthew G. Knepley const PetscInt *values;
2997b004864fSMatthew G. Knepley PetscInt Nv, v;
2998b004864fSMatthew G. Knepley
2999b004864fSMatthew G. Knepley PetscFunctionBegin;
30009566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv));
30019566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS));
30029566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values));
3003b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) {
3004b004864fSMatthew G. Knepley const PetscInt val = values[v];
3005b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient;
3006b004864fSMatthew G. Knepley const PetscInt **perms;
3007b004864fSMatthew G. Knepley const PetscScalar **rots;
3008b004864fSMatthew G. Knepley
30099566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots));
30109566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots));
3011b004864fSMatthew G. Knepley }
30129566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS));
30133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3014b004864fSMatthew G. Knepley }
3015b004864fSMatthew G. Knepley
PetscSectionSymDistribute_Label(PetscSectionSym sym,PetscSF migrationSF,PetscSectionSym * dsym)3016d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym)
3017d71ae5a4SJacob Faibussowitsch {
3018b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data;
3019b004864fSMatthew G. Knepley DMLabel dlabel;
3020b004864fSMatthew G. Knepley
3021b004864fSMatthew G. Knepley PetscFunctionBegin;
30229566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel));
30239566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym));
30249566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel));
30259566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym));
30263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3027b004864fSMatthew G. Knepley }
3028b004864fSMatthew G. Knepley
PetscSectionSymCreate_Label(PetscSectionSym sym)3029d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym)
3030d71ae5a4SJacob Faibussowitsch {
30315fdea053SToby Isaac PetscSectionSym_Label *sl;
30325fdea053SToby Isaac
30335fdea053SToby Isaac PetscFunctionBegin;
30344dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl));
30355fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label;
3036b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label;
3037b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label;
30385fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label;
30395fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label;
30405fdea053SToby Isaac sym->data = (void *)sl;
30413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
30425fdea053SToby Isaac }
30435fdea053SToby Isaac
30445fdea053SToby Isaac /*@
30455fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label
30465fdea053SToby Isaac
30475fdea053SToby Isaac Collective
30485fdea053SToby Isaac
30495fdea053SToby Isaac Input Parameters:
30505fdea053SToby Isaac + comm - the MPI communicator for the new symmetry
30515fdea053SToby Isaac - label - the label defining the strata
30525fdea053SToby Isaac
30532fe279fdSBarry Smith Output Parameter:
30545fdea053SToby Isaac . sym - the section symmetries
30555fdea053SToby Isaac
30565fdea053SToby Isaac Level: developer
30575fdea053SToby Isaac
305820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()`
30595fdea053SToby Isaac @*/
PetscSectionSymCreateLabel(MPI_Comm comm,DMLabel label,PetscSectionSym * sym)3060d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym)
3061d71ae5a4SJacob Faibussowitsch {
30625fdea053SToby Isaac PetscFunctionBegin;
30639566063dSJacob Faibussowitsch PetscCall(DMInitializePackage());
30649566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym));
30659566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL));
30669566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label));
30673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
30685fdea053SToby Isaac }
3069