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 @*/ 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 @*/ 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 */ 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 } 1159566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)is, "indices")); 116277ea44aSLisandro Dalcin label->points[v] = is; 117ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 1189566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 120c58f1c22SToby Isaac } 121c58f1c22SToby Isaac 122c58f1c22SToby Isaac /* 123c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 124c58f1c22SToby Isaac 12520f4b53cSBarry Smith Not Collective 1265b5e7992SMatthew G. Knepley 127c58f1c22SToby Isaac Input parameter: 12820f4b53cSBarry Smith . label - The `DMLabel` 129c58f1c22SToby Isaac 130c58f1c22SToby Isaac Output parameter: 13120f4b53cSBarry Smith . label - The `DMLabel` with all strata in sorted list format 132c58f1c22SToby Isaac 133c58f1c22SToby Isaac Level: developer 134c58f1c22SToby Isaac 13520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()` 136c58f1c22SToby Isaac */ 137d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 138d71ae5a4SJacob Faibussowitsch { 139c58f1c22SToby Isaac PetscInt v; 140c58f1c22SToby Isaac 141c58f1c22SToby Isaac PetscFunctionBegin; 14248a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeValid_Private(label, v)); 1433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 144c58f1c22SToby Isaac } 145c58f1c22SToby Isaac 146c58f1c22SToby Isaac /* 147c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 148c58f1c22SToby Isaac 14920f4b53cSBarry Smith Not Collective 1505b5e7992SMatthew G. Knepley 151c58f1c22SToby Isaac Input parameter: 15220f4b53cSBarry Smith + label - The `DMLabel` 153c58f1c22SToby Isaac - v - The stratum value 154c58f1c22SToby Isaac 155c58f1c22SToby Isaac Output parameter: 15620f4b53cSBarry Smith . label - The `DMLabel` with stratum in hash format 157c58f1c22SToby Isaac 158c58f1c22SToby Isaac Level: developer 159c58f1c22SToby Isaac 16020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()` 161c58f1c22SToby Isaac */ 162d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 163d71ae5a4SJacob Faibussowitsch { 164c58f1c22SToby Isaac PetscInt p; 165ad8374ffSToby Isaac const PetscInt *points; 166c58f1c22SToby Isaac 167c58f1c22SToby Isaac PetscFunctionBegin; 1684d86920dSPierre Jolivet if ((PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) || label->readonly) PetscFunctionReturn(PETSC_SUCCESS); 1691dca8a05SBarry 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); 170ad8374ffSToby Isaac if (label->points[v]) { 1719566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 17248a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 1739566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 174f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 175ad8374ffSToby Isaac } 176ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 1773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 178c58f1c22SToby Isaac } 179c58f1c22SToby Isaac 180d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelMakeAllInvalid_Internal(DMLabel label) 181d71ae5a4SJacob Faibussowitsch { 182695799ffSMatthew G. Knepley PetscInt v; 183695799ffSMatthew G. Knepley 184695799ffSMatthew G. Knepley PetscFunctionBegin; 18548a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeInvalid_Private(label, v)); 1863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 187695799ffSMatthew G. Knepley } 188695799ffSMatthew G. Knepley 189b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 190b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 191b9907514SLisandro Dalcin #endif 192b9907514SLisandro Dalcin 1939f6c5813SMatthew G. Knepley PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 194d71ae5a4SJacob Faibussowitsch { 1950c3c4a36SLisandro Dalcin PetscInt v; 1960e79e033SBarry Smith 1970c3c4a36SLisandro Dalcin PetscFunctionBegin; 1980e79e033SBarry Smith *index = -1; 1999f6c5813SMatthew G. Knepley if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD || label->readonly) { 200b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2019371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2029371c9d4SSatish Balay *index = v; 2039371c9d4SSatish Balay break; 2049371c9d4SSatish Balay } 205b9907514SLisandro Dalcin } else { 2069566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index)); 2070e79e033SBarry Smith } 2089f6c5813SMatthew G. Knepley if (PetscDefined(USE_DEBUG) && !label->readonly) { /* Check strata hash map consistency */ 20990e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 2109566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len)); 21108401ef6SPierre Jolivet PetscCheck(len == label->numStrata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 21290e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 2139566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc)); 21490e9b2aeSLisandro Dalcin } else { 21590e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2169371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2179371c9d4SSatish Balay loc = v; 2189371c9d4SSatish Balay break; 2199371c9d4SSatish Balay } 22090e9b2aeSLisandro Dalcin } 22108401ef6SPierre Jolivet PetscCheck(loc == *index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 22290e9b2aeSLisandro Dalcin } 2233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2240c3c4a36SLisandro Dalcin } 2250c3c4a36SLisandro Dalcin 226d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 227d71ae5a4SJacob Faibussowitsch { 228b9907514SLisandro Dalcin PetscInt v; 229b9907514SLisandro Dalcin PetscInt *tmpV; 230b9907514SLisandro Dalcin PetscInt *tmpS; 231b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 232b9907514SLisandro Dalcin IS *tmpP, is; 233c58f1c22SToby Isaac PetscBool *tmpB; 234b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 235c58f1c22SToby Isaac 236c58f1c22SToby Isaac PetscFunctionBegin; 237b9907514SLisandro Dalcin v = label->numStrata; 238b9907514SLisandro Dalcin tmpV = label->stratumValues; 239b9907514SLisandro Dalcin tmpS = label->stratumSizes; 240b9907514SLisandro Dalcin tmpH = label->ht; 241b9907514SLisandro Dalcin tmpP = label->points; 242b9907514SLisandro Dalcin tmpB = label->validIS; 2438e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2448e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2458e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2468e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2478e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2488e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2499566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpV), &tmpV)); 2509566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpS), &tmpS)); 2519f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpH), &tmpH)); 2529f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpP), &tmpP)); 2539566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpB), &tmpB)); 2549566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v)); 2559566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v)); 2569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v)); 2579566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v)); 2589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v)); 2599566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV)); 2609566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS)); 2619566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH)); 2629566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP)); 2639566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB)); 2648e1f8cf0SLisandro Dalcin } 265b9907514SLisandro Dalcin label->numStrata = v + 1; 266c58f1c22SToby Isaac label->stratumValues = tmpV; 267c58f1c22SToby Isaac label->stratumSizes = tmpS; 268c58f1c22SToby Isaac label->ht = tmpH; 269c58f1c22SToby Isaac label->points = tmpP; 270ad8374ffSToby Isaac label->validIS = tmpB; 2719566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 2729566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 2739566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v)); 274b9907514SLisandro Dalcin tmpV[v] = value; 275b9907514SLisandro Dalcin tmpS[v] = 0; 276b9907514SLisandro Dalcin tmpH[v] = ht; 277b9907514SLisandro Dalcin tmpP[v] = is; 278b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 2799566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 2800c3c4a36SLisandro Dalcin *index = v; 2813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2820c3c4a36SLisandro Dalcin } 2830c3c4a36SLisandro Dalcin 284d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 285d71ae5a4SJacob Faibussowitsch { 286b9907514SLisandro Dalcin PetscFunctionBegin; 2879566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index)); 2889566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index)); 2893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 290b9907514SLisandro Dalcin } 291b9907514SLisandro Dalcin 2929f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) 293d71ae5a4SJacob Faibussowitsch { 2949e63cc69SVaclav Hapla PetscFunctionBegin; 2959e63cc69SVaclav Hapla *size = 0; 2963ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 2979f6c5813SMatthew G. Knepley if (label->readonly || label->validIS[v]) { 2989e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 2999e63cc69SVaclav Hapla } else { 3009566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size)); 3019e63cc69SVaclav Hapla } 3023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3039e63cc69SVaclav Hapla } 3049e63cc69SVaclav Hapla 305b9907514SLisandro Dalcin /*@ 30620f4b53cSBarry Smith DMLabelAddStratum - Adds a new stratum value in a `DMLabel` 307b9907514SLisandro Dalcin 308d8d19677SJose E. Roman Input Parameters: 30920f4b53cSBarry Smith + label - The `DMLabel` 310b9907514SLisandro Dalcin - value - The stratum value 311b9907514SLisandro Dalcin 312b9907514SLisandro Dalcin Level: beginner 313b9907514SLisandro Dalcin 31420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 315b9907514SLisandro Dalcin @*/ 316d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 317d71ae5a4SJacob Faibussowitsch { 3180c3c4a36SLisandro Dalcin PetscInt v; 3190c3c4a36SLisandro Dalcin 3200c3c4a36SLisandro Dalcin PetscFunctionBegin; 321d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3229f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3239566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 3243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 325b9907514SLisandro Dalcin } 326b9907514SLisandro Dalcin 327b9907514SLisandro Dalcin /*@ 32820f4b53cSBarry Smith DMLabelAddStrata - Adds new stratum values in a `DMLabel` 329b9907514SLisandro Dalcin 33020f4b53cSBarry Smith Not Collective 3315b5e7992SMatthew G. Knepley 332d8d19677SJose E. Roman Input Parameters: 33320f4b53cSBarry Smith + label - The `DMLabel` 334b9907514SLisandro Dalcin . numStrata - The number of stratum values 335b9907514SLisandro Dalcin - stratumValues - The stratum values 336b9907514SLisandro Dalcin 337b9907514SLisandro Dalcin Level: beginner 338b9907514SLisandro Dalcin 33920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 340b9907514SLisandro Dalcin @*/ 341d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 342d71ae5a4SJacob Faibussowitsch { 343b9907514SLisandro Dalcin PetscInt *values, v; 344b9907514SLisandro Dalcin 345b9907514SLisandro Dalcin PetscFunctionBegin; 346b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3474f572ea9SToby Isaac if (numStrata) PetscAssertPointer(stratumValues, 3); 3489f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &values)); 3509566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(values, stratumValues, numStrata)); 3519566063dSJacob Faibussowitsch PetscCall(PetscSortRemoveDupsInt(&numStrata, values)); 352b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 353b9907514SLisandro Dalcin PetscInt *tmpV; 354b9907514SLisandro Dalcin PetscInt *tmpS; 355b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 356b9907514SLisandro Dalcin IS *tmpP, is; 357b9907514SLisandro Dalcin PetscBool *tmpB; 358b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 359b9907514SLisandro Dalcin 3609566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpV)); 3619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpS)); 3629f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpH)); 3639f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpP)); 3649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpB)); 365b9907514SLisandro Dalcin label->numStrata = numStrata; 366b9907514SLisandro Dalcin label->stratumValues = tmpV; 367b9907514SLisandro Dalcin label->stratumSizes = tmpS; 368b9907514SLisandro Dalcin label->ht = tmpH; 369b9907514SLisandro Dalcin label->points = tmpP; 370b9907514SLisandro Dalcin label->validIS = tmpB; 371b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 3729566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 3739566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 3749566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, values[v], v)); 375b9907514SLisandro Dalcin tmpV[v] = values[v]; 376b9907514SLisandro Dalcin tmpS[v] = 0; 377b9907514SLisandro Dalcin tmpH[v] = ht; 378b9907514SLisandro Dalcin tmpP[v] = is; 379b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 380b9907514SLisandro Dalcin } 3819566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 382b9907514SLisandro Dalcin } else { 38348a46eb9SPierre Jolivet for (v = 0; v < numStrata; ++v) PetscCall(DMLabelAddStratum(label, values[v])); 384b9907514SLisandro Dalcin } 3859566063dSJacob Faibussowitsch PetscCall(PetscFree(values)); 3863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 387b9907514SLisandro Dalcin } 388b9907514SLisandro Dalcin 389b9907514SLisandro Dalcin /*@ 39020f4b53cSBarry Smith DMLabelAddStrataIS - Adds new stratum values in a `DMLabel` 391b9907514SLisandro Dalcin 39220f4b53cSBarry Smith Not Collective 3935b5e7992SMatthew G. Knepley 394d8d19677SJose E. Roman Input Parameters: 39520f4b53cSBarry Smith + label - The `DMLabel` 396b9907514SLisandro Dalcin - valueIS - Index set with stratum values 397b9907514SLisandro Dalcin 398b9907514SLisandro Dalcin Level: beginner 399b9907514SLisandro Dalcin 40020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 401b9907514SLisandro Dalcin @*/ 402d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 403d71ae5a4SJacob Faibussowitsch { 404b9907514SLisandro Dalcin PetscInt numStrata; 405b9907514SLisandro Dalcin const PetscInt *stratumValues; 406b9907514SLisandro Dalcin 407b9907514SLisandro Dalcin PetscFunctionBegin; 408b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 409b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 4109f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 4119566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata)); 4129566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues)); 4139566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues)); 4143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 415c58f1c22SToby Isaac } 416c58f1c22SToby Isaac 4179f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelView_Concrete_Ascii(DMLabel label, PetscViewer viewer) 418d71ae5a4SJacob Faibussowitsch { 419c58f1c22SToby Isaac PetscInt v; 420c58f1c22SToby Isaac PetscMPIInt rank; 421c58f1c22SToby Isaac 422c58f1c22SToby Isaac PetscFunctionBegin; 4239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 4249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 425c58f1c22SToby Isaac if (label) { 426d67d17b1SMatthew G. Knepley const char *name; 427d67d17b1SMatthew G. Knepley 4289566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 4299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name)); 43063a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd)); 431c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 432c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 433ad8374ffSToby Isaac const PetscInt *points; 434c58f1c22SToby Isaac PetscInt p; 435c58f1c22SToby Isaac 4369566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 43748a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 4389566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 439c58f1c22SToby Isaac } 440c58f1c22SToby Isaac } 4419566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 4429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 4433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 444c58f1c22SToby Isaac } 445c58f1c22SToby Isaac 44666976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelView_Concrete(DMLabel label, PetscViewer viewer) 4479f6c5813SMatthew G. Knepley { 4489f6c5813SMatthew G. Knepley PetscBool iascii; 4499f6c5813SMatthew G. Knepley 4509f6c5813SMatthew G. Knepley PetscFunctionBegin; 4519f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4529f6c5813SMatthew G. Knepley if (iascii) PetscCall(DMLabelView_Concrete_Ascii(label, viewer)); 4533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4549f6c5813SMatthew G. Knepley } 4559f6c5813SMatthew G. Knepley 456ffeef943SBarry Smith /*@ 457c58f1c22SToby Isaac DMLabelView - View the label 458c58f1c22SToby Isaac 45920f4b53cSBarry Smith Collective 4605b5e7992SMatthew G. Knepley 461c58f1c22SToby Isaac Input Parameters: 46220f4b53cSBarry Smith + label - The `DMLabel` 46320f4b53cSBarry Smith - viewer - The `PetscViewer` 464c58f1c22SToby Isaac 465c58f1c22SToby Isaac Level: intermediate 466c58f1c22SToby Isaac 46720f4b53cSBarry Smith .seealso: `DMLabel`, `PetscViewer`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 468c58f1c22SToby Isaac @*/ 469d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 470d71ae5a4SJacob Faibussowitsch { 471c58f1c22SToby Isaac PetscFunctionBegin; 472d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 4739566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer)); 474c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4759f6c5813SMatthew G. Knepley PetscCall(DMLabelMakeAllValid_Private(label)); 4769f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, view, viewer); 4773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 478c58f1c22SToby Isaac } 479c58f1c22SToby Isaac 48084f0b6dfSMatthew G. Knepley /*@ 48120f4b53cSBarry Smith DMLabelReset - Destroys internal data structures in a `DMLabel` 482d67d17b1SMatthew G. Knepley 48320f4b53cSBarry Smith Not Collective 4845b5e7992SMatthew G. Knepley 485d67d17b1SMatthew G. Knepley Input Parameter: 48620f4b53cSBarry Smith . label - The `DMLabel` 487d67d17b1SMatthew G. Knepley 488d67d17b1SMatthew G. Knepley Level: beginner 489d67d17b1SMatthew G. Knepley 49020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDestroy()`, `DMLabelCreate()` 491d67d17b1SMatthew G. Knepley @*/ 492d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelReset(DMLabel label) 493d71ae5a4SJacob Faibussowitsch { 494d67d17b1SMatthew G. Knepley PetscInt v; 495d67d17b1SMatthew G. Knepley 496d67d17b1SMatthew G. Knepley PetscFunctionBegin; 497d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 498d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 4999f6c5813SMatthew G. Knepley if (label->ht[v]) PetscCall(PetscHSetIDestroy(&label->ht[v])); 5009566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 501d67d17b1SMatthew G. Knepley } 502b9907514SLisandro Dalcin label->numStrata = 0; 5039566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues)); 5049566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes)); 5059566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht)); 5069566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points)); 5079566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS)); 5089566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 509b9907514SLisandro Dalcin label->pStart = -1; 510b9907514SLisandro Dalcin label->pEnd = -1; 5119566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 5123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 513d67d17b1SMatthew G. Knepley } 514d67d17b1SMatthew G. Knepley 515d67d17b1SMatthew G. Knepley /*@ 51620f4b53cSBarry Smith DMLabelDestroy - Destroys a `DMLabel` 51784f0b6dfSMatthew G. Knepley 51820f4b53cSBarry Smith Collective 5195b5e7992SMatthew G. Knepley 52084f0b6dfSMatthew G. Knepley Input Parameter: 52120f4b53cSBarry Smith . label - The `DMLabel` 52284f0b6dfSMatthew G. Knepley 52384f0b6dfSMatthew G. Knepley Level: beginner 52484f0b6dfSMatthew G. Knepley 52520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelReset()`, `DMLabelCreate()` 52684f0b6dfSMatthew G. Knepley @*/ 527d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroy(DMLabel *label) 528d71ae5a4SJacob Faibussowitsch { 529c58f1c22SToby Isaac PetscFunctionBegin; 5303ba16761SJacob Faibussowitsch if (!*label) PetscFunctionReturn(PETSC_SUCCESS); 531f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 1); 532f4f49eeaSPierre Jolivet if (--((PetscObject)*label)->refct > 0) { 5339371c9d4SSatish Balay *label = NULL; 5343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5359371c9d4SSatish Balay } 5369566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 5379566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 5389566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 5393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 540c58f1c22SToby Isaac } 541c58f1c22SToby Isaac 54266976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDuplicate_Concrete(DMLabel label, DMLabel *labelnew) 5439f6c5813SMatthew G. Knepley { 5449f6c5813SMatthew G. Knepley PetscFunctionBegin; 5459f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 5469f6c5813SMatthew G. Knepley PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 547f4f49eeaSPierre Jolivet PetscCall(PetscObjectReference((PetscObject)label->points[v])); 5489f6c5813SMatthew G. Knepley (*labelnew)->points[v] = label->points[v]; 5499f6c5813SMatthew G. Knepley } 5509f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5519f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDuplicate(label->hmap, &(*labelnew)->hmap)); 5523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5539f6c5813SMatthew G. Knepley } 5549f6c5813SMatthew G. Knepley 55584f0b6dfSMatthew G. Knepley /*@ 55620f4b53cSBarry Smith DMLabelDuplicate - Duplicates a `DMLabel` 55784f0b6dfSMatthew G. Knepley 55820f4b53cSBarry Smith Collective 5595b5e7992SMatthew G. Knepley 56084f0b6dfSMatthew G. Knepley Input Parameter: 56120f4b53cSBarry Smith . label - The `DMLabel` 56284f0b6dfSMatthew G. Knepley 56384f0b6dfSMatthew G. Knepley Output Parameter: 56420f4b53cSBarry Smith . labelnew - new label 56584f0b6dfSMatthew G. Knepley 56684f0b6dfSMatthew G. Knepley Level: intermediate 56784f0b6dfSMatthew G. Knepley 56820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 56984f0b6dfSMatthew G. Knepley @*/ 570d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 571d71ae5a4SJacob Faibussowitsch { 572d67d17b1SMatthew G. Knepley const char *name; 573c58f1c22SToby Isaac 574c58f1c22SToby Isaac PetscFunctionBegin; 575d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 5769566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 5779566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 5789566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)label), name, labelnew)); 579c58f1c22SToby Isaac 580c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5815aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 5828dcf10e8SMatthew G. Knepley (*labelnew)->readonly = label->readonly; 5839566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 5849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 5859f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->ht)); 5869f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->points)); 5879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 5889f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 589c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 590c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 591b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 592c58f1c22SToby Isaac } 593c58f1c22SToby Isaac (*labelnew)->pStart = -1; 594c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 595c58f1c22SToby Isaac (*labelnew)->bt = NULL; 5969f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, duplicate, labelnew); 5973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 598c58f1c22SToby Isaac } 599c58f1c22SToby Isaac 600609dae6eSVaclav Hapla /*@C 60120f4b53cSBarry Smith DMLabelCompare - Compare two `DMLabel` objects 602609dae6eSVaclav Hapla 60320f4b53cSBarry Smith Collective; No Fortran Support 604609dae6eSVaclav Hapla 605609dae6eSVaclav Hapla Input Parameters: 606f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 60720f4b53cSBarry Smith . l0 - First `DMLabel` 60820f4b53cSBarry Smith - l1 - Second `DMLabel` 609609dae6eSVaclav Hapla 610a4e35b19SJacob Faibussowitsch Output Parameters: 6115efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 6125efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 613609dae6eSVaclav Hapla 614609dae6eSVaclav Hapla Level: intermediate 615609dae6eSVaclav Hapla 616609dae6eSVaclav Hapla Notes: 6175efe38ccSVaclav Hapla The output flag equal is the same on all processes. 61820f4b53cSBarry Smith If it is passed as `NULL` and difference is found, an error is thrown on all processes. 61920f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 620609dae6eSVaclav Hapla 6215efe38ccSVaclav Hapla The output message is set independently on each rank. 62220f4b53cSBarry Smith It is set to `NULL` if no difference was found on the current rank. It must be freed by user. 62320f4b53cSBarry Smith If message is passed as `NULL` and difference is found, the difference description is printed to stderr in synchronized manner. 62420f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 625609dae6eSVaclav Hapla 626609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 627609dae6eSVaclav Hapla 62820f4b53cSBarry Smith The communicator needs to be specified because currently `DMLabel` can live on `PETSC_COMM_SELF` even if the underlying `DM` is parallel. 6295efe38ccSVaclav Hapla 630a3b724e8SBarry Smith Developer Note: 631a3b724e8SBarry Smith Fortran stub cannot be generated automatically because `message` must be freed with `PetscFree()` 632a3b724e8SBarry Smith 63320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 634609dae6eSVaclav Hapla @*/ 635d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 636d71ae5a4SJacob Faibussowitsch { 637609dae6eSVaclav Hapla const char *name0, *name1; 638609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 6395efe38ccSVaclav Hapla PetscBool eq; 6405efe38ccSVaclav Hapla PetscMPIInt rank; 641609dae6eSVaclav Hapla 642609dae6eSVaclav Hapla PetscFunctionBegin; 6435efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 6445efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6454f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 4); 6464f572ea9SToby Isaac if (message) PetscAssertPointer(message, 5); 6479566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6489566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6499566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 650609dae6eSVaclav Hapla { 651609dae6eSVaclav Hapla PetscInt v0, v1; 652609dae6eSVaclav Hapla 6539566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6549566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6555efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 65648a46eb9SPierre 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)); 657712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6585efe38ccSVaclav Hapla if (!eq) goto finish; 659609dae6eSVaclav Hapla } 660609dae6eSVaclav Hapla { 661609dae6eSVaclav Hapla IS is0, is1; 662609dae6eSVaclav Hapla 6639566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6649566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6659566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6669566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6679566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 66848a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 669712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6705efe38ccSVaclav Hapla if (!eq) goto finish; 671609dae6eSVaclav Hapla } 672609dae6eSVaclav Hapla { 673609dae6eSVaclav Hapla PetscInt i, nValues; 674609dae6eSVaclav Hapla 6759566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 676609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 677609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 678609dae6eSVaclav Hapla PetscInt n; 679609dae6eSVaclav Hapla IS is0, is1; 680609dae6eSVaclav Hapla 6819566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 682609dae6eSVaclav Hapla if (!n) continue; 6839566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6849566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6859566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6869566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6879566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6885efe38ccSVaclav Hapla if (!eq) { 68963a3b9bcSJacob 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)); 6905efe38ccSVaclav Hapla break; 691609dae6eSVaclav Hapla } 692609dae6eSVaclav Hapla } 693712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 694609dae6eSVaclav Hapla } 695609dae6eSVaclav Hapla finish: 6965efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 697609dae6eSVaclav Hapla if (message) { 698609dae6eSVaclav Hapla *message = NULL; 69948a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 7005efe38ccSVaclav Hapla } else { 70148a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 7029566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 7035efe38ccSVaclav Hapla } 7045efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 7055efe38ccSVaclav Hapla if (equal) *equal = eq; 70663a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 7073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 708609dae6eSVaclav Hapla } 709609dae6eSVaclav Hapla 710c6a43d28SMatthew G. Knepley /*@ 711c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 712c6a43d28SMatthew G. Knepley 71320f4b53cSBarry Smith Not Collective 7145b5e7992SMatthew G. Knepley 715c6a43d28SMatthew G. Knepley Input Parameter: 71620f4b53cSBarry Smith . label - The `DMLabel` 717c6a43d28SMatthew G. Knepley 718c6a43d28SMatthew G. Knepley Level: intermediate 719c6a43d28SMatthew G. Knepley 72020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 721c6a43d28SMatthew G. Knepley @*/ 722d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label) 723d71ae5a4SJacob Faibussowitsch { 724*1690c2aeSBarry Smith PetscInt pStart = PETSC_INT_MAX, pEnd = -1, v; 725c6a43d28SMatthew G. Knepley 726c6a43d28SMatthew G. Knepley PetscFunctionBegin; 727c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7289566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 729c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 730c6a43d28SMatthew G. Knepley const PetscInt *points; 731c6a43d28SMatthew G. Knepley PetscInt i; 732c6a43d28SMatthew G. Knepley 7339566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 734c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 735c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 736c6a43d28SMatthew G. Knepley 737c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 738c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 739c6a43d28SMatthew G. Knepley } 7409566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 741c6a43d28SMatthew G. Knepley } 742*1690c2aeSBarry Smith label->pStart = pStart == PETSC_INT_MAX ? -1 : pStart; 743c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7449566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 7453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 746c6a43d28SMatthew G. Knepley } 747c6a43d28SMatthew G. Knepley 748c6a43d28SMatthew G. Knepley /*@ 749c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 750c6a43d28SMatthew G. Knepley 75120f4b53cSBarry Smith Not Collective 7525b5e7992SMatthew G. Knepley 753c6a43d28SMatthew G. Knepley Input Parameters: 75420f4b53cSBarry Smith + label - The `DMLabel` 755c6a43d28SMatthew G. Knepley . pStart - The smallest point 756c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 757c6a43d28SMatthew G. Knepley 758c6a43d28SMatthew G. Knepley Level: intermediate 759c6a43d28SMatthew G. Knepley 76020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 761c6a43d28SMatthew G. Knepley @*/ 762d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 763d71ae5a4SJacob Faibussowitsch { 764c58f1c22SToby Isaac PetscInt v; 765c58f1c22SToby Isaac 766c58f1c22SToby Isaac PetscFunctionBegin; 767d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7689566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7699566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 770c58f1c22SToby Isaac label->pStart = pStart; 771c58f1c22SToby Isaac label->pEnd = pEnd; 772c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7739566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 774c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 7759f6c5813SMatthew G. Knepley IS pointIS; 776ad8374ffSToby Isaac const PetscInt *points; 777c58f1c22SToby Isaac PetscInt i; 778c58f1c22SToby Isaac 7799f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 7809f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points)); 781c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 782ad8374ffSToby Isaac const PetscInt point = points[i]; 783c58f1c22SToby Isaac 7849f6c5813SMatthew 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); 7859566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 786c58f1c22SToby Isaac } 7879566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 7889f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 789c58f1c22SToby Isaac } 7903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 791c58f1c22SToby Isaac } 792c58f1c22SToby Isaac 793c6a43d28SMatthew G. Knepley /*@ 794c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 795c6a43d28SMatthew G. Knepley 79620f4b53cSBarry Smith Not Collective 7975b5e7992SMatthew G. Knepley 798c6a43d28SMatthew G. Knepley Input Parameter: 79920f4b53cSBarry Smith . label - the `DMLabel` 800c6a43d28SMatthew G. Knepley 801c6a43d28SMatthew G. Knepley Level: intermediate 802c6a43d28SMatthew G. Knepley 80320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 804c6a43d28SMatthew G. Knepley @*/ 805d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label) 806d71ae5a4SJacob Faibussowitsch { 807c58f1c22SToby Isaac PetscFunctionBegin; 808d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 809c58f1c22SToby Isaac label->pStart = -1; 810c58f1c22SToby Isaac label->pEnd = -1; 8119566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 8123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 813c58f1c22SToby Isaac } 814c58f1c22SToby Isaac 815c58f1c22SToby Isaac /*@ 816c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 817c6a43d28SMatthew G. Knepley 81820f4b53cSBarry Smith Not Collective 8195b5e7992SMatthew G. Knepley 820c6a43d28SMatthew G. Knepley Input Parameter: 82120f4b53cSBarry Smith . label - the `DMLabel` 822c6a43d28SMatthew G. Knepley 823c6a43d28SMatthew G. Knepley Output Parameters: 824c6a43d28SMatthew G. Knepley + pStart - The smallest point 825c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 826c6a43d28SMatthew G. Knepley 827c6a43d28SMatthew G. Knepley Level: intermediate 828c6a43d28SMatthew G. Knepley 82920f4b53cSBarry Smith Note: 83020f4b53cSBarry Smith This will compute an index for the label if one does not exist. 83120f4b53cSBarry Smith 83220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 833c6a43d28SMatthew G. Knepley @*/ 834d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 835d71ae5a4SJacob Faibussowitsch { 836c6a43d28SMatthew G. Knepley PetscFunctionBegin; 837c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8389566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 839c6a43d28SMatthew G. Knepley if (pStart) { 8404f572ea9SToby Isaac PetscAssertPointer(pStart, 2); 841c6a43d28SMatthew G. Knepley *pStart = label->pStart; 842c6a43d28SMatthew G. Knepley } 843c6a43d28SMatthew G. Knepley if (pEnd) { 8444f572ea9SToby Isaac PetscAssertPointer(pEnd, 3); 845c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 846c6a43d28SMatthew G. Knepley } 8473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 848c6a43d28SMatthew G. Knepley } 849c6a43d28SMatthew G. Knepley 850c6a43d28SMatthew G. Knepley /*@ 851c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 852c58f1c22SToby Isaac 85320f4b53cSBarry Smith Not Collective 8545b5e7992SMatthew G. Knepley 855c58f1c22SToby Isaac Input Parameters: 85620f4b53cSBarry Smith + label - the `DMLabel` 857c58f1c22SToby Isaac - value - the value 858c58f1c22SToby Isaac 859c58f1c22SToby Isaac Output Parameter: 860c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 861c58f1c22SToby Isaac 862c58f1c22SToby Isaac Level: developer 863c58f1c22SToby Isaac 86420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 865c58f1c22SToby Isaac @*/ 866d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 867d71ae5a4SJacob Faibussowitsch { 868c58f1c22SToby Isaac PetscInt v; 869c58f1c22SToby Isaac 870c58f1c22SToby Isaac PetscFunctionBegin; 871d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8724f572ea9SToby Isaac PetscAssertPointer(contains, 3); 8739566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8740c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 8753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 876c58f1c22SToby Isaac } 877c58f1c22SToby Isaac 878c58f1c22SToby Isaac /*@ 879c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 880c58f1c22SToby Isaac 88120f4b53cSBarry Smith Not Collective 8825b5e7992SMatthew G. Knepley 883c58f1c22SToby Isaac Input Parameters: 88420f4b53cSBarry Smith + label - the `DMLabel` 885c58f1c22SToby Isaac - point - the point 886c58f1c22SToby Isaac 887c58f1c22SToby Isaac Output Parameter: 888c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 889c58f1c22SToby Isaac 890c58f1c22SToby Isaac Level: developer 891c58f1c22SToby Isaac 89220f4b53cSBarry Smith Note: 89320f4b53cSBarry Smith The user must call `DMLabelCreateIndex()` before this function. 89420f4b53cSBarry Smith 89520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 896c58f1c22SToby Isaac @*/ 897d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 898d71ae5a4SJacob Faibussowitsch { 899c58f1c22SToby Isaac PetscFunctionBeginHot; 900d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9014f572ea9SToby Isaac PetscAssertPointer(contains, 3); 9029566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 90376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 90428b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 90563a3b9bcSJacob 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); 90676bd3646SJed Brown } 907c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 9083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 909c58f1c22SToby Isaac } 910c58f1c22SToby Isaac 911c58f1c22SToby Isaac /*@ 912c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 913c58f1c22SToby Isaac 91420f4b53cSBarry Smith Not Collective 9155b5e7992SMatthew G. Knepley 916c58f1c22SToby Isaac Input Parameters: 91720f4b53cSBarry Smith + label - the `DMLabel` 918c58f1c22SToby Isaac . value - the stratum value 919c58f1c22SToby Isaac - point - the point 920c58f1c22SToby Isaac 921c58f1c22SToby Isaac Output Parameter: 922c58f1c22SToby Isaac . contains - true if the stratum contains the point 923c58f1c22SToby Isaac 924c58f1c22SToby Isaac Level: intermediate 925c58f1c22SToby Isaac 92620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 927c58f1c22SToby Isaac @*/ 928d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 929d71ae5a4SJacob Faibussowitsch { 9300c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 931d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9324f572ea9SToby Isaac PetscAssertPointer(contains, 4); 933cffad2c9SToby Isaac if (value == label->defaultValue) { 934cffad2c9SToby Isaac PetscInt pointVal; 9350c3c4a36SLisandro Dalcin 936cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 937cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 938cffad2c9SToby Isaac } else { 939cffad2c9SToby Isaac PetscInt v; 940cffad2c9SToby Isaac 941cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 942cffad2c9SToby Isaac if (v >= 0) { 9439f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 9449f6c5813SMatthew G. Knepley IS is; 945c58f1c22SToby Isaac PetscInt i; 946c58f1c22SToby Isaac 9479f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 9482b4d18a0SMatthew G. Knepley PetscCall(ISLocate(is, point, &i)); 9499f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 950cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 951c58f1c22SToby Isaac } else { 952cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 953cffad2c9SToby Isaac } 954cffad2c9SToby Isaac } else { // value is not present 955cffad2c9SToby Isaac *contains = PETSC_FALSE; 956cffad2c9SToby Isaac } 957c58f1c22SToby Isaac } 9583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 959c58f1c22SToby Isaac } 960c58f1c22SToby Isaac 96184f0b6dfSMatthew G. Knepley /*@ 96220f4b53cSBarry Smith DMLabelGetDefaultValue - Get the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9635aa44df4SToby Isaac When a label is created, it is initialized to -1. 9645aa44df4SToby Isaac 96520f4b53cSBarry Smith Not Collective 9665b5e7992SMatthew G. Knepley 96760225df5SJacob Faibussowitsch Input Parameter: 96820f4b53cSBarry Smith . label - a `DMLabel` object 9695aa44df4SToby Isaac 97060225df5SJacob Faibussowitsch Output Parameter: 9715aa44df4SToby Isaac . defaultValue - the default value 9725aa44df4SToby Isaac 9735aa44df4SToby Isaac Level: beginner 9745aa44df4SToby Isaac 97520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 97684f0b6dfSMatthew G. Knepley @*/ 977d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 978d71ae5a4SJacob Faibussowitsch { 9795aa44df4SToby Isaac PetscFunctionBegin; 980d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9815aa44df4SToby Isaac *defaultValue = label->defaultValue; 9823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9835aa44df4SToby Isaac } 9845aa44df4SToby Isaac 98584f0b6dfSMatthew G. Knepley /*@ 98620f4b53cSBarry Smith DMLabelSetDefaultValue - Set the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9875aa44df4SToby Isaac When a label is created, it is initialized to -1. 9885aa44df4SToby Isaac 98920f4b53cSBarry Smith Not Collective 9905b5e7992SMatthew G. Knepley 99160225df5SJacob Faibussowitsch Input Parameter: 99220f4b53cSBarry Smith . label - a `DMLabel` object 9935aa44df4SToby Isaac 99460225df5SJacob Faibussowitsch Output Parameter: 9955aa44df4SToby Isaac . defaultValue - the default value 9965aa44df4SToby Isaac 9975aa44df4SToby Isaac Level: beginner 9985aa44df4SToby Isaac 99920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 100084f0b6dfSMatthew G. Knepley @*/ 1001d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 1002d71ae5a4SJacob Faibussowitsch { 10035aa44df4SToby Isaac PetscFunctionBegin; 1004d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10055aa44df4SToby Isaac label->defaultValue = defaultValue; 10063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10075aa44df4SToby Isaac } 10085aa44df4SToby Isaac 1009c58f1c22SToby Isaac /*@ 101020f4b53cSBarry 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 101120f4b53cSBarry Smith `DMLabelSetDefaultValue()`) 1012c58f1c22SToby Isaac 101320f4b53cSBarry Smith Not Collective 10145b5e7992SMatthew G. Knepley 1015c58f1c22SToby Isaac Input Parameters: 101620f4b53cSBarry Smith + label - the `DMLabel` 1017c58f1c22SToby Isaac - point - the point 1018c58f1c22SToby Isaac 1019c58f1c22SToby Isaac Output Parameter: 10208e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 1021c58f1c22SToby Isaac 1022c58f1c22SToby Isaac Level: intermediate 1023c58f1c22SToby Isaac 102420f4b53cSBarry Smith Note: 102520f4b53cSBarry Smith A label may assign multiple values to a point. No guarantees are made about which value is returned in that case. 102620f4b53cSBarry Smith Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum. 102720f4b53cSBarry Smith 102820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1029c58f1c22SToby Isaac @*/ 1030d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 1031d71ae5a4SJacob Faibussowitsch { 1032c58f1c22SToby Isaac PetscInt v; 1033c58f1c22SToby Isaac 10340c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 1035d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10364f572ea9SToby Isaac PetscAssertPointer(value, 3); 10375aa44df4SToby Isaac *value = label->defaultValue; 1038c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 10399f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 10409f6c5813SMatthew G. Knepley IS is; 1041c58f1c22SToby Isaac PetscInt i; 1042c58f1c22SToby Isaac 10439f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 10442b4d18a0SMatthew G. Knepley PetscCall(ISLocate(label->points[v], point, &i)); 10459f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1046c58f1c22SToby Isaac if (i >= 0) { 1047c58f1c22SToby Isaac *value = label->stratumValues[v]; 1048c58f1c22SToby Isaac break; 1049c58f1c22SToby Isaac } 1050c58f1c22SToby Isaac } else { 1051c58f1c22SToby Isaac PetscBool has; 1052c58f1c22SToby Isaac 10539566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 1054c58f1c22SToby Isaac if (has) { 1055c58f1c22SToby Isaac *value = label->stratumValues[v]; 1056c58f1c22SToby Isaac break; 1057c58f1c22SToby Isaac } 1058c58f1c22SToby Isaac } 1059c58f1c22SToby Isaac } 10603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1061c58f1c22SToby Isaac } 1062c58f1c22SToby Isaac 1063c58f1c22SToby Isaac /*@ 106420f4b53cSBarry 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 106520f4b53cSBarry Smith be changed with `DMLabelSetDefaultValue()` to something different), then this function will do nothing. 1066c58f1c22SToby Isaac 106720f4b53cSBarry Smith Not Collective 10685b5e7992SMatthew G. Knepley 1069c58f1c22SToby Isaac Input Parameters: 107020f4b53cSBarry Smith + label - the `DMLabel` 1071c58f1c22SToby Isaac . point - the point 1072c58f1c22SToby Isaac - value - The point value 1073c58f1c22SToby Isaac 1074c58f1c22SToby Isaac Level: intermediate 1075c58f1c22SToby Isaac 107620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1077c58f1c22SToby Isaac @*/ 1078d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1079d71ae5a4SJacob Faibussowitsch { 1080c58f1c22SToby Isaac PetscInt v; 1081c58f1c22SToby Isaac 1082c58f1c22SToby Isaac PetscFunctionBegin; 1083d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10840c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10853ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 10869f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 10879566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1088c58f1c22SToby Isaac /* Set key */ 10899566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10909566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 10913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1092c58f1c22SToby Isaac } 1093c58f1c22SToby Isaac 1094c58f1c22SToby Isaac /*@ 1095c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1096c58f1c22SToby Isaac 109720f4b53cSBarry Smith Not Collective 10985b5e7992SMatthew G. Knepley 1099c58f1c22SToby Isaac Input Parameters: 110020f4b53cSBarry Smith + label - the `DMLabel` 1101c58f1c22SToby Isaac . point - the point 1102c58f1c22SToby Isaac - value - The point value 1103c58f1c22SToby Isaac 1104c58f1c22SToby Isaac Level: intermediate 1105c58f1c22SToby Isaac 110620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1107c58f1c22SToby Isaac @*/ 1108d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1109d71ae5a4SJacob Faibussowitsch { 1110ad8374ffSToby Isaac PetscInt v; 1111c58f1c22SToby Isaac 1112c58f1c22SToby Isaac PetscFunctionBegin; 1113d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11149f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 1115c58f1c22SToby Isaac /* Find label value */ 11169566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 11173ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 11180c3c4a36SLisandro Dalcin 1119eeed21e7SToby Isaac if (label->bt) { 112063a3b9bcSJacob 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); 11219566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1122eeed21e7SToby Isaac } 11230c3c4a36SLisandro Dalcin 11240c3c4a36SLisandro Dalcin /* Delete key */ 11259566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11269566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 11273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1128c58f1c22SToby Isaac } 1129c58f1c22SToby Isaac 1130c58f1c22SToby Isaac /*@ 113120f4b53cSBarry Smith DMLabelInsertIS - Set all points in the `IS` to a value 1132c58f1c22SToby Isaac 113320f4b53cSBarry Smith Not Collective 11345b5e7992SMatthew G. Knepley 1135c58f1c22SToby Isaac Input Parameters: 113620f4b53cSBarry Smith + label - the `DMLabel` 11372fe279fdSBarry Smith . is - the point `IS` 1138c58f1c22SToby Isaac - value - The point value 1139c58f1c22SToby Isaac 1140c58f1c22SToby Isaac Level: intermediate 1141c58f1c22SToby Isaac 114220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1143c58f1c22SToby Isaac @*/ 1144d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1145d71ae5a4SJacob Faibussowitsch { 11460c3c4a36SLisandro Dalcin PetscInt v, n, p; 1147c58f1c22SToby Isaac const PetscInt *points; 1148c58f1c22SToby Isaac 1149c58f1c22SToby Isaac PetscFunctionBegin; 1150d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1151c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 11520c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11533ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 11549f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 11559566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 11560c3c4a36SLisandro Dalcin /* Set keys */ 11579566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11589566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 11599566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 11609566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 11619566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 11623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1163c58f1c22SToby Isaac } 1164c58f1c22SToby Isaac 116584f0b6dfSMatthew G. Knepley /*@ 116620f4b53cSBarry Smith DMLabelGetNumValues - Get the number of values that the `DMLabel` takes 116784f0b6dfSMatthew G. Knepley 116820f4b53cSBarry Smith Not Collective 11695b5e7992SMatthew G. Knepley 117084f0b6dfSMatthew G. Knepley Input Parameter: 117120f4b53cSBarry Smith . label - the `DMLabel` 117284f0b6dfSMatthew G. Knepley 117301d2d390SJose E. Roman Output Parameter: 117484f0b6dfSMatthew G. Knepley . numValues - the number of values 117584f0b6dfSMatthew G. Knepley 117684f0b6dfSMatthew G. Knepley Level: intermediate 117784f0b6dfSMatthew G. Knepley 117820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 117984f0b6dfSMatthew G. Knepley @*/ 1180d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1181d71ae5a4SJacob Faibussowitsch { 1182c58f1c22SToby Isaac PetscFunctionBegin; 1183d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11844f572ea9SToby Isaac PetscAssertPointer(numValues, 2); 1185c58f1c22SToby Isaac *numValues = label->numStrata; 11863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1187c58f1c22SToby Isaac } 1188c58f1c22SToby Isaac 118984f0b6dfSMatthew G. Knepley /*@ 119020f4b53cSBarry Smith DMLabelGetValueIS - Get an `IS` of all values that the `DMlabel` takes 119184f0b6dfSMatthew G. Knepley 119220f4b53cSBarry Smith Not Collective 11935b5e7992SMatthew G. Knepley 119484f0b6dfSMatthew G. Knepley Input Parameter: 119520f4b53cSBarry Smith . label - the `DMLabel` 119684f0b6dfSMatthew G. Knepley 119701d2d390SJose E. Roman Output Parameter: 119860225df5SJacob Faibussowitsch . values - the value `IS` 119984f0b6dfSMatthew G. Knepley 120084f0b6dfSMatthew G. Knepley Level: intermediate 120184f0b6dfSMatthew G. Knepley 12021d04cbbeSVaclav Hapla Notes: 120320f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 120420f4b53cSBarry Smith Strata which are allocated but empty [`DMLabelGetStratumSize()` yields 0] are counted. 120520f4b53cSBarry Smith If you need to count only nonempty strata, use `DMLabelGetNonEmptyStratumValuesIS()`. 12061d04cbbeSVaclav Hapla 120720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 120884f0b6dfSMatthew G. Knepley @*/ 1209d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1210d71ae5a4SJacob Faibussowitsch { 1211c58f1c22SToby Isaac PetscFunctionBegin; 1212d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12134f572ea9SToby Isaac PetscAssertPointer(values, 2); 12149566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1216c58f1c22SToby Isaac } 1217c58f1c22SToby Isaac 121884f0b6dfSMatthew G. Knepley /*@ 12198696263dSMatthew G. Knepley DMLabelGetValueBounds - Return the smallest and largest value in the label 12208696263dSMatthew G. Knepley 12218696263dSMatthew G. Knepley Not Collective 12228696263dSMatthew G. Knepley 12238696263dSMatthew G. Knepley Input Parameter: 12248696263dSMatthew G. Knepley . label - the `DMLabel` 12258696263dSMatthew G. Knepley 12268696263dSMatthew G. Knepley Output Parameters: 12278696263dSMatthew G. Knepley + minValue - The smallest value 12288696263dSMatthew G. Knepley - maxValue - The largest value 12298696263dSMatthew G. Knepley 12308696263dSMatthew G. Knepley Level: intermediate 12318696263dSMatthew G. Knepley 12328696263dSMatthew G. Knepley .seealso: `DMLabel`, `DM`, `DMLabelGetBounds()`, `DMLabelGetValue()`, `DMLabelSetValue()` 12338696263dSMatthew G. Knepley @*/ 12348696263dSMatthew G. Knepley PetscErrorCode DMLabelGetValueBounds(DMLabel label, PetscInt *minValue, PetscInt *maxValue) 12358696263dSMatthew G. Knepley { 1236*1690c2aeSBarry Smith PetscInt min = PETSC_INT_MAX, max = PETSC_INT_MIN; 12378696263dSMatthew G. Knepley 12388696263dSMatthew G. Knepley PetscFunctionBegin; 12398696263dSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12408696263dSMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 12418696263dSMatthew G. Knepley min = PetscMin(min, label->stratumValues[v]); 12428696263dSMatthew G. Knepley max = PetscMax(max, label->stratumValues[v]); 12438696263dSMatthew G. Knepley } 12448696263dSMatthew G. Knepley if (minValue) { 12458696263dSMatthew G. Knepley PetscAssertPointer(minValue, 2); 12468696263dSMatthew G. Knepley *minValue = min; 12478696263dSMatthew G. Knepley } 12488696263dSMatthew G. Knepley if (maxValue) { 12498696263dSMatthew G. Knepley PetscAssertPointer(maxValue, 3); 12508696263dSMatthew G. Knepley *maxValue = max; 12518696263dSMatthew G. Knepley } 12528696263dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 12538696263dSMatthew G. Knepley } 12548696263dSMatthew G. Knepley 12558696263dSMatthew G. Knepley /*@ 125620f4b53cSBarry Smith DMLabelGetNonEmptyStratumValuesIS - Get an `IS` of all values that the `DMlabel` takes 12571d04cbbeSVaclav Hapla 125820f4b53cSBarry Smith Not Collective 12591d04cbbeSVaclav Hapla 12601d04cbbeSVaclav Hapla Input Parameter: 126120f4b53cSBarry Smith . label - the `DMLabel` 12621d04cbbeSVaclav Hapla 1263d5b43468SJose E. Roman Output Parameter: 126460225df5SJacob Faibussowitsch . values - the value `IS` 12651d04cbbeSVaclav Hapla 12661d04cbbeSVaclav Hapla Level: intermediate 12671d04cbbeSVaclav Hapla 12681d04cbbeSVaclav Hapla Notes: 126920f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 127020f4b53cSBarry Smith This is similar to `DMLabelGetValueIS()` but counts only nonempty strata. 12711d04cbbeSVaclav Hapla 127220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 12731d04cbbeSVaclav Hapla @*/ 1274d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 1275d71ae5a4SJacob Faibussowitsch { 12761d04cbbeSVaclav Hapla PetscInt i, j; 12771d04cbbeSVaclav Hapla PetscInt *valuesArr; 12781d04cbbeSVaclav Hapla 12791d04cbbeSVaclav Hapla PetscFunctionBegin; 12801d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12814f572ea9SToby Isaac PetscAssertPointer(values, 2); 12829566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 12831d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 12841d04cbbeSVaclav Hapla PetscInt n; 12851d04cbbeSVaclav Hapla 12869566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 12871d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 12881d04cbbeSVaclav Hapla } 12891d04cbbeSVaclav Hapla if (j == label->numStrata) { 12909566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12911d04cbbeSVaclav Hapla } else { 12929566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 12931d04cbbeSVaclav Hapla } 12949566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 12953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12961d04cbbeSVaclav Hapla } 12971d04cbbeSVaclav Hapla 12981d04cbbeSVaclav Hapla /*@ 129920f4b53cSBarry Smith DMLabelGetValueIndex - Get the index of a given value in the list of values for the `DMlabel`, or -1 if it is not present 1300d123abd9SMatthew G. Knepley 130120f4b53cSBarry Smith Not Collective 1302d123abd9SMatthew G. Knepley 1303d123abd9SMatthew G. Knepley Input Parameters: 130420f4b53cSBarry Smith + label - the `DMLabel` 130597bb3fdcSJose E. Roman - value - the value 1306d123abd9SMatthew G. Knepley 130701d2d390SJose E. Roman Output Parameter: 1308d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1309d123abd9SMatthew G. Knepley 1310d123abd9SMatthew G. Knepley Level: intermediate 1311d123abd9SMatthew G. Knepley 131220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1313d123abd9SMatthew G. Knepley @*/ 1314d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1315d71ae5a4SJacob Faibussowitsch { 1316d123abd9SMatthew G. Knepley PetscInt v; 1317d123abd9SMatthew G. Knepley 1318d123abd9SMatthew G. Knepley PetscFunctionBegin; 1319d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13204f572ea9SToby Isaac PetscAssertPointer(index, 3); 1321d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 13229371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 13239371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1324d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1325d123abd9SMatthew G. Knepley else *index = v; 13263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1327d123abd9SMatthew G. Knepley } 1328d123abd9SMatthew G. Knepley 1329d123abd9SMatthew G. Knepley /*@ 133084f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 133184f0b6dfSMatthew G. Knepley 133220f4b53cSBarry Smith Not Collective 13335b5e7992SMatthew G. Knepley 133484f0b6dfSMatthew G. Knepley Input Parameters: 133520f4b53cSBarry Smith + label - the `DMLabel` 133684f0b6dfSMatthew G. Knepley - value - the stratum value 133784f0b6dfSMatthew G. Knepley 133801d2d390SJose E. Roman Output Parameter: 133984f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 134084f0b6dfSMatthew G. Knepley 134184f0b6dfSMatthew G. Knepley Level: intermediate 134284f0b6dfSMatthew G. Knepley 134320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 134484f0b6dfSMatthew G. Knepley @*/ 1345d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1346d71ae5a4SJacob Faibussowitsch { 1347fada774cSMatthew G. Knepley PetscInt v; 1348fada774cSMatthew G. Knepley 1349fada774cSMatthew G. Knepley PetscFunctionBegin; 1350d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13514f572ea9SToby Isaac PetscAssertPointer(exists, 3); 13529566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13530c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 13543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1355fada774cSMatthew G. Knepley } 1356fada774cSMatthew G. Knepley 135784f0b6dfSMatthew G. Knepley /*@ 135884f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 135984f0b6dfSMatthew G. Knepley 136020f4b53cSBarry Smith Not Collective 13615b5e7992SMatthew G. Knepley 136284f0b6dfSMatthew G. Knepley Input Parameters: 136320f4b53cSBarry Smith + label - the `DMLabel` 136484f0b6dfSMatthew G. Knepley - value - the stratum value 136584f0b6dfSMatthew G. Knepley 136601d2d390SJose E. Roman Output Parameter: 136784f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 136884f0b6dfSMatthew G. Knepley 136984f0b6dfSMatthew G. Knepley Level: intermediate 137084f0b6dfSMatthew G. Knepley 137120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 137284f0b6dfSMatthew G. Knepley @*/ 1373d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1374d71ae5a4SJacob Faibussowitsch { 1375c58f1c22SToby Isaac PetscInt v; 1376c58f1c22SToby Isaac 1377c58f1c22SToby Isaac PetscFunctionBegin; 1378d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13794f572ea9SToby Isaac PetscAssertPointer(size, 3); 13809566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13819566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 13823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1383c58f1c22SToby Isaac } 1384c58f1c22SToby Isaac 138584f0b6dfSMatthew G. Knepley /*@ 138684f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 138784f0b6dfSMatthew G. Knepley 138820f4b53cSBarry Smith Not Collective 13895b5e7992SMatthew G. Knepley 139084f0b6dfSMatthew G. Knepley Input Parameters: 139120f4b53cSBarry Smith + label - the `DMLabel` 139284f0b6dfSMatthew G. Knepley - value - the stratum value 139384f0b6dfSMatthew G. Knepley 139401d2d390SJose E. Roman Output Parameters: 139584f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 139684f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 139784f0b6dfSMatthew G. Knepley 139884f0b6dfSMatthew G. Knepley Level: intermediate 139984f0b6dfSMatthew G. Knepley 140020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 140184f0b6dfSMatthew G. Knepley @*/ 1402d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1403d71ae5a4SJacob Faibussowitsch { 14049f6c5813SMatthew G. Knepley IS is; 14050c3c4a36SLisandro Dalcin PetscInt v, min, max; 1406c58f1c22SToby Isaac 1407c58f1c22SToby Isaac PetscFunctionBegin; 1408d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14099371c9d4SSatish Balay if (start) { 14104f572ea9SToby Isaac PetscAssertPointer(start, 3); 14119371c9d4SSatish Balay *start = -1; 14129371c9d4SSatish Balay } 14139371c9d4SSatish Balay if (end) { 14144f572ea9SToby Isaac PetscAssertPointer(end, 4); 14159371c9d4SSatish Balay *end = -1; 14169371c9d4SSatish Balay } 14179566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14183ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14199566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14203ba16761SJacob Faibussowitsch if (label->stratumSizes[v] <= 0) PetscFunctionReturn(PETSC_SUCCESS); 14219f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 14229f6c5813SMatthew G. Knepley PetscCall(ISGetMinMax(is, &min, &max)); 14239f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1424d6cb179aSToby Isaac if (start) *start = min; 1425d6cb179aSToby Isaac if (end) *end = max + 1; 14263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1427c58f1c22SToby Isaac } 1428c58f1c22SToby Isaac 142966976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelGetStratumIS_Concrete(DMLabel label, PetscInt v, IS *pointIS) 14309f6c5813SMatthew G. Knepley { 14319f6c5813SMatthew G. Knepley PetscFunctionBegin; 14329f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)label->points[v])); 14339f6c5813SMatthew G. Knepley *pointIS = label->points[v]; 14343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14359f6c5813SMatthew G. Knepley } 14369f6c5813SMatthew G. Knepley 143784f0b6dfSMatthew G. Knepley /*@ 143820f4b53cSBarry Smith DMLabelGetStratumIS - Get an `IS` with the stratum points 143984f0b6dfSMatthew G. Knepley 144020f4b53cSBarry Smith Not Collective 14415b5e7992SMatthew G. Knepley 144284f0b6dfSMatthew G. Knepley Input Parameters: 144320f4b53cSBarry Smith + label - the `DMLabel` 144484f0b6dfSMatthew G. Knepley - value - the stratum value 144584f0b6dfSMatthew G. Knepley 144601d2d390SJose E. Roman Output Parameter: 144784f0b6dfSMatthew G. Knepley . points - The stratum points 144884f0b6dfSMatthew G. Knepley 144984f0b6dfSMatthew G. Knepley Level: intermediate 145084f0b6dfSMatthew G. Knepley 1451593ce467SVaclav Hapla Notes: 145220f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 145320f4b53cSBarry Smith Returns `NULL` if the stratum is empty. 1454593ce467SVaclav Hapla 145520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 145684f0b6dfSMatthew G. Knepley @*/ 1457d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1458d71ae5a4SJacob Faibussowitsch { 1459c58f1c22SToby Isaac PetscInt v; 1460c58f1c22SToby Isaac 1461c58f1c22SToby Isaac PetscFunctionBegin; 1462d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14634f572ea9SToby Isaac PetscAssertPointer(points, 3); 1464c58f1c22SToby Isaac *points = NULL; 14659566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14663ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14679566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14689f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, points); 14693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1470c58f1c22SToby Isaac } 1471c58f1c22SToby Isaac 147284f0b6dfSMatthew G. Knepley /*@ 147320f4b53cSBarry Smith DMLabelSetStratumIS - Set the stratum points using an `IS` 147484f0b6dfSMatthew G. Knepley 147520f4b53cSBarry Smith Not Collective 14765b5e7992SMatthew G. Knepley 147784f0b6dfSMatthew G. Knepley Input Parameters: 147820f4b53cSBarry Smith + label - the `DMLabel` 147984f0b6dfSMatthew G. Knepley . value - the stratum value 148060225df5SJacob Faibussowitsch - is - The stratum points 148184f0b6dfSMatthew G. Knepley 148284f0b6dfSMatthew G. Knepley Level: intermediate 148384f0b6dfSMatthew G. Knepley 148420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 148584f0b6dfSMatthew G. Knepley @*/ 1486d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 1487d71ae5a4SJacob Faibussowitsch { 14880c3c4a36SLisandro Dalcin PetscInt v; 14894de306b1SToby Isaac 14904de306b1SToby Isaac PetscFunctionBegin; 1491d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1492d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 14939f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 14949566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 14953ba16761SJacob Faibussowitsch if (is == label->points[v]) PetscFunctionReturn(PETSC_SUCCESS); 14969566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 1497f4f49eeaSPierre Jolivet PetscCall(ISGetLocalSize(is, &label->stratumSizes[v])); 14989566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 1499f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 15000c3c4a36SLisandro Dalcin label->points[v] = is; 15010c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 15029566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 15034de306b1SToby Isaac if (label->bt) { 15044de306b1SToby Isaac const PetscInt *points; 15054de306b1SToby Isaac PetscInt p; 15064de306b1SToby Isaac 15079566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 15084de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 15094de306b1SToby Isaac const PetscInt point = points[p]; 15104de306b1SToby Isaac 151163a3b9bcSJacob 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); 15129566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 15134de306b1SToby Isaac } 15144de306b1SToby Isaac } 15153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15164de306b1SToby Isaac } 15174de306b1SToby Isaac 151884f0b6dfSMatthew G. Knepley /*@ 151984f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 15204de306b1SToby Isaac 152120f4b53cSBarry Smith Not Collective 15225b5e7992SMatthew G. Knepley 152384f0b6dfSMatthew G. Knepley Input Parameters: 152420f4b53cSBarry Smith + label - the `DMLabel` 152584f0b6dfSMatthew G. Knepley - value - the stratum value 152684f0b6dfSMatthew G. Knepley 152784f0b6dfSMatthew G. Knepley Level: intermediate 152884f0b6dfSMatthew G. Knepley 152920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 153084f0b6dfSMatthew G. Knepley @*/ 1531d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1532d71ae5a4SJacob Faibussowitsch { 1533c58f1c22SToby Isaac PetscInt v; 1534c58f1c22SToby Isaac 1535c58f1c22SToby Isaac PetscFunctionBegin; 1536d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15379f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 15389566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15393ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15404de306b1SToby Isaac if (label->validIS[v]) { 15414de306b1SToby Isaac if (label->bt) { 1542c58f1c22SToby Isaac PetscInt i; 1543ad8374ffSToby Isaac const PetscInt *points; 1544c58f1c22SToby Isaac 15459566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1546c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1547ad8374ffSToby Isaac const PetscInt point = points[i]; 1548c58f1c22SToby Isaac 154963a3b9bcSJacob 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); 15509566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1551c58f1c22SToby Isaac } 15529566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1553c58f1c22SToby Isaac } 1554c58f1c22SToby Isaac label->stratumSizes[v] = 0; 15559566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 15569566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 15579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 15589566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1559c58f1c22SToby Isaac } else { 15609566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1561c58f1c22SToby Isaac } 15623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1563c58f1c22SToby Isaac } 1564c58f1c22SToby Isaac 156584f0b6dfSMatthew G. Knepley /*@ 1566412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1567412e9a14SMatthew G. Knepley 156820f4b53cSBarry Smith Not Collective 1569412e9a14SMatthew G. Knepley 1570412e9a14SMatthew G. Knepley Input Parameters: 157120f4b53cSBarry Smith + label - The `DMLabel` 1572412e9a14SMatthew G. Knepley . value - The label value for all points 1573412e9a14SMatthew G. Knepley . pStart - The first point 1574412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1575412e9a14SMatthew G. Knepley 1576412e9a14SMatthew G. Knepley Level: intermediate 1577412e9a14SMatthew G. Knepley 157820f4b53cSBarry Smith Note: 157920f4b53cSBarry Smith The marks points are [`pStart`, `pEnd`), and only the bounds are stored. 158020f4b53cSBarry Smith 158120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1582412e9a14SMatthew G. Knepley @*/ 1583d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1584d71ae5a4SJacob Faibussowitsch { 1585412e9a14SMatthew G. Knepley IS pIS; 1586412e9a14SMatthew G. Knepley 1587412e9a14SMatthew G. Knepley PetscFunctionBegin; 15889566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 15899566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 15909566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 15913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1592412e9a14SMatthew G. Knepley } 1593412e9a14SMatthew G. Knepley 1594412e9a14SMatthew G. Knepley /*@ 1595d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1596d123abd9SMatthew G. Knepley 159720f4b53cSBarry Smith Not Collective 1598d123abd9SMatthew G. Knepley 1599d123abd9SMatthew G. Knepley Input Parameters: 160020f4b53cSBarry Smith + label - The `DMLabel` 1601d123abd9SMatthew G. Knepley . value - The label value 1602d123abd9SMatthew G. Knepley - p - A point with this value 1603d123abd9SMatthew G. Knepley 1604d123abd9SMatthew G. Knepley Output Parameter: 1605d123abd9SMatthew 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 1606d123abd9SMatthew G. Knepley 1607d123abd9SMatthew G. Knepley Level: intermediate 1608d123abd9SMatthew G. Knepley 160920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1610d123abd9SMatthew G. Knepley @*/ 1611d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1612d71ae5a4SJacob Faibussowitsch { 16139f6c5813SMatthew G. Knepley IS pointIS; 1614d123abd9SMatthew G. Knepley const PetscInt *indices; 1615d123abd9SMatthew G. Knepley PetscInt v; 1616d123abd9SMatthew G. Knepley 1617d123abd9SMatthew G. Knepley PetscFunctionBegin; 1618d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16194f572ea9SToby Isaac PetscAssertPointer(index, 4); 1620d123abd9SMatthew G. Knepley *index = -1; 16219566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 16223ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 16239566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 16249f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 16259f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &indices)); 16269566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 16279f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(pointIS, &indices)); 16289f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 16293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1630d123abd9SMatthew G. Knepley } 1631d123abd9SMatthew G. Knepley 1632d123abd9SMatthew G. Knepley /*@ 163320f4b53cSBarry Smith DMLabelFilter - Remove all points outside of [`start`, `end`) 163484f0b6dfSMatthew G. Knepley 163520f4b53cSBarry Smith Not Collective 16365b5e7992SMatthew G. Knepley 163784f0b6dfSMatthew G. Knepley Input Parameters: 163820f4b53cSBarry Smith + label - the `DMLabel` 163922cd2cdaSVaclav Hapla . start - the first point kept 164022cd2cdaSVaclav Hapla - end - one more than the last point kept 164184f0b6dfSMatthew G. Knepley 164284f0b6dfSMatthew G. Knepley Level: intermediate 164384f0b6dfSMatthew G. Knepley 164420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 164584f0b6dfSMatthew G. Knepley @*/ 1646d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1647d71ae5a4SJacob Faibussowitsch { 1648c58f1c22SToby Isaac PetscInt v; 1649c58f1c22SToby Isaac 1650c58f1c22SToby Isaac PetscFunctionBegin; 1651d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16529f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16539566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 16549566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16559f6c5813SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 16569f6c5813SMatthew G. Knepley PetscCall(ISGeneralFilter(label->points[v], start, end)); 16579f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(label->points[v], &label->stratumSizes[v])); 16589f6c5813SMatthew G. Knepley } 16599566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 16603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1661c58f1c22SToby Isaac } 1662c58f1c22SToby Isaac 166384f0b6dfSMatthew G. Knepley /*@ 166484f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 166584f0b6dfSMatthew G. Knepley 166620f4b53cSBarry Smith Not Collective 16675b5e7992SMatthew G. Knepley 166884f0b6dfSMatthew G. Knepley Input Parameters: 166920f4b53cSBarry Smith + label - the `DMLabel` 167084f0b6dfSMatthew G. Knepley - permutation - the point permutation 167184f0b6dfSMatthew G. Knepley 167284f0b6dfSMatthew G. Knepley Output Parameter: 167360225df5SJacob Faibussowitsch . labelNew - the new label containing the permuted points 167484f0b6dfSMatthew G. Knepley 167584f0b6dfSMatthew G. Knepley Level: intermediate 167684f0b6dfSMatthew G. Knepley 167720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 167884f0b6dfSMatthew G. Knepley @*/ 1679d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1680d71ae5a4SJacob Faibussowitsch { 1681c58f1c22SToby Isaac const PetscInt *perm; 1682c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1683c58f1c22SToby Isaac 1684c58f1c22SToby Isaac PetscFunctionBegin; 1685d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1686d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 16879f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16889566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16899566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 16909566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 16919566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 16929566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1693c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1694c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1695ad8374ffSToby Isaac const PetscInt *points; 1696ad8374ffSToby Isaac PetscInt *pointsNew; 1697c58f1c22SToby Isaac 16989566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 16999f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(size, &pointsNew)); 1700c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1701ad8374ffSToby Isaac const PetscInt point = points[q]; 1702c58f1c22SToby Isaac 170363a3b9bcSJacob 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); 1704ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1705c58f1c22SToby Isaac } 17069566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 17079566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 17089566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1709fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 17109566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 17119566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1712fa8e8ae5SToby Isaac } else { 17139566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1714fa8e8ae5SToby Isaac } 17159566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1716c58f1c22SToby Isaac } 17179566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1718c58f1c22SToby Isaac if (label->bt) { 17199566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 17209566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1721c58f1c22SToby Isaac } 17223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1723c58f1c22SToby Isaac } 1724c58f1c22SToby Isaac 172566976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 1726d71ae5a4SJacob Faibussowitsch { 172726c55118SMichael Lange MPI_Comm comm; 1728eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 172926c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 173026c55118SMichael Lange PetscSection rootSection; 173126c55118SMichael Lange PetscSF labelSF; 173226c55118SMichael Lange 173326c55118SMichael Lange PetscFunctionBegin; 17349566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 173626c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 173726c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 17389566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 17409566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 174126c55118SMichael Lange if (label) { 174226c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1743ad8374ffSToby Isaac const PetscInt *points; 1744ad8374ffSToby Isaac 17459566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 174648a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 17479566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 174826c55118SMichael Lange } 174926c55118SMichael Lange } 17509566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 175126c55118SMichael Lange /* Create a point-wise array of stratum values */ 17529566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 17539566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 17549566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 175526c55118SMichael Lange if (label) { 175626c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1757ad8374ffSToby Isaac const PetscInt *points; 1758ad8374ffSToby Isaac 17599566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 176026c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1761ad8374ffSToby Isaac const PetscInt p = points[l]; 17629566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 176326c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 176426c55118SMichael Lange } 17659566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 176626c55118SMichael Lange } 176726c55118SMichael Lange } 176826c55118SMichael Lange /* Build SF that maps label points to remote processes */ 17699566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 17709566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 17719566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 17729566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 177326c55118SMichael Lange /* Send the strata for each point over the derived SF */ 17749566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 17759566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 17769566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 17779566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 177826c55118SMichael Lange /* Clean up */ 17799566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 17809566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 17819566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 17829566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 17833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 178426c55118SMichael Lange } 178526c55118SMichael Lange 178684f0b6dfSMatthew G. Knepley /*@ 178720f4b53cSBarry Smith DMLabelDistribute - Create a new label pushed forward over the `PetscSF` 178884f0b6dfSMatthew G. Knepley 178920f4b53cSBarry Smith Collective 17905b5e7992SMatthew G. Knepley 179184f0b6dfSMatthew G. Knepley Input Parameters: 179220f4b53cSBarry Smith + label - the `DMLabel` 179384f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 179484f0b6dfSMatthew G. Knepley 179584f0b6dfSMatthew G. Knepley Output Parameter: 179660225df5SJacob Faibussowitsch . labelNew - the new redistributed label 179784f0b6dfSMatthew G. Knepley 179884f0b6dfSMatthew G. Knepley Level: intermediate 179984f0b6dfSMatthew G. Knepley 180020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 180184f0b6dfSMatthew G. Knepley @*/ 1802d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1803d71ae5a4SJacob Faibussowitsch { 1804c58f1c22SToby Isaac MPI_Comm comm; 180526c55118SMichael Lange PetscSection leafSection; 180626c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 180726c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1808ad8374ffSToby Isaac PetscInt **points; 1809d67d17b1SMatthew G. Knepley const char *lname = NULL; 1810c58f1c22SToby Isaac char *name; 1811c58f1c22SToby Isaac PetscInt nameSize; 1812e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1813c58f1c22SToby Isaac size_t len = 0; 181426c55118SMichael Lange PetscMPIInt rank; 1815c58f1c22SToby Isaac 1816c58f1c22SToby Isaac PetscFunctionBegin; 1817d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1818f018e600SMatthew G. Knepley if (label) { 1819f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 18209f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 18219566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1822f018e600SMatthew G. Knepley } 18239566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 18249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1825c58f1c22SToby Isaac /* Bcast name */ 1826dd400576SPatrick Sanan if (rank == 0) { 18279566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 18289566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1829d67d17b1SMatthew G. Knepley } 18306497c311SBarry Smith nameSize = (PetscInt)len; 18319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 18329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 18339566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 18346497c311SBarry Smith PetscCallMPI(MPI_Bcast(name, (PetscMPIInt)(nameSize + 1), MPI_CHAR, 0, comm)); 18359566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 18369566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 183777d236dfSMichael Lange /* Bcast defaultValue */ 1838dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 18399566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 184026c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 18419566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 18425cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 18439566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 18449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 18459566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 18469566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 18479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1848ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 18499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 18505cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 18515cbdf6fcSMichael Lange offset = 0; 18529566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 18539566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 185448a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 18555cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1856231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 18579371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 18589371c9d4SSatish Balay leafStrata[p] = s; 18599371c9d4SSatish Balay break; 18609371c9d4SSatish Balay } 18615cbdf6fcSMichael Lange } 18625cbdf6fcSMichael Lange } 1863c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 18649566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 18659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1866c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18679566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18689566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1869ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1870c58f1c22SToby Isaac } 18719566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 18729f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 18739f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &points)); 1874c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 18759566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 1876f4f49eeaSPierre Jolivet PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &points[s])); 1877c58f1c22SToby Isaac } 1878c58f1c22SToby Isaac /* Insert points into new strata */ 18799566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 18809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1881c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1884c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1885c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1886ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1887c58f1c22SToby Isaac } 1888c58f1c22SToby Isaac } 1889ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1890f4f49eeaSPierre Jolivet PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &points[s][0], PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 18919566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1892ad8374ffSToby Isaac } 18939566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 18949566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 18959566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 18969566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 18979566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 18983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1899c58f1c22SToby Isaac } 1900c58f1c22SToby Isaac 19017937d9ceSMichael Lange /*@ 19027937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 19037937d9ceSMichael Lange 190420f4b53cSBarry Smith Collective 19055b5e7992SMatthew G. Knepley 19067937d9ceSMichael Lange Input Parameters: 190720f4b53cSBarry Smith + label - the `DMLabel` 190820f4b53cSBarry Smith - sf - the `PetscSF` communication map 19097937d9ceSMichael Lange 19102fe279fdSBarry Smith Output Parameter: 191120f4b53cSBarry Smith . labelNew - the new `DMLabel` with localised leaf values 19127937d9ceSMichael Lange 19137937d9ceSMichael Lange Level: developer 19147937d9ceSMichael Lange 191520f4b53cSBarry Smith Note: 191620f4b53cSBarry Smith This is the inverse operation to `DMLabelDistribute()`. 19177937d9ceSMichael Lange 191820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 19197937d9ceSMichael Lange @*/ 1920d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 1921d71ae5a4SJacob Faibussowitsch { 19227937d9ceSMichael Lange MPI_Comm comm; 19237937d9ceSMichael Lange PetscSection rootSection; 19247937d9ceSMichael Lange PetscSF sfLabel; 19257937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 19267937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 19277937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 19287937d9ceSMichael Lange PetscInt *rootStrata; 1929d67d17b1SMatthew G. Knepley const char *lname; 19307937d9ceSMichael Lange char *name; 19317937d9ceSMichael Lange PetscInt nameSize; 19327937d9ceSMichael Lange size_t len = 0; 19339852e123SBarry Smith PetscMPIInt rank, size; 19347937d9ceSMichael Lange 19357937d9ceSMichael Lange PetscFunctionBegin; 1936d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1937d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 19389f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 19399566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 19409566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 19419566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 19427937d9ceSMichael Lange /* Bcast name */ 1943dd400576SPatrick Sanan if (rank == 0) { 19449566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 19459566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1946d67d17b1SMatthew G. Knepley } 19476497c311SBarry Smith nameSize = (PetscInt)len; 19489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 19499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 19509566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 19516497c311SBarry Smith PetscCallMPI(MPI_Bcast(name, (PetscMPIInt)(nameSize + 1), MPI_CHAR, 0, comm)); 19529566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 19539566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 19547937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 19557937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 19567937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 19579566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 19589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1959dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 19607937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 19618212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 19628212dd46SStefano Zampini 19638212dd46SStefano Zampini leafPoints[ilp].index = ilp; 19648212dd46SStefano Zampini leafPoints[ilp].rank = rank; 19657937d9ceSMichael Lange } 19669566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 19679566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 19687937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 19699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 19706497c311SBarry Smith PetscCall(PetscSFGatherBegin(sf, MPIU_SF_NODE, leafPoints, rootPoints)); 19716497c311SBarry Smith PetscCall(PetscSFGatherEnd(sf, MPIU_SF_NODE, leafPoints, rootPoints)); 19729566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 19739566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 19747937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 19759566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 19767937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 19777937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 19787937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 19799566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 19809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 19819566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 19827937d9ceSMichael Lange } 19837937d9ceSMichael Lange idx += rootDegree[p]; 19847937d9ceSMichael Lange } 19859566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 19869566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 19879566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 19889566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 19893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19907937d9ceSMichael Lange } 19917937d9ceSMichael Lange 1992d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1993d71ae5a4SJacob Faibussowitsch { 1994d42890abSMatthew G. Knepley const PetscInt *degree; 1995d42890abSMatthew G. Knepley const PetscInt *points; 1996d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1997d42890abSMatthew G. Knepley 1998d42890abSMatthew G. Knepley PetscFunctionBegin; 1999d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2000d42890abSMatthew G. Knepley /* Add in leaves */ 2001d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 2002d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 2003d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 2004d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 2005d42890abSMatthew G. Knepley } 2006d42890abSMatthew G. Knepley /* Add in shared roots */ 2007d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2008d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2009d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2010d42890abSMatthew G. Knepley if (degree[r]) { 2011d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2012d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 2013d42890abSMatthew G. Knepley } 2014d42890abSMatthew G. Knepley } 20153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2016d42890abSMatthew G. Knepley } 2017d42890abSMatthew G. Knepley 2018d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 2019d71ae5a4SJacob Faibussowitsch { 2020d42890abSMatthew G. Knepley const PetscInt *degree; 2021d42890abSMatthew G. Knepley const PetscInt *points; 2022d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 2023d42890abSMatthew G. Knepley 2024d42890abSMatthew G. Knepley PetscFunctionBegin; 2025d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2026d42890abSMatthew G. Knepley /* Read out leaves */ 2027d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 2028d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 2029d42890abSMatthew G. Knepley const PetscInt p = points[l]; 2030d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 2031d42890abSMatthew G. Knepley 2032d42890abSMatthew G. Knepley if (cval != defVal) { 2033d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 2034d42890abSMatthew G. Knepley if (val == defVal) { 2035d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 203648a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 2037d42890abSMatthew G. Knepley } 2038d42890abSMatthew G. Knepley } 2039d42890abSMatthew G. Knepley } 2040d42890abSMatthew G. Knepley /* Read out shared roots */ 2041d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2042d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2043d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2044d42890abSMatthew G. Knepley if (degree[r]) { 2045d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 2046d42890abSMatthew G. Knepley 2047d42890abSMatthew G. Knepley if (cval != defVal) { 2048d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2049d42890abSMatthew G. Knepley if (val == defVal) { 2050d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 205148a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 2052d42890abSMatthew G. Knepley } 2053d42890abSMatthew G. Knepley } 2054d42890abSMatthew G. Knepley } 2055d42890abSMatthew G. Knepley } 20563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2057d42890abSMatthew G. Knepley } 2058d42890abSMatthew G. Knepley 2059d42890abSMatthew G. Knepley /*@ 2060d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 2061d42890abSMatthew G. Knepley 206220f4b53cSBarry Smith Collective 2063d42890abSMatthew G. Knepley 2064d42890abSMatthew G. Knepley Input Parameters: 206520f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 206620f4b53cSBarry Smith - sf - The `PetscSF` describing parallel layout of the label points 2067d42890abSMatthew G. Knepley 2068d42890abSMatthew G. Knepley Level: intermediate 2069d42890abSMatthew G. Knepley 207020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 2071d42890abSMatthew G. Knepley @*/ 2072d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 2073d71ae5a4SJacob Faibussowitsch { 2074d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 2075d42890abSMatthew G. Knepley PetscMPIInt size; 2076d42890abSMatthew G. Knepley 2077d42890abSMatthew G. Knepley PetscFunctionBegin; 20789f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2079d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 2080d42890abSMatthew G. Knepley if (size > 1) { 2081d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2082d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 2083d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 2084d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 2085d42890abSMatthew G. Knepley } 20863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2087d42890abSMatthew G. Knepley } 2088d42890abSMatthew G. Knepley 2089d42890abSMatthew G. Knepley /*@ 2090d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 2091d42890abSMatthew G. Knepley 209220f4b53cSBarry Smith Collective 2093d42890abSMatthew G. Knepley 2094d42890abSMatthew G. Knepley Input Parameters: 209520f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 209660225df5SJacob Faibussowitsch - pointSF - The `PetscSF` describing parallel layout of the label points 2097d42890abSMatthew G. Knepley 2098d42890abSMatthew G. Knepley Level: intermediate 2099d42890abSMatthew G. Knepley 210020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 2101d42890abSMatthew G. Knepley @*/ 2102d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 2103d71ae5a4SJacob Faibussowitsch { 2104d42890abSMatthew G. Knepley PetscFunctionBegin; 21059f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2106d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 2107d42890abSMatthew G. Knepley label->propArray = NULL; 21083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2109d42890abSMatthew G. Knepley } 2110d42890abSMatthew G. Knepley 2111d42890abSMatthew G. Knepley /*@C 2112d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 2113d42890abSMatthew G. Knepley 211420f4b53cSBarry Smith Collective 2115d42890abSMatthew G. Knepley 2116d42890abSMatthew G. Knepley Input Parameters: 211720f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 2118a4e35b19SJacob Faibussowitsch . pointSF - The `PetscSF` describing parallel layout of the label points 211920f4b53cSBarry Smith . markPoint - An optional callback that is called when a point is marked, or `NULL` 212020f4b53cSBarry Smith - ctx - An optional user context for the callback, or `NULL` 2121d42890abSMatthew G. Knepley 212220f4b53cSBarry Smith Calling sequence of `markPoint`: 212320f4b53cSBarry Smith + label - The `DMLabel` 2124d42890abSMatthew G. Knepley . p - The point being marked 2125a4e35b19SJacob Faibussowitsch . val - The label value for `p` 2126d42890abSMatthew G. Knepley - ctx - An optional user context 2127d42890abSMatthew G. Knepley 2128d42890abSMatthew G. Knepley Level: intermediate 2129d42890abSMatthew G. Knepley 213020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2131d42890abSMatthew G. Knepley @*/ 2132a4e35b19SJacob Faibussowitsch PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel label, PetscInt p, PetscInt val, void *ctx), void *ctx) 2133d71ae5a4SJacob Faibussowitsch { 2134c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2135d42890abSMatthew G. Knepley PetscMPIInt size; 2136d42890abSMatthew G. Knepley 2137d42890abSMatthew G. Knepley PetscFunctionBegin; 21389f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2139d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 2140c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2141c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2142d42890abSMatthew G. Knepley /* Communicate marked edges 2143d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2144d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2145d42890abSMatthew G. Knepley 2146d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2147d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2148d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2149d42890abSMatthew G. Knepley 2150d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2151d42890abSMatthew 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 2152d42890abSMatthew G. Knepley edge to the queue. 2153d42890abSMatthew G. Knepley */ 2154d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2155d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2156d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2157d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2158d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2159d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2160d42890abSMatthew G. Knepley } 21613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2162d42890abSMatthew G. Knepley } 2163d42890abSMatthew G. Knepley 216484f0b6dfSMatthew G. Knepley /*@ 216520f4b53cSBarry Smith DMLabelConvertToSection - Make a `PetscSection`/`IS` pair that encodes the label 216684f0b6dfSMatthew G. Knepley 216720f4b53cSBarry Smith Not Collective 21685b5e7992SMatthew G. Knepley 216984f0b6dfSMatthew G. Knepley Input Parameter: 217020f4b53cSBarry Smith . label - the `DMLabel` 217184f0b6dfSMatthew G. Knepley 217284f0b6dfSMatthew G. Knepley Output Parameters: 217384f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 217420f4b53cSBarry Smith - is - An `IS` containing all the label points 217584f0b6dfSMatthew G. Knepley 217684f0b6dfSMatthew G. Knepley Level: developer 217784f0b6dfSMatthew G. Knepley 217820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 217984f0b6dfSMatthew G. Knepley @*/ 2180d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2181d71ae5a4SJacob Faibussowitsch { 2182c58f1c22SToby Isaac IS vIS; 2183c58f1c22SToby Isaac const PetscInt *values; 2184c58f1c22SToby Isaac PetscInt *points; 2185c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2186c58f1c22SToby Isaac 2187c58f1c22SToby Isaac PetscFunctionBegin; 2188d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 21899566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 21909566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 21919566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 21929371c9d4SSatish Balay if (nV) { 21939371c9d4SSatish Balay vS = values[0]; 21949371c9d4SSatish Balay vE = values[0] + 1; 21959371c9d4SSatish Balay } 2196c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2197c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2198c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2199c58f1c22SToby Isaac } 22009566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 22019566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2202c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2203c58f1c22SToby Isaac PetscInt n; 2204c58f1c22SToby Isaac 22059566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 22069566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2207c58f1c22SToby Isaac } 22089566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 22099566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 22109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2211c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2212c58f1c22SToby Isaac IS is; 2213c58f1c22SToby Isaac const PetscInt *spoints; 2214c58f1c22SToby Isaac PetscInt dof, off, p; 2215c58f1c22SToby Isaac 22169566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 22179566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 22189566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 22199566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2220c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 22219566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 22229566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2223c58f1c22SToby Isaac } 22249566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 22259566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 22269566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 22273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2228c58f1c22SToby Isaac } 2229c58f1c22SToby Isaac 22309f6c5813SMatthew G. Knepley /*@C 22319f6c5813SMatthew G. Knepley DMLabelRegister - Adds a new label component implementation 22329f6c5813SMatthew G. Knepley 22339f6c5813SMatthew G. Knepley Not Collective 22349f6c5813SMatthew G. Knepley 22359f6c5813SMatthew G. Knepley Input Parameters: 22369f6c5813SMatthew G. Knepley + name - The name of a new user-defined creation routine 22379f6c5813SMatthew G. Knepley - create_func - The creation routine itself 22389f6c5813SMatthew G. Knepley 22399f6c5813SMatthew G. Knepley Notes: 22409f6c5813SMatthew G. Knepley `DMLabelRegister()` may be called multiple times to add several user-defined labels 22419f6c5813SMatthew G. Knepley 224260225df5SJacob Faibussowitsch Example Usage: 22439f6c5813SMatthew G. Knepley .vb 22449f6c5813SMatthew G. Knepley DMLabelRegister("my_label", MyLabelCreate); 22459f6c5813SMatthew G. Knepley .ve 22469f6c5813SMatthew G. Knepley 22479f6c5813SMatthew G. Knepley Then, your label type can be chosen with the procedural interface via 22489f6c5813SMatthew G. Knepley .vb 22499f6c5813SMatthew G. Knepley DMLabelCreate(MPI_Comm, DMLabel *); 22509f6c5813SMatthew G. Knepley DMLabelSetType(DMLabel, "my_label"); 22519f6c5813SMatthew G. Knepley .ve 22529f6c5813SMatthew G. Knepley or at runtime via the option 22539f6c5813SMatthew G. Knepley .vb 22549f6c5813SMatthew G. Knepley -dm_label_type my_label 22559f6c5813SMatthew G. Knepley .ve 22569f6c5813SMatthew G. Knepley 22579f6c5813SMatthew G. Knepley Level: advanced 22589f6c5813SMatthew G. Knepley 225960225df5SJacob Faibussowitsch .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelRegisterAll()`, `DMLabelRegisterDestroy()` 22609f6c5813SMatthew G. Knepley @*/ 22619f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegister(const char name[], PetscErrorCode (*create_func)(DMLabel)) 22629f6c5813SMatthew G. Knepley { 22639f6c5813SMatthew G. Knepley PetscFunctionBegin; 22649f6c5813SMatthew G. Knepley PetscCall(DMInitializePackage()); 22659f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListAdd(&DMLabelList, name, create_func)); 22663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22679f6c5813SMatthew G. Knepley } 22689f6c5813SMatthew G. Knepley 22699f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel); 22709f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel); 22719f6c5813SMatthew G. Knepley 22729f6c5813SMatthew G. Knepley /*@C 22739f6c5813SMatthew G. Knepley DMLabelRegisterAll - Registers all of the `DMLabel` implementations in the `DM` package. 22749f6c5813SMatthew G. Knepley 22759f6c5813SMatthew G. Knepley Not Collective 22769f6c5813SMatthew G. Knepley 22779f6c5813SMatthew G. Knepley Level: advanced 22789f6c5813SMatthew G. Knepley 227920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMRegisterAll()`, `DMLabelRegisterDestroy()` 22809f6c5813SMatthew G. Knepley @*/ 22819f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterAll(void) 22829f6c5813SMatthew G. Knepley { 22839f6c5813SMatthew G. Knepley PetscFunctionBegin; 22843ba16761SJacob Faibussowitsch if (DMLabelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 22859f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_TRUE; 22869f6c5813SMatthew G. Knepley 22879f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELCONCRETE, DMLabelCreate_Concrete)); 22889f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELEPHEMERAL, DMLabelCreate_Ephemeral)); 22893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22909f6c5813SMatthew G. Knepley } 22919f6c5813SMatthew G. Knepley 22929f6c5813SMatthew G. Knepley /*@C 22939f6c5813SMatthew G. Knepley DMLabelRegisterDestroy - This function destroys the `DMLabel` registry. It is called from `PetscFinalize()`. 22949f6c5813SMatthew G. Knepley 22959f6c5813SMatthew G. Knepley Level: developer 22969f6c5813SMatthew G. Knepley 229720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscInitialize()` 22989f6c5813SMatthew G. Knepley @*/ 22999f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterDestroy(void) 23009f6c5813SMatthew G. Knepley { 23019f6c5813SMatthew G. Knepley PetscFunctionBegin; 23029f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMLabelList)); 23039f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_FALSE; 23043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23059f6c5813SMatthew G. Knepley } 23069f6c5813SMatthew G. Knepley 2307cc4c1da9SBarry Smith /*@ 23089f6c5813SMatthew G. Knepley DMLabelSetType - Sets the particular implementation for a label. 23099f6c5813SMatthew G. Knepley 231020f4b53cSBarry Smith Collective 23119f6c5813SMatthew G. Knepley 23129f6c5813SMatthew G. Knepley Input Parameters: 23139f6c5813SMatthew G. Knepley + label - The label 23149f6c5813SMatthew G. Knepley - method - The name of the label type 23159f6c5813SMatthew G. Knepley 23169f6c5813SMatthew G. Knepley Options Database Key: 231720f4b53cSBarry Smith . -dm_label_type <type> - Sets the label type; use -help for a list of available types or see `DMLabelType` 23189f6c5813SMatthew G. Knepley 23199f6c5813SMatthew G. Knepley Level: intermediate 23209f6c5813SMatthew G. Knepley 232120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetType()`, `DMLabelCreate()` 23229f6c5813SMatthew G. Knepley @*/ 23239f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetType(DMLabel label, DMLabelType method) 23249f6c5813SMatthew G. Knepley { 23259f6c5813SMatthew G. Knepley PetscErrorCode (*r)(DMLabel); 23269f6c5813SMatthew G. Knepley PetscBool match; 23279f6c5813SMatthew G. Knepley 23289f6c5813SMatthew G. Knepley PetscFunctionBegin; 23299f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23309f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)label, method, &match)); 23313ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 23329f6c5813SMatthew G. Knepley 23339f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23349f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListFind(DMLabelList, method, &r)); 23359f6c5813SMatthew G. Knepley PetscCheck(r, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMLabel type: %s", method); 23369f6c5813SMatthew G. Knepley 23379f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, destroy); 23389f6c5813SMatthew G. Knepley PetscCall(PetscMemzero(label->ops, sizeof(*label->ops))); 23399f6c5813SMatthew G. Knepley PetscCall(PetscObjectChangeTypeName((PetscObject)label, method)); 23409f6c5813SMatthew G. Knepley PetscCall((*r)(label)); 23413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23429f6c5813SMatthew G. Knepley } 23439f6c5813SMatthew G. Knepley 2344cc4c1da9SBarry Smith /*@ 23459f6c5813SMatthew G. Knepley DMLabelGetType - Gets the type name (as a string) from the label. 23469f6c5813SMatthew G. Knepley 23479f6c5813SMatthew G. Knepley Not Collective 23489f6c5813SMatthew G. Knepley 23499f6c5813SMatthew G. Knepley Input Parameter: 235020f4b53cSBarry Smith . label - The `DMLabel` 23519f6c5813SMatthew G. Knepley 23529f6c5813SMatthew G. Knepley Output Parameter: 235320f4b53cSBarry Smith . type - The `DMLabel` type name 23549f6c5813SMatthew G. Knepley 23559f6c5813SMatthew G. Knepley Level: intermediate 23569f6c5813SMatthew G. Knepley 235720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetType()`, `DMLabelCreate()` 23589f6c5813SMatthew G. Knepley @*/ 23599f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetType(DMLabel label, DMLabelType *type) 23609f6c5813SMatthew G. Knepley { 23619f6c5813SMatthew G. Knepley PetscFunctionBegin; 23629f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23634f572ea9SToby Isaac PetscAssertPointer(type, 2); 23649f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23659f6c5813SMatthew G. Knepley *type = ((PetscObject)label)->type_name; 23663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23679f6c5813SMatthew G. Knepley } 23689f6c5813SMatthew G. Knepley 23699f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Concrete(DMLabel label) 23709f6c5813SMatthew G. Knepley { 23719f6c5813SMatthew G. Knepley PetscFunctionBegin; 23729f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Concrete; 23739f6c5813SMatthew G. Knepley label->ops->setup = NULL; 23749f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Concrete; 23759f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Concrete; 23763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23779f6c5813SMatthew G. Knepley } 23789f6c5813SMatthew G. Knepley 23799f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel label) 23809f6c5813SMatthew G. Knepley { 23819f6c5813SMatthew G. Knepley PetscFunctionBegin; 23829f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23839f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Concrete(label)); 23843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23859f6c5813SMatthew G. Knepley } 23869f6c5813SMatthew G. Knepley 238784f0b6dfSMatthew G. Knepley /*@ 2388c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 238920f4b53cSBarry Smith the local section and an `PetscSF` describing the section point overlap. 2390c58f1c22SToby Isaac 239120f4b53cSBarry Smith Collective 23925b5e7992SMatthew G. Knepley 2393c58f1c22SToby Isaac Input Parameters: 239420f4b53cSBarry Smith + s - The `PetscSection` for the local field layout 239520f4b53cSBarry Smith . sf - The `PetscSF` describing parallel layout of the section points 239620f4b53cSBarry Smith . includeConstraints - By default this is `PETSC_FALSE`, meaning that the global field vector will not possess constrained dofs 2397c58f1c22SToby Isaac . label - The label specifying the points 2398c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2399c58f1c22SToby Isaac 2400c58f1c22SToby Isaac Output Parameter: 240120f4b53cSBarry Smith . gsection - The `PetscSection` for the global field layout 2402c58f1c22SToby Isaac 2403c58f1c22SToby Isaac Level: developer 2404c58f1c22SToby Isaac 240520f4b53cSBarry Smith Note: 240620f4b53cSBarry Smith This gives negative sizes and offsets to points not owned by this process 240720f4b53cSBarry Smith 240820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionCreate()` 2409c58f1c22SToby Isaac @*/ 2410d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2411d71ae5a4SJacob Faibussowitsch { 2412c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2413c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2414c58f1c22SToby Isaac 2415c58f1c22SToby Isaac PetscFunctionBegin; 2416d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2417d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2418d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 24199566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 24209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 24219566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 24229566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2423c58f1c22SToby Isaac if (nroots >= 0) { 242463a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 24259566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2426c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24279566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2428c58f1c22SToby Isaac } else { 2429c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2430c58f1c22SToby Isaac } 2431c58f1c22SToby Isaac } 2432c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2433c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2434c58f1c22SToby Isaac PetscInt value; 2435c58f1c22SToby Isaac 24369566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2437c58f1c22SToby Isaac if (value != labelValue) continue; 24389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 24399566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 24409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 24419566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2442c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2443c58f1c22SToby Isaac } 24449566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2445c58f1c22SToby Isaac if (nroots >= 0) { 24469566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24479566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2448c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24499371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24509371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 24519371c9d4SSatish Balay } 2452c58f1c22SToby Isaac } 2453c58f1c22SToby Isaac } 245435cb6cd3SPierre Jolivet /* Calculate new sizes, get process offset, and calculate point offsets */ 2455c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2456c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2457c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2458c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2459c58f1c22SToby Isaac } 24609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2461c58f1c22SToby Isaac globalOff -= off; 2462c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2463c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2464c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2465c58f1c22SToby Isaac } 2466c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2467c58f1c22SToby Isaac if (nroots >= 0) { 24689566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24699566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2470c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24719371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24729371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 24739371c9d4SSatish Balay } 2474c58f1c22SToby Isaac } 2475c58f1c22SToby Isaac } 24769566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 24779566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 24783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2479c58f1c22SToby Isaac } 2480c58f1c22SToby Isaac 24819371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 24825fdea053SToby Isaac DMLabel label; 24835fdea053SToby Isaac PetscCopyMode *modes; 24845fdea053SToby Isaac PetscInt *sizes; 24855fdea053SToby Isaac const PetscInt ***perms; 24865fdea053SToby Isaac const PetscScalar ***rots; 24875fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 24885fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 24895fdea053SToby Isaac } PetscSectionSym_Label; 24905fdea053SToby Isaac 2491d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 2492d71ae5a4SJacob Faibussowitsch { 24935fdea053SToby Isaac PetscInt i, j; 24945fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24955fdea053SToby Isaac 24965fdea053SToby Isaac PetscFunctionBegin; 24975fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24985fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 24995fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 25009566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 25019566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 25025fdea053SToby Isaac } 25035fdea053SToby Isaac if (sl->perms[i]) { 25045fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 25055fdea053SToby Isaac 25069566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 25075fdea053SToby Isaac } 25085fdea053SToby Isaac if (sl->rots[i]) { 25095fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 25105fdea053SToby Isaac 25119566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 25125fdea053SToby Isaac } 25135fdea053SToby Isaac } 25145fdea053SToby Isaac } 25159566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 25169566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 25175fdea053SToby Isaac sl->numStrata = 0; 25183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25195fdea053SToby Isaac } 25205fdea053SToby Isaac 2521d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 2522d71ae5a4SJacob Faibussowitsch { 25235fdea053SToby Isaac PetscFunctionBegin; 25249566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 25259566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 25263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25275fdea053SToby Isaac } 25285fdea053SToby Isaac 2529d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 2530d71ae5a4SJacob Faibussowitsch { 25315fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 25325fdea053SToby Isaac PetscBool isAscii; 25335fdea053SToby Isaac DMLabel label = sl->label; 2534d67d17b1SMatthew G. Knepley const char *name; 25355fdea053SToby Isaac 25365fdea053SToby Isaac PetscFunctionBegin; 25379566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 25385fdea053SToby Isaac if (isAscii) { 25395fdea053SToby Isaac PetscInt i, j, k; 25405fdea053SToby Isaac PetscViewerFormat format; 25415fdea053SToby Isaac 25429566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25435fdea053SToby Isaac if (label) { 25449566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25455fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25479566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 25489566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25495fdea053SToby Isaac } else { 25509566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 25519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 25525fdea053SToby Isaac } 25535fdea053SToby Isaac } else { 25549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 25555fdea053SToby Isaac } 25569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25575fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 25585fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 25595fdea053SToby Isaac 25605fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 256163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 25625fdea053SToby Isaac } else { 256363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 25649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 256563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 25665fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25685fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 25695fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 257063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 25715fdea053SToby Isaac } else { 25725fdea053SToby Isaac PetscInt tab; 25735fdea053SToby Isaac 257463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 25759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 25775fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 25789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 25799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 258063a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 25819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25835fdea053SToby Isaac } 25845fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 25859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 25869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 25875fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 258863a3b9bcSJacob 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]))); 25895fdea053SToby Isaac #else 259063a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 25915fdea053SToby Isaac #endif 25929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25945fdea053SToby Isaac } 25959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25965fdea053SToby Isaac } 25975fdea053SToby Isaac } 25989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25995fdea053SToby Isaac } 26009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 26015fdea053SToby Isaac } 26025fdea053SToby Isaac } 26039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 26045fdea053SToby Isaac } 26053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26065fdea053SToby Isaac } 26075fdea053SToby Isaac 26085fdea053SToby Isaac /*@ 26095fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 26105fdea053SToby Isaac 261120f4b53cSBarry Smith Logically 26125fdea053SToby Isaac 261360225df5SJacob Faibussowitsch Input Parameters: 26145fdea053SToby Isaac + sym - the section symmetries 261520f4b53cSBarry Smith - label - the `DMLabel` describing the types of points 26165fdea053SToby Isaac 26175fdea053SToby Isaac Level: developer: 26185fdea053SToby Isaac 261920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 26205fdea053SToby Isaac @*/ 2621d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 2622d71ae5a4SJacob Faibussowitsch { 26235fdea053SToby Isaac PetscSectionSym_Label *sl; 26245fdea053SToby Isaac 26255fdea053SToby Isaac PetscFunctionBegin; 26265fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 26275fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 26289566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 26295fdea053SToby Isaac if (label) { 26305fdea053SToby Isaac sl->label = label; 26319566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 26329566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 26339566063dSJacob 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)); 26349566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 26359566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 26369566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 26379566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 26389566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 26395fdea053SToby Isaac } 26403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26415fdea053SToby Isaac } 26425fdea053SToby Isaac 26435fdea053SToby Isaac /*@C 2644b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2645b004864fSMatthew G. Knepley 264620f4b53cSBarry Smith Logically Collective 2647b004864fSMatthew G. Knepley 2648b004864fSMatthew G. Knepley Input Parameters: 2649b004864fSMatthew G. Knepley + sym - the section symmetries 2650b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2651b004864fSMatthew G. Knepley 2652b004864fSMatthew G. Knepley Output Parameters: 265320f4b53cSBarry Smith + size - the number of dofs for points in the `stratum` of the label 265420f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 265520f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a ppoint in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 265620f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 265720f4b53cSBarry 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 2658b004864fSMatthew G. Knepley 2659b004864fSMatthew G. Knepley Level: developer 2660b004864fSMatthew G. Knepley 266120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2662b004864fSMatthew G. Knepley @*/ 2663d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2664d71ae5a4SJacob Faibussowitsch { 2665b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2666b004864fSMatthew G. Knepley const char *name; 2667b004864fSMatthew G. Knepley PetscInt i; 2668b004864fSMatthew G. Knepley 2669b004864fSMatthew G. Knepley PetscFunctionBegin; 2670b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2671b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2672b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2673b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2674b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2675b004864fSMatthew G. Knepley 2676b004864fSMatthew G. Knepley if (stratum == value) break; 2677b004864fSMatthew G. Knepley } 26789566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2679b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 26809371c9d4SSatish Balay if (size) { 26814f572ea9SToby Isaac PetscAssertPointer(size, 3); 26829371c9d4SSatish Balay *size = sl->sizes[i]; 26839371c9d4SSatish Balay } 26849371c9d4SSatish Balay if (minOrient) { 26854f572ea9SToby Isaac PetscAssertPointer(minOrient, 4); 26869371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 26879371c9d4SSatish Balay } 26889371c9d4SSatish Balay if (maxOrient) { 26894f572ea9SToby Isaac PetscAssertPointer(maxOrient, 5); 26909371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 26919371c9d4SSatish Balay } 26929371c9d4SSatish Balay if (perms) { 26934f572ea9SToby Isaac PetscAssertPointer(perms, 6); 26948e3a54c0SPierre Jolivet *perms = PetscSafePointerPlusOffset(sl->perms[i], sl->minMaxOrients[i][0]); 26959371c9d4SSatish Balay } 26969371c9d4SSatish Balay if (rots) { 26974f572ea9SToby Isaac PetscAssertPointer(rots, 7); 26988e3a54c0SPierre Jolivet *rots = PetscSafePointerPlusOffset(sl->rots[i], sl->minMaxOrients[i][0]); 26999371c9d4SSatish Balay } 27003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2701b004864fSMatthew G. Knepley } 2702b004864fSMatthew G. Knepley 2703b004864fSMatthew G. Knepley /*@C 27045fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 27055fdea053SToby Isaac 270620f4b53cSBarry Smith Logically 27075fdea053SToby Isaac 27085fdea053SToby Isaac Input Parameters: 27095b5e7992SMatthew G. Knepley + sym - the section symmetries 27105fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 271120f4b53cSBarry Smith . size - the number of dofs for points in the `stratum` of the label 271220f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 271320f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a point in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 271420f4b53cSBarry Smith . mode - how `sym` should copy the `perms` and `rots` arrays 271520f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 271620f4b53cSBarry 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 27175fdea053SToby Isaac 27185fdea053SToby Isaac Level: developer 27195fdea053SToby Isaac 272020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 27215fdea053SToby Isaac @*/ 2722d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 2723d71ae5a4SJacob Faibussowitsch { 27245fdea053SToby Isaac PetscSectionSym_Label *sl; 2725d67d17b1SMatthew G. Knepley const char *name; 2726d67d17b1SMatthew G. Knepley PetscInt i, j, k; 27275fdea053SToby Isaac 27285fdea053SToby Isaac PetscFunctionBegin; 27295fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 27305fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2731b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 27325fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 27335fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 27345fdea053SToby Isaac 27355fdea053SToby Isaac if (stratum == value) break; 27365fdea053SToby Isaac } 27379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 273863a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 27395fdea053SToby Isaac sl->sizes[i] = size; 27405fdea053SToby Isaac sl->modes[i] = mode; 27415fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 27425fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 27435fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 27445fdea053SToby Isaac if (perms) { 27455fdea053SToby Isaac PetscInt **ownPerms; 27465fdea053SToby Isaac 27479566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 27485fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27495fdea053SToby Isaac if (perms[j]) { 27509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2751ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 27525fdea053SToby Isaac } 27535fdea053SToby Isaac } 27545fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 27555fdea053SToby Isaac } 27565fdea053SToby Isaac if (rots) { 27575fdea053SToby Isaac PetscScalar **ownRots; 27585fdea053SToby Isaac 27599566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 27605fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27615fdea053SToby Isaac if (rots[j]) { 27629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2763ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 27645fdea053SToby Isaac } 27655fdea053SToby Isaac } 27665fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 27675fdea053SToby Isaac } 27685fdea053SToby Isaac } else { 27698e3a54c0SPierre Jolivet sl->perms[i] = PetscSafePointerPlusOffset(perms, -minOrient); 27708e3a54c0SPierre Jolivet sl->rots[i] = PetscSafePointerPlusOffset(rots, -minOrient); 27715fdea053SToby Isaac } 27723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27735fdea053SToby Isaac } 27745fdea053SToby Isaac 2775d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 2776d71ae5a4SJacob Faibussowitsch { 27775fdea053SToby Isaac PetscInt i, j, numStrata; 27785fdea053SToby Isaac PetscSectionSym_Label *sl; 27795fdea053SToby Isaac DMLabel label; 27805fdea053SToby Isaac 27815fdea053SToby Isaac PetscFunctionBegin; 27825fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 27835fdea053SToby Isaac numStrata = sl->numStrata; 27845fdea053SToby Isaac label = sl->label; 27855fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 27865fdea053SToby Isaac PetscInt point = points[2 * i]; 27875fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 27885fdea053SToby Isaac 27895fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 27905fdea053SToby Isaac if (label->validIS[j]) { 27915fdea053SToby Isaac PetscInt k; 27925fdea053SToby Isaac 27932b4d18a0SMatthew G. Knepley PetscCall(ISLocate(label->points[j], point, &k)); 27945fdea053SToby Isaac if (k >= 0) break; 27955fdea053SToby Isaac } else { 27965fdea053SToby Isaac PetscBool has; 27975fdea053SToby Isaac 27989566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 27995fdea053SToby Isaac if (has) break; 28005fdea053SToby Isaac } 28015fdea053SToby Isaac } 28029371c9d4SSatish 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], 28039371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2804ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2805ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 28065fdea053SToby Isaac } 28073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28085fdea053SToby Isaac } 28095fdea053SToby Isaac 2810d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2811d71ae5a4SJacob Faibussowitsch { 2812b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2813b004864fSMatthew G. Knepley IS valIS; 2814b004864fSMatthew G. Knepley const PetscInt *values; 2815b004864fSMatthew G. Knepley PetscInt Nv, v; 2816b004864fSMatthew G. Knepley 2817b004864fSMatthew G. Knepley PetscFunctionBegin; 28189566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 28199566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 28209566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2821b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2822b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2823b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2824b004864fSMatthew G. Knepley const PetscInt **perms; 2825b004864fSMatthew G. Knepley const PetscScalar **rots; 2826b004864fSMatthew G. Knepley 28279566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 28289566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2829b004864fSMatthew G. Knepley } 28309566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 28313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2832b004864fSMatthew G. Knepley } 2833b004864fSMatthew G. Knepley 2834d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2835d71ae5a4SJacob Faibussowitsch { 2836b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2837b004864fSMatthew G. Knepley DMLabel dlabel; 2838b004864fSMatthew G. Knepley 2839b004864fSMatthew G. Knepley PetscFunctionBegin; 28409566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 28419566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 28429566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 28439566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 28443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2845b004864fSMatthew G. Knepley } 2846b004864fSMatthew G. Knepley 2847d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 2848d71ae5a4SJacob Faibussowitsch { 28495fdea053SToby Isaac PetscSectionSym_Label *sl; 28505fdea053SToby Isaac 28515fdea053SToby Isaac PetscFunctionBegin; 28524dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 28535fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2854b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2855b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 28565fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 28575fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 28585fdea053SToby Isaac sym->data = (void *)sl; 28593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28605fdea053SToby Isaac } 28615fdea053SToby Isaac 28625fdea053SToby Isaac /*@ 28635fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 28645fdea053SToby Isaac 28655fdea053SToby Isaac Collective 28665fdea053SToby Isaac 28675fdea053SToby Isaac Input Parameters: 28685fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 28695fdea053SToby Isaac - label - the label defining the strata 28705fdea053SToby Isaac 28712fe279fdSBarry Smith Output Parameter: 28725fdea053SToby Isaac . sym - the section symmetries 28735fdea053SToby Isaac 28745fdea053SToby Isaac Level: developer 28755fdea053SToby Isaac 287620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 28775fdea053SToby Isaac @*/ 2878d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 2879d71ae5a4SJacob Faibussowitsch { 28805fdea053SToby Isaac PetscFunctionBegin; 28819566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 28829566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 28839566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 28849566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 28853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28865fdea053SToby Isaac } 2887