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 } 115f622de60SMatthew G. Knepley PetscCall(ISSetInfo(is, IS_SORTED, IS_LOCAL, PETSC_TRUE, PETSC_TRUE)); 1169566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)is, "indices")); 117277ea44aSLisandro Dalcin label->points[v] = is; 118ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 1199566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 121c58f1c22SToby Isaac } 122c58f1c22SToby Isaac 123c58f1c22SToby Isaac /* 124c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 125c58f1c22SToby Isaac 12620f4b53cSBarry Smith Not Collective 1275b5e7992SMatthew G. Knepley 128c58f1c22SToby Isaac Input parameter: 12920f4b53cSBarry Smith . label - The `DMLabel` 130c58f1c22SToby Isaac 131c58f1c22SToby Isaac Output parameter: 13220f4b53cSBarry Smith . label - The `DMLabel` with all strata in sorted list format 133c58f1c22SToby Isaac 134c58f1c22SToby Isaac Level: developer 135c58f1c22SToby Isaac 13620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()` 137c58f1c22SToby Isaac */ 138d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 139d71ae5a4SJacob Faibussowitsch { 140c58f1c22SToby Isaac PetscInt v; 141c58f1c22SToby Isaac 142c58f1c22SToby Isaac PetscFunctionBegin; 14348a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeValid_Private(label, v)); 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 145c58f1c22SToby Isaac } 146c58f1c22SToby Isaac 147c58f1c22SToby Isaac /* 148c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 149c58f1c22SToby Isaac 15020f4b53cSBarry Smith Not Collective 1515b5e7992SMatthew G. Knepley 152c58f1c22SToby Isaac Input parameter: 15320f4b53cSBarry Smith + label - The `DMLabel` 154c58f1c22SToby Isaac - v - The stratum value 155c58f1c22SToby Isaac 156c58f1c22SToby Isaac Output parameter: 15720f4b53cSBarry Smith . label - The `DMLabel` with stratum in hash format 158c58f1c22SToby Isaac 159c58f1c22SToby Isaac Level: developer 160c58f1c22SToby Isaac 16120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()` 162c58f1c22SToby Isaac */ 163d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 164d71ae5a4SJacob Faibussowitsch { 165c58f1c22SToby Isaac PetscInt p; 166ad8374ffSToby Isaac const PetscInt *points; 167c58f1c22SToby Isaac 168c58f1c22SToby Isaac PetscFunctionBegin; 1694d86920dSPierre Jolivet if ((PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) || label->readonly) PetscFunctionReturn(PETSC_SUCCESS); 1701dca8a05SBarry Smith PetscCheck(v >= 0 && v < label->numStrata, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %" PetscInt_FMT " in DMLabelMakeInvalid_Private", v); 171ad8374ffSToby Isaac if (label->points[v]) { 1729566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 17348a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 1749566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 175f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 176ad8374ffSToby Isaac } 177ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 179c58f1c22SToby Isaac } 180c58f1c22SToby Isaac 181d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelMakeAllInvalid_Internal(DMLabel label) 182d71ae5a4SJacob Faibussowitsch { 183695799ffSMatthew G. Knepley PetscInt v; 184695799ffSMatthew G. Knepley 185695799ffSMatthew G. Knepley PetscFunctionBegin; 18648a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeInvalid_Private(label, v)); 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 188695799ffSMatthew G. Knepley } 189695799ffSMatthew G. Knepley 190b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 191b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 192b9907514SLisandro Dalcin #endif 193b9907514SLisandro Dalcin 1949f6c5813SMatthew G. Knepley PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 195d71ae5a4SJacob Faibussowitsch { 1960c3c4a36SLisandro Dalcin PetscInt v; 1970e79e033SBarry Smith 1980c3c4a36SLisandro Dalcin PetscFunctionBegin; 1990e79e033SBarry Smith *index = -1; 2009f6c5813SMatthew G. Knepley if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD || label->readonly) { 201b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2029371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2039371c9d4SSatish Balay *index = v; 2049371c9d4SSatish Balay break; 2059371c9d4SSatish Balay } 206b9907514SLisandro Dalcin } else { 2079566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index)); 2080e79e033SBarry Smith } 2099f6c5813SMatthew G. Knepley if (PetscDefined(USE_DEBUG) && !label->readonly) { /* Check strata hash map consistency */ 21090e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 2119566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len)); 21208401ef6SPierre Jolivet PetscCheck(len == label->numStrata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 21390e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 2149566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc)); 21590e9b2aeSLisandro Dalcin } else { 21690e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2179371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2189371c9d4SSatish Balay loc = v; 2199371c9d4SSatish Balay break; 2209371c9d4SSatish Balay } 22190e9b2aeSLisandro Dalcin } 22208401ef6SPierre Jolivet PetscCheck(loc == *index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 22390e9b2aeSLisandro Dalcin } 2243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2250c3c4a36SLisandro Dalcin } 2260c3c4a36SLisandro Dalcin 227d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 228d71ae5a4SJacob Faibussowitsch { 229b9907514SLisandro Dalcin PetscInt v; 230b9907514SLisandro Dalcin PetscInt *tmpV; 231b9907514SLisandro Dalcin PetscInt *tmpS; 232b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 233b9907514SLisandro Dalcin IS *tmpP, is; 234c58f1c22SToby Isaac PetscBool *tmpB; 235b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 236c58f1c22SToby Isaac 237c58f1c22SToby Isaac PetscFunctionBegin; 238b9907514SLisandro Dalcin v = label->numStrata; 239b9907514SLisandro Dalcin tmpV = label->stratumValues; 240b9907514SLisandro Dalcin tmpS = label->stratumSizes; 241b9907514SLisandro Dalcin tmpH = label->ht; 242b9907514SLisandro Dalcin tmpP = label->points; 243b9907514SLisandro Dalcin tmpB = label->validIS; 2448e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2458e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2468e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2478e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2488e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2498e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2509566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpV), &tmpV)); 2519566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpS), &tmpS)); 2529f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpH), &tmpH)); 2539f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpP), &tmpP)); 2549566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpB), &tmpB)); 2559566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v)); 2569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v)); 2579566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v)); 2589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v)); 2599566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v)); 2609566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV)); 2619566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS)); 2629566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH)); 2639566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP)); 2649566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB)); 2658e1f8cf0SLisandro Dalcin } 266b9907514SLisandro Dalcin label->numStrata = v + 1; 267c58f1c22SToby Isaac label->stratumValues = tmpV; 268c58f1c22SToby Isaac label->stratumSizes = tmpS; 269c58f1c22SToby Isaac label->ht = tmpH; 270c58f1c22SToby Isaac label->points = tmpP; 271ad8374ffSToby Isaac label->validIS = tmpB; 2729566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 2739566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 2749566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v)); 275b9907514SLisandro Dalcin tmpV[v] = value; 276b9907514SLisandro Dalcin tmpS[v] = 0; 277b9907514SLisandro Dalcin tmpH[v] = ht; 278b9907514SLisandro Dalcin tmpP[v] = is; 279b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 2809566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 2810c3c4a36SLisandro Dalcin *index = v; 2823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2830c3c4a36SLisandro Dalcin } 2840c3c4a36SLisandro Dalcin 285d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 286d71ae5a4SJacob Faibussowitsch { 287b9907514SLisandro Dalcin PetscFunctionBegin; 2889566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index)); 2899566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index)); 2903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 291b9907514SLisandro Dalcin } 292b9907514SLisandro Dalcin 2939f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) 294d71ae5a4SJacob Faibussowitsch { 2959e63cc69SVaclav Hapla PetscFunctionBegin; 2969e63cc69SVaclav Hapla *size = 0; 2973ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 2989f6c5813SMatthew G. Knepley if (label->readonly || label->validIS[v]) { 2999e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 3009e63cc69SVaclav Hapla } else { 3019566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size)); 3029e63cc69SVaclav Hapla } 3033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3049e63cc69SVaclav Hapla } 3059e63cc69SVaclav Hapla 306b9907514SLisandro Dalcin /*@ 30720f4b53cSBarry Smith DMLabelAddStratum - Adds a new stratum value in a `DMLabel` 308b9907514SLisandro Dalcin 309d8d19677SJose E. Roman Input Parameters: 31020f4b53cSBarry Smith + label - The `DMLabel` 311b9907514SLisandro Dalcin - value - The stratum value 312b9907514SLisandro Dalcin 313b9907514SLisandro Dalcin Level: beginner 314b9907514SLisandro Dalcin 31520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 316b9907514SLisandro Dalcin @*/ 317d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 318d71ae5a4SJacob Faibussowitsch { 3190c3c4a36SLisandro Dalcin PetscInt v; 3200c3c4a36SLisandro Dalcin 3210c3c4a36SLisandro Dalcin PetscFunctionBegin; 322d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3239f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3249566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 3253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 326b9907514SLisandro Dalcin } 327b9907514SLisandro Dalcin 328b9907514SLisandro Dalcin /*@ 32920f4b53cSBarry Smith DMLabelAddStrata - Adds new stratum values in a `DMLabel` 330b9907514SLisandro Dalcin 33120f4b53cSBarry Smith Not Collective 3325b5e7992SMatthew G. Knepley 333d8d19677SJose E. Roman Input Parameters: 33420f4b53cSBarry Smith + label - The `DMLabel` 335b9907514SLisandro Dalcin . numStrata - The number of stratum values 336b9907514SLisandro Dalcin - stratumValues - The stratum values 337b9907514SLisandro Dalcin 338b9907514SLisandro Dalcin Level: beginner 339b9907514SLisandro Dalcin 34020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 341b9907514SLisandro Dalcin @*/ 342d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 343d71ae5a4SJacob Faibussowitsch { 344b9907514SLisandro Dalcin PetscInt *values, v; 345b9907514SLisandro Dalcin 346b9907514SLisandro Dalcin PetscFunctionBegin; 347b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3484f572ea9SToby Isaac if (numStrata) PetscAssertPointer(stratumValues, 3); 3499f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &values)); 3519566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(values, stratumValues, numStrata)); 3529566063dSJacob Faibussowitsch PetscCall(PetscSortRemoveDupsInt(&numStrata, values)); 353b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 354b9907514SLisandro Dalcin PetscInt *tmpV; 355b9907514SLisandro Dalcin PetscInt *tmpS; 356b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 357b9907514SLisandro Dalcin IS *tmpP, is; 358b9907514SLisandro Dalcin PetscBool *tmpB; 359b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 360b9907514SLisandro Dalcin 3619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpV)); 3629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpS)); 3639f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpH)); 3649f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpP)); 3659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpB)); 366b9907514SLisandro Dalcin label->numStrata = numStrata; 367b9907514SLisandro Dalcin label->stratumValues = tmpV; 368b9907514SLisandro Dalcin label->stratumSizes = tmpS; 369b9907514SLisandro Dalcin label->ht = tmpH; 370b9907514SLisandro Dalcin label->points = tmpP; 371b9907514SLisandro Dalcin label->validIS = tmpB; 372b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 3739566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 3749566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 3759566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, values[v], v)); 376b9907514SLisandro Dalcin tmpV[v] = values[v]; 377b9907514SLisandro Dalcin tmpS[v] = 0; 378b9907514SLisandro Dalcin tmpH[v] = ht; 379b9907514SLisandro Dalcin tmpP[v] = is; 380b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 381b9907514SLisandro Dalcin } 3829566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 383b9907514SLisandro Dalcin } else { 38448a46eb9SPierre Jolivet for (v = 0; v < numStrata; ++v) PetscCall(DMLabelAddStratum(label, values[v])); 385b9907514SLisandro Dalcin } 3869566063dSJacob Faibussowitsch PetscCall(PetscFree(values)); 3873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 388b9907514SLisandro Dalcin } 389b9907514SLisandro Dalcin 390b9907514SLisandro Dalcin /*@ 39120f4b53cSBarry Smith DMLabelAddStrataIS - Adds new stratum values in a `DMLabel` 392b9907514SLisandro Dalcin 39320f4b53cSBarry Smith Not Collective 3945b5e7992SMatthew G. Knepley 395d8d19677SJose E. Roman Input Parameters: 39620f4b53cSBarry Smith + label - The `DMLabel` 397b9907514SLisandro Dalcin - valueIS - Index set with stratum values 398b9907514SLisandro Dalcin 399b9907514SLisandro Dalcin Level: beginner 400b9907514SLisandro Dalcin 40120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 402b9907514SLisandro Dalcin @*/ 403d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 404d71ae5a4SJacob Faibussowitsch { 405b9907514SLisandro Dalcin PetscInt numStrata; 406b9907514SLisandro Dalcin const PetscInt *stratumValues; 407b9907514SLisandro Dalcin 408b9907514SLisandro Dalcin PetscFunctionBegin; 409b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 410b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 4119f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 4129566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata)); 4139566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues)); 4149566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues)); 4153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 416c58f1c22SToby Isaac } 417c58f1c22SToby Isaac 4189f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelView_Concrete_Ascii(DMLabel label, PetscViewer viewer) 419d71ae5a4SJacob Faibussowitsch { 420c58f1c22SToby Isaac PetscInt v; 421c58f1c22SToby Isaac PetscMPIInt rank; 422c58f1c22SToby Isaac 423c58f1c22SToby Isaac PetscFunctionBegin; 4249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 4259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 426c58f1c22SToby Isaac if (label) { 427d67d17b1SMatthew G. Knepley const char *name; 428d67d17b1SMatthew G. Knepley 4299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 4309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name)); 43163a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd)); 432c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 433c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 434ad8374ffSToby Isaac const PetscInt *points; 435c58f1c22SToby Isaac PetscInt p; 436c58f1c22SToby Isaac 4379566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 43848a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 4399566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 440c58f1c22SToby Isaac } 441c58f1c22SToby Isaac } 4429566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 4443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 445c58f1c22SToby Isaac } 446c58f1c22SToby Isaac 44766976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelView_Concrete(DMLabel label, PetscViewer viewer) 4489f6c5813SMatthew G. Knepley { 4499f196a02SMartin Diehl PetscBool isascii; 4509f6c5813SMatthew G. Knepley 4519f6c5813SMatthew G. Knepley PetscFunctionBegin; 4529f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 4539f196a02SMartin Diehl if (isascii) PetscCall(DMLabelView_Concrete_Ascii(label, viewer)); 4543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4559f6c5813SMatthew G. Knepley } 4569f6c5813SMatthew G. Knepley 457ffeef943SBarry Smith /*@ 458c58f1c22SToby Isaac DMLabelView - View the label 459c58f1c22SToby Isaac 46020f4b53cSBarry Smith Collective 4615b5e7992SMatthew G. Knepley 462c58f1c22SToby Isaac Input Parameters: 46320f4b53cSBarry Smith + label - The `DMLabel` 46420f4b53cSBarry Smith - viewer - The `PetscViewer` 465c58f1c22SToby Isaac 466c58f1c22SToby Isaac Level: intermediate 467c58f1c22SToby Isaac 46820f4b53cSBarry Smith .seealso: `DMLabel`, `PetscViewer`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 469c58f1c22SToby Isaac @*/ 470d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 471d71ae5a4SJacob Faibussowitsch { 472c58f1c22SToby Isaac PetscFunctionBegin; 473d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 4749566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer)); 475c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4769f6c5813SMatthew G. Knepley PetscCall(DMLabelMakeAllValid_Private(label)); 4779f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, view, viewer); 4783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 479c58f1c22SToby Isaac } 480c58f1c22SToby Isaac 48184f0b6dfSMatthew G. Knepley /*@ 482*4b793533SStefano Zampini DMLabelViewFromOptions - View a `DMLabel` in a particular way based on a request in the options database 483*4b793533SStefano Zampini 484*4b793533SStefano Zampini Collective 485*4b793533SStefano Zampini 486*4b793533SStefano Zampini Input Parameters: 487*4b793533SStefano Zampini + label - the `DMLabel` object 488*4b793533SStefano Zampini . obj - optional object that provides the prefix for the options database (if `NULL` then the prefix in `obj` is used) 489*4b793533SStefano Zampini - name - option string that is used to activate viewing 490*4b793533SStefano Zampini 491*4b793533SStefano Zampini Level: intermediate 492*4b793533SStefano Zampini 493*4b793533SStefano Zampini Note: 494*4b793533SStefano Zampini See `PetscObjectViewFromOptions()` for a list of values that can be provided in the options database to determine how the `DMLabel` is viewed 495*4b793533SStefano Zampini 496*4b793533SStefano Zampini .seealso: [](ch_dmbase), `DMLabel`, `DMLabelView()`, `PetscObjectViewFromOptions()`, `DMLabelCreate()` 497*4b793533SStefano Zampini @*/ 498*4b793533SStefano Zampini PetscErrorCode DMLabelViewFromOptions(DMLabel label, PeOp PetscObject obj, const char name[]) 499*4b793533SStefano Zampini { 500*4b793533SStefano Zampini PetscFunctionBegin; 501*4b793533SStefano Zampini PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 502*4b793533SStefano Zampini PetscCall(PetscObjectViewFromOptions((PetscObject)label, obj, name)); 503*4b793533SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 504*4b793533SStefano Zampini } 505*4b793533SStefano Zampini 506*4b793533SStefano Zampini /*@ 50720f4b53cSBarry Smith DMLabelReset - Destroys internal data structures in a `DMLabel` 508d67d17b1SMatthew G. Knepley 50920f4b53cSBarry Smith Not Collective 5105b5e7992SMatthew G. Knepley 511d67d17b1SMatthew G. Knepley Input Parameter: 51220f4b53cSBarry Smith . label - The `DMLabel` 513d67d17b1SMatthew G. Knepley 514d67d17b1SMatthew G. Knepley Level: beginner 515d67d17b1SMatthew G. Knepley 51620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDestroy()`, `DMLabelCreate()` 517d67d17b1SMatthew G. Knepley @*/ 518d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelReset(DMLabel label) 519d71ae5a4SJacob Faibussowitsch { 520d67d17b1SMatthew G. Knepley PetscInt v; 521d67d17b1SMatthew G. Knepley 522d67d17b1SMatthew G. Knepley PetscFunctionBegin; 523d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 524d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 5259f6c5813SMatthew G. Knepley if (label->ht[v]) PetscCall(PetscHSetIDestroy(&label->ht[v])); 5269566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 527d67d17b1SMatthew G. Knepley } 528b9907514SLisandro Dalcin label->numStrata = 0; 5299566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues)); 5309566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes)); 5319566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht)); 5329566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points)); 5339566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS)); 5349566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 535b9907514SLisandro Dalcin label->pStart = -1; 536b9907514SLisandro Dalcin label->pEnd = -1; 5379566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 5383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 539d67d17b1SMatthew G. Knepley } 540d67d17b1SMatthew G. Knepley 541d67d17b1SMatthew G. Knepley /*@ 54220f4b53cSBarry Smith DMLabelDestroy - Destroys a `DMLabel` 54384f0b6dfSMatthew G. Knepley 54420f4b53cSBarry Smith Collective 5455b5e7992SMatthew G. Knepley 54684f0b6dfSMatthew G. Knepley Input Parameter: 54720f4b53cSBarry Smith . label - The `DMLabel` 54884f0b6dfSMatthew G. Knepley 54984f0b6dfSMatthew G. Knepley Level: beginner 55084f0b6dfSMatthew G. Knepley 55120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelReset()`, `DMLabelCreate()` 55284f0b6dfSMatthew G. Knepley @*/ 553d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroy(DMLabel *label) 554d71ae5a4SJacob Faibussowitsch { 555c58f1c22SToby Isaac PetscFunctionBegin; 5563ba16761SJacob Faibussowitsch if (!*label) PetscFunctionReturn(PETSC_SUCCESS); 557f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 1); 558f4f49eeaSPierre Jolivet if (--((PetscObject)*label)->refct > 0) { 5599371c9d4SSatish Balay *label = NULL; 5603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5619371c9d4SSatish Balay } 5629566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 5639566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 5649566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 5653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 566c58f1c22SToby Isaac } 567c58f1c22SToby Isaac 56866976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDuplicate_Concrete(DMLabel label, DMLabel *labelnew) 5699f6c5813SMatthew G. Knepley { 5709f6c5813SMatthew G. Knepley PetscFunctionBegin; 5719f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 5729f6c5813SMatthew G. Knepley PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 573f4f49eeaSPierre Jolivet PetscCall(PetscObjectReference((PetscObject)label->points[v])); 5749f6c5813SMatthew G. Knepley (*labelnew)->points[v] = label->points[v]; 5759f6c5813SMatthew G. Knepley } 5769f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5779f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDuplicate(label->hmap, &(*labelnew)->hmap)); 5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5799f6c5813SMatthew G. Knepley } 5809f6c5813SMatthew G. Knepley 58184f0b6dfSMatthew G. Knepley /*@ 58220f4b53cSBarry Smith DMLabelDuplicate - Duplicates a `DMLabel` 58384f0b6dfSMatthew G. Knepley 58420f4b53cSBarry Smith Collective 5855b5e7992SMatthew G. Knepley 58684f0b6dfSMatthew G. Knepley Input Parameter: 58720f4b53cSBarry Smith . label - The `DMLabel` 58884f0b6dfSMatthew G. Knepley 58984f0b6dfSMatthew G. Knepley Output Parameter: 59020f4b53cSBarry Smith . labelnew - new label 59184f0b6dfSMatthew G. Knepley 59284f0b6dfSMatthew G. Knepley Level: intermediate 59384f0b6dfSMatthew G. Knepley 59420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 59584f0b6dfSMatthew G. Knepley @*/ 596d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 597d71ae5a4SJacob Faibussowitsch { 598d67d17b1SMatthew G. Knepley const char *name; 599c58f1c22SToby Isaac 600c58f1c22SToby Isaac PetscFunctionBegin; 601d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 6029566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 6039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 6049566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)label), name, labelnew)); 605c58f1c22SToby Isaac 606c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 6075aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 6088dcf10e8SMatthew G. Knepley (*labelnew)->readonly = label->readonly; 6099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 6109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 6119f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->ht)); 6129f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->points)); 6139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 6149f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 615c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 616c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 617b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 618c58f1c22SToby Isaac } 619c58f1c22SToby Isaac (*labelnew)->pStart = -1; 620c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 621c58f1c22SToby Isaac (*labelnew)->bt = NULL; 6229f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, duplicate, labelnew); 6233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 624c58f1c22SToby Isaac } 625c58f1c22SToby Isaac 626609dae6eSVaclav Hapla /*@C 62720f4b53cSBarry Smith DMLabelCompare - Compare two `DMLabel` objects 628609dae6eSVaclav Hapla 62920f4b53cSBarry Smith Collective; No Fortran Support 630609dae6eSVaclav Hapla 631609dae6eSVaclav Hapla Input Parameters: 632f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 63320f4b53cSBarry Smith . l0 - First `DMLabel` 63420f4b53cSBarry Smith - l1 - Second `DMLabel` 635609dae6eSVaclav Hapla 636a4e35b19SJacob Faibussowitsch Output Parameters: 6375efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 6385efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 639609dae6eSVaclav Hapla 640609dae6eSVaclav Hapla Level: intermediate 641609dae6eSVaclav Hapla 642609dae6eSVaclav Hapla Notes: 6435efe38ccSVaclav Hapla The output flag equal is the same on all processes. 64420f4b53cSBarry Smith If it is passed as `NULL` and difference is found, an error is thrown on all processes. 64520f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 646609dae6eSVaclav Hapla 6475efe38ccSVaclav Hapla The output message is set independently on each rank. 64820f4b53cSBarry Smith It is set to `NULL` if no difference was found on the current rank. It must be freed by user. 64920f4b53cSBarry Smith If message is passed as `NULL` and difference is found, the difference description is printed to stderr in synchronized manner. 65020f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 651609dae6eSVaclav Hapla 652609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 653609dae6eSVaclav Hapla 65420f4b53cSBarry Smith The communicator needs to be specified because currently `DMLabel` can live on `PETSC_COMM_SELF` even if the underlying `DM` is parallel. 6555efe38ccSVaclav Hapla 656a3b724e8SBarry Smith Developer Note: 657a3b724e8SBarry Smith Fortran stub cannot be generated automatically because `message` must be freed with `PetscFree()` 658a3b724e8SBarry Smith 65920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 660609dae6eSVaclav Hapla @*/ 661d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 662d71ae5a4SJacob Faibussowitsch { 663609dae6eSVaclav Hapla const char *name0, *name1; 664609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 6655efe38ccSVaclav Hapla PetscBool eq; 6665efe38ccSVaclav Hapla PetscMPIInt rank; 667609dae6eSVaclav Hapla 668609dae6eSVaclav Hapla PetscFunctionBegin; 6695efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 6705efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6714f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 4); 6724f572ea9SToby Isaac if (message) PetscAssertPointer(message, 5); 6739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6759566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 676609dae6eSVaclav Hapla { 677609dae6eSVaclav Hapla PetscInt v0, v1; 678609dae6eSVaclav Hapla 6799566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6809566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6815efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 68248a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Default value of DMLabel l0 \"%s\" = %" PetscInt_FMT " != %" PetscInt_FMT " = Default value of DMLabel l1 \"%s\"", name0, v0, v1, name1)); 6835440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPI_C_BOOL, MPI_LAND, comm)); 6845efe38ccSVaclav Hapla if (!eq) goto finish; 685609dae6eSVaclav Hapla } 686609dae6eSVaclav Hapla { 687609dae6eSVaclav Hapla IS is0, is1; 688609dae6eSVaclav Hapla 6899566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6909566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6919566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6929566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6939566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 69448a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 6955440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPI_C_BOOL, MPI_LAND, comm)); 6965efe38ccSVaclav Hapla if (!eq) goto finish; 697609dae6eSVaclav Hapla } 698609dae6eSVaclav Hapla { 699609dae6eSVaclav Hapla PetscInt i, nValues; 700609dae6eSVaclav Hapla 7019566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 702609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 703609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 704609dae6eSVaclav Hapla PetscInt n; 705609dae6eSVaclav Hapla IS is0, is1; 706609dae6eSVaclav Hapla 7079566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 708609dae6eSVaclav Hapla if (!n) continue; 7099566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 7109566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 7119566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 7129566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 7139566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 7145efe38ccSVaclav Hapla if (!eq) { 71563a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum #%" PetscInt_FMT " with value %" PetscInt_FMT " contains different points in DMLabel l0 \"%s\" and DMLabel l1 \"%s\"", i, v, name0, name1)); 7165efe38ccSVaclav Hapla break; 717609dae6eSVaclav Hapla } 718609dae6eSVaclav Hapla } 7195440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPI_C_BOOL, MPI_LAND, comm)); 720609dae6eSVaclav Hapla } 721609dae6eSVaclav Hapla finish: 7225efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 723609dae6eSVaclav Hapla if (message) { 724609dae6eSVaclav Hapla *message = NULL; 72548a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 7265efe38ccSVaclav Hapla } else { 72748a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 7289566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 7295efe38ccSVaclav Hapla } 7305efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 7315efe38ccSVaclav Hapla if (equal) *equal = eq; 73263a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 7333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 734609dae6eSVaclav Hapla } 735609dae6eSVaclav Hapla 736c6a43d28SMatthew G. Knepley /*@ 737c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 738c6a43d28SMatthew G. Knepley 73920f4b53cSBarry Smith Not Collective 7405b5e7992SMatthew G. Knepley 741c6a43d28SMatthew G. Knepley Input Parameter: 74220f4b53cSBarry Smith . label - The `DMLabel` 743c6a43d28SMatthew G. Knepley 744c6a43d28SMatthew G. Knepley Level: intermediate 745c6a43d28SMatthew G. Knepley 74620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 747c6a43d28SMatthew G. Knepley @*/ 748d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label) 749d71ae5a4SJacob Faibussowitsch { 7501690c2aeSBarry Smith PetscInt pStart = PETSC_INT_MAX, pEnd = -1, v; 751c6a43d28SMatthew G. Knepley 752c6a43d28SMatthew G. Knepley PetscFunctionBegin; 753c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7549566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 755c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 756c6a43d28SMatthew G. Knepley const PetscInt *points; 757c6a43d28SMatthew G. Knepley PetscInt i; 758c6a43d28SMatthew G. Knepley 7599566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 760c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 761c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 762c6a43d28SMatthew G. Knepley 763c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 764c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 765c6a43d28SMatthew G. Knepley } 7669566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 767c6a43d28SMatthew G. Knepley } 7681690c2aeSBarry Smith label->pStart = pStart == PETSC_INT_MAX ? -1 : pStart; 769c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7709566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 7713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 772c6a43d28SMatthew G. Knepley } 773c6a43d28SMatthew G. Knepley 774c6a43d28SMatthew G. Knepley /*@ 775c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 776c6a43d28SMatthew G. Knepley 77720f4b53cSBarry Smith Not Collective 7785b5e7992SMatthew G. Knepley 779c6a43d28SMatthew G. Knepley Input Parameters: 78020f4b53cSBarry Smith + label - The `DMLabel` 781c6a43d28SMatthew G. Knepley . pStart - The smallest point 782c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 783c6a43d28SMatthew G. Knepley 784c6a43d28SMatthew G. Knepley Level: intermediate 785c6a43d28SMatthew G. Knepley 78620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 787c6a43d28SMatthew G. Knepley @*/ 788d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 789d71ae5a4SJacob Faibussowitsch { 790c58f1c22SToby Isaac PetscInt v; 791c58f1c22SToby Isaac 792c58f1c22SToby Isaac PetscFunctionBegin; 793d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7949566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7959566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 796c58f1c22SToby Isaac label->pStart = pStart; 797c58f1c22SToby Isaac label->pEnd = pEnd; 798c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7999566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 800c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 8019f6c5813SMatthew G. Knepley IS pointIS; 802ad8374ffSToby Isaac const PetscInt *points; 803c58f1c22SToby Isaac PetscInt i; 804c58f1c22SToby Isaac 8059f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 8069f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points)); 807c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 808ad8374ffSToby Isaac const PetscInt point = points[i]; 809c58f1c22SToby Isaac 8109f6c5813SMatthew G. Knepley PetscCheck(!(point < pStart) && !(point >= pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " in stratum %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->stratumValues[v], pStart, pEnd); 8119566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 812c58f1c22SToby Isaac } 8139566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 8149f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 815c58f1c22SToby Isaac } 8163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 817c58f1c22SToby Isaac } 818c58f1c22SToby Isaac 819c6a43d28SMatthew G. Knepley /*@ 820c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 821c6a43d28SMatthew G. Knepley 82220f4b53cSBarry Smith Not Collective 8235b5e7992SMatthew G. Knepley 824c6a43d28SMatthew G. Knepley Input Parameter: 82520f4b53cSBarry Smith . label - the `DMLabel` 826c6a43d28SMatthew G. Knepley 827c6a43d28SMatthew G. Knepley Level: intermediate 828c6a43d28SMatthew G. Knepley 82920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 830c6a43d28SMatthew G. Knepley @*/ 831d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label) 832d71ae5a4SJacob Faibussowitsch { 833c58f1c22SToby Isaac PetscFunctionBegin; 834d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 835c58f1c22SToby Isaac label->pStart = -1; 836c58f1c22SToby Isaac label->pEnd = -1; 8379566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 8383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 839c58f1c22SToby Isaac } 840c58f1c22SToby Isaac 841c58f1c22SToby Isaac /*@ 842c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 843c6a43d28SMatthew G. Knepley 84420f4b53cSBarry Smith Not Collective 8455b5e7992SMatthew G. Knepley 846c6a43d28SMatthew G. Knepley Input Parameter: 84720f4b53cSBarry Smith . label - the `DMLabel` 848c6a43d28SMatthew G. Knepley 849c6a43d28SMatthew G. Knepley Output Parameters: 850c6a43d28SMatthew G. Knepley + pStart - The smallest point 851c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 852c6a43d28SMatthew G. Knepley 853c6a43d28SMatthew G. Knepley Level: intermediate 854c6a43d28SMatthew G. Knepley 85520f4b53cSBarry Smith Note: 85620f4b53cSBarry Smith This will compute an index for the label if one does not exist. 85720f4b53cSBarry Smith 85820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 859c6a43d28SMatthew G. Knepley @*/ 860d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 861d71ae5a4SJacob Faibussowitsch { 862c6a43d28SMatthew G. Knepley PetscFunctionBegin; 863c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8649566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 865c6a43d28SMatthew G. Knepley if (pStart) { 8664f572ea9SToby Isaac PetscAssertPointer(pStart, 2); 867c6a43d28SMatthew G. Knepley *pStart = label->pStart; 868c6a43d28SMatthew G. Knepley } 869c6a43d28SMatthew G. Knepley if (pEnd) { 8704f572ea9SToby Isaac PetscAssertPointer(pEnd, 3); 871c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 872c6a43d28SMatthew G. Knepley } 8733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 874c6a43d28SMatthew G. Knepley } 875c6a43d28SMatthew G. Knepley 876c6a43d28SMatthew G. Knepley /*@ 877c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 878c58f1c22SToby Isaac 87920f4b53cSBarry Smith Not Collective 8805b5e7992SMatthew G. Knepley 881c58f1c22SToby Isaac Input Parameters: 88220f4b53cSBarry Smith + label - the `DMLabel` 883c58f1c22SToby Isaac - value - the value 884c58f1c22SToby Isaac 885c58f1c22SToby Isaac Output Parameter: 886c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 887c58f1c22SToby Isaac 888c58f1c22SToby Isaac Level: developer 889c58f1c22SToby Isaac 89020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 891c58f1c22SToby Isaac @*/ 892d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 893d71ae5a4SJacob Faibussowitsch { 894c58f1c22SToby Isaac PetscInt v; 895c58f1c22SToby Isaac 896c58f1c22SToby Isaac PetscFunctionBegin; 897d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8984f572ea9SToby Isaac PetscAssertPointer(contains, 3); 8999566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 9000c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 9013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 902c58f1c22SToby Isaac } 903c58f1c22SToby Isaac 904c58f1c22SToby Isaac /*@ 905c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 906c58f1c22SToby Isaac 90720f4b53cSBarry Smith Not Collective 9085b5e7992SMatthew G. Knepley 909c58f1c22SToby Isaac Input Parameters: 91020f4b53cSBarry Smith + label - the `DMLabel` 911c58f1c22SToby Isaac - point - the point 912c58f1c22SToby Isaac 913c58f1c22SToby Isaac Output Parameter: 914c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 915c58f1c22SToby Isaac 916c58f1c22SToby Isaac Level: developer 917c58f1c22SToby Isaac 91820f4b53cSBarry Smith Note: 91920f4b53cSBarry Smith The user must call `DMLabelCreateIndex()` before this function. 92020f4b53cSBarry Smith 92120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 922c58f1c22SToby Isaac @*/ 923d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 924d71ae5a4SJacob Faibussowitsch { 925c58f1c22SToby Isaac PetscFunctionBeginHot; 926d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9274f572ea9SToby Isaac PetscAssertPointer(contains, 3); 9289566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 92976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 93028b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 93163a3b9bcSJacob 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); 93276bd3646SJed Brown } 933c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 9343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 935c58f1c22SToby Isaac } 936c58f1c22SToby Isaac 937c58f1c22SToby Isaac /*@ 938c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 939c58f1c22SToby Isaac 94020f4b53cSBarry Smith Not Collective 9415b5e7992SMatthew G. Knepley 942c58f1c22SToby Isaac Input Parameters: 94320f4b53cSBarry Smith + label - the `DMLabel` 944c58f1c22SToby Isaac . value - the stratum value 945c58f1c22SToby Isaac - point - the point 946c58f1c22SToby Isaac 947c58f1c22SToby Isaac Output Parameter: 948c58f1c22SToby Isaac . contains - true if the stratum contains the point 949c58f1c22SToby Isaac 950c58f1c22SToby Isaac Level: intermediate 951c58f1c22SToby Isaac 95220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 953c58f1c22SToby Isaac @*/ 954d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 955d71ae5a4SJacob Faibussowitsch { 9560c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 957d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9584f572ea9SToby Isaac PetscAssertPointer(contains, 4); 959cffad2c9SToby Isaac if (value == label->defaultValue) { 960cffad2c9SToby Isaac PetscInt pointVal; 9610c3c4a36SLisandro Dalcin 962cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 963cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 964cffad2c9SToby Isaac } else { 965cffad2c9SToby Isaac PetscInt v; 966cffad2c9SToby Isaac 967cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 968cffad2c9SToby Isaac if (v >= 0) { 9699f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 9709f6c5813SMatthew G. Knepley IS is; 971c58f1c22SToby Isaac PetscInt i; 972c58f1c22SToby Isaac 9739f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 9742b4d18a0SMatthew G. Knepley PetscCall(ISLocate(is, point, &i)); 9759f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 976cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 977c58f1c22SToby Isaac } else { 978cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 979cffad2c9SToby Isaac } 980cffad2c9SToby Isaac } else { // value is not present 981cffad2c9SToby Isaac *contains = PETSC_FALSE; 982cffad2c9SToby Isaac } 983c58f1c22SToby Isaac } 9843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 985c58f1c22SToby Isaac } 986c58f1c22SToby Isaac 98784f0b6dfSMatthew G. Knepley /*@ 98820f4b53cSBarry Smith DMLabelGetDefaultValue - Get the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9895aa44df4SToby Isaac When a label is created, it is initialized to -1. 9905aa44df4SToby Isaac 99120f4b53cSBarry Smith Not Collective 9925b5e7992SMatthew G. Knepley 99360225df5SJacob Faibussowitsch Input Parameter: 99420f4b53cSBarry Smith . label - a `DMLabel` object 9955aa44df4SToby Isaac 99660225df5SJacob Faibussowitsch Output Parameter: 9975aa44df4SToby Isaac . defaultValue - the default value 9985aa44df4SToby Isaac 9995aa44df4SToby Isaac Level: beginner 10005aa44df4SToby Isaac 100120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 100284f0b6dfSMatthew G. Knepley @*/ 1003d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 1004d71ae5a4SJacob Faibussowitsch { 10055aa44df4SToby Isaac PetscFunctionBegin; 1006d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10075aa44df4SToby Isaac *defaultValue = label->defaultValue; 10083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10095aa44df4SToby Isaac } 10105aa44df4SToby Isaac 101184f0b6dfSMatthew G. Knepley /*@ 101220f4b53cSBarry Smith DMLabelSetDefaultValue - Set the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 10135aa44df4SToby Isaac When a label is created, it is initialized to -1. 10145aa44df4SToby Isaac 101520f4b53cSBarry Smith Not Collective 10165b5e7992SMatthew G. Knepley 101760225df5SJacob Faibussowitsch Input Parameter: 101820f4b53cSBarry Smith . label - a `DMLabel` object 10195aa44df4SToby Isaac 102060225df5SJacob Faibussowitsch Output Parameter: 10215aa44df4SToby Isaac . defaultValue - the default value 10225aa44df4SToby Isaac 10235aa44df4SToby Isaac Level: beginner 10245aa44df4SToby Isaac 102520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 102684f0b6dfSMatthew G. Knepley @*/ 1027d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 1028d71ae5a4SJacob Faibussowitsch { 10295aa44df4SToby Isaac PetscFunctionBegin; 1030d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10315aa44df4SToby Isaac label->defaultValue = defaultValue; 10323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10335aa44df4SToby Isaac } 10345aa44df4SToby Isaac 1035c58f1c22SToby Isaac /*@ 103620f4b53cSBarry Smith DMLabelGetValue - Return the value a label assigns to a point, or the label's default value (which is initially -1, and can be changed with 103720f4b53cSBarry Smith `DMLabelSetDefaultValue()`) 1038c58f1c22SToby Isaac 103920f4b53cSBarry Smith Not Collective 10405b5e7992SMatthew G. Knepley 1041c58f1c22SToby Isaac Input Parameters: 104220f4b53cSBarry Smith + label - the `DMLabel` 1043c58f1c22SToby Isaac - point - the point 1044c58f1c22SToby Isaac 1045c58f1c22SToby Isaac Output Parameter: 10468e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 1047c58f1c22SToby Isaac 1048c58f1c22SToby Isaac Level: intermediate 1049c58f1c22SToby Isaac 105020f4b53cSBarry Smith Note: 105120f4b53cSBarry Smith A label may assign multiple values to a point. No guarantees are made about which value is returned in that case. 105220f4b53cSBarry Smith Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum. 105320f4b53cSBarry Smith 105420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1055c58f1c22SToby Isaac @*/ 1056d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 1057d71ae5a4SJacob Faibussowitsch { 1058c58f1c22SToby Isaac PetscInt v; 1059c58f1c22SToby Isaac 10600c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 1061d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10624f572ea9SToby Isaac PetscAssertPointer(value, 3); 10635aa44df4SToby Isaac *value = label->defaultValue; 1064c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 10659f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 10669f6c5813SMatthew G. Knepley IS is; 1067c58f1c22SToby Isaac PetscInt i; 1068c58f1c22SToby Isaac 10699f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 10702b4d18a0SMatthew G. Knepley PetscCall(ISLocate(label->points[v], point, &i)); 10719f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1072c58f1c22SToby Isaac if (i >= 0) { 1073c58f1c22SToby Isaac *value = label->stratumValues[v]; 1074c58f1c22SToby Isaac break; 1075c58f1c22SToby Isaac } 1076c58f1c22SToby Isaac } else { 1077c58f1c22SToby Isaac PetscBool has; 1078c58f1c22SToby Isaac 10799566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 1080c58f1c22SToby Isaac if (has) { 1081c58f1c22SToby Isaac *value = label->stratumValues[v]; 1082c58f1c22SToby Isaac break; 1083c58f1c22SToby Isaac } 1084c58f1c22SToby Isaac } 1085c58f1c22SToby Isaac } 10863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1087c58f1c22SToby Isaac } 1088c58f1c22SToby Isaac 1089c58f1c22SToby Isaac /*@ 109020f4b53cSBarry Smith DMLabelSetValue - Set the value a label assigns to a point. If the value is the same as the label's default value (which is initially -1, and can 109120f4b53cSBarry Smith be changed with `DMLabelSetDefaultValue()` to something different), then this function will do nothing. 1092c58f1c22SToby Isaac 109320f4b53cSBarry Smith Not Collective 10945b5e7992SMatthew G. Knepley 1095c58f1c22SToby Isaac Input Parameters: 109620f4b53cSBarry Smith + label - the `DMLabel` 1097c58f1c22SToby Isaac . point - the point 1098c58f1c22SToby Isaac - value - The point value 1099c58f1c22SToby Isaac 1100c58f1c22SToby Isaac Level: intermediate 1101c58f1c22SToby Isaac 110220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1103c58f1c22SToby Isaac @*/ 1104d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1105d71ae5a4SJacob Faibussowitsch { 1106c58f1c22SToby Isaac PetscInt v; 1107c58f1c22SToby Isaac 1108c58f1c22SToby Isaac PetscFunctionBegin; 1109d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11100c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11113ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 11129f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 11139566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1114c58f1c22SToby Isaac /* Set key */ 11159566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11169566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 11173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1118c58f1c22SToby Isaac } 1119c58f1c22SToby Isaac 1120c58f1c22SToby Isaac /*@ 1121c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1122c58f1c22SToby Isaac 112320f4b53cSBarry Smith Not Collective 11245b5e7992SMatthew G. Knepley 1125c58f1c22SToby Isaac Input Parameters: 112620f4b53cSBarry Smith + label - the `DMLabel` 1127c58f1c22SToby Isaac . point - the point 1128c58f1c22SToby Isaac - value - The point value 1129c58f1c22SToby Isaac 1130c58f1c22SToby Isaac Level: intermediate 1131c58f1c22SToby Isaac 113220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1133c58f1c22SToby Isaac @*/ 1134d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1135d71ae5a4SJacob Faibussowitsch { 1136ad8374ffSToby Isaac PetscInt v; 1137c58f1c22SToby Isaac 1138c58f1c22SToby Isaac PetscFunctionBegin; 1139d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11409f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 1141c58f1c22SToby Isaac /* Find label value */ 11429566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 11433ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 11440c3c4a36SLisandro Dalcin 1145eeed21e7SToby Isaac if (label->bt) { 114663a3b9bcSJacob 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); 11479566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1148eeed21e7SToby Isaac } 11490c3c4a36SLisandro Dalcin 11500c3c4a36SLisandro Dalcin /* Delete key */ 11519566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11529566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 11533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1154c58f1c22SToby Isaac } 1155c58f1c22SToby Isaac 1156c58f1c22SToby Isaac /*@ 115720f4b53cSBarry Smith DMLabelInsertIS - Set all points in the `IS` to a value 1158c58f1c22SToby Isaac 115920f4b53cSBarry Smith Not Collective 11605b5e7992SMatthew G. Knepley 1161c58f1c22SToby Isaac Input Parameters: 116220f4b53cSBarry Smith + label - the `DMLabel` 11632fe279fdSBarry Smith . is - the point `IS` 1164c58f1c22SToby Isaac - value - The point value 1165c58f1c22SToby Isaac 1166c58f1c22SToby Isaac Level: intermediate 1167c58f1c22SToby Isaac 116820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1169c58f1c22SToby Isaac @*/ 1170d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1171d71ae5a4SJacob Faibussowitsch { 11720c3c4a36SLisandro Dalcin PetscInt v, n, p; 1173c58f1c22SToby Isaac const PetscInt *points; 1174c58f1c22SToby Isaac 1175c58f1c22SToby Isaac PetscFunctionBegin; 1176d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1177c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 11780c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11793ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 11809f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 11819566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 11820c3c4a36SLisandro Dalcin /* Set keys */ 11839566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11849566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 11859566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 11869566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 11879566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 11883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1189c58f1c22SToby Isaac } 1190c58f1c22SToby Isaac 119184f0b6dfSMatthew G. Knepley /*@ 119220f4b53cSBarry Smith DMLabelGetNumValues - Get the number of values that the `DMLabel` takes 119384f0b6dfSMatthew G. Knepley 119420f4b53cSBarry Smith Not Collective 11955b5e7992SMatthew G. Knepley 119684f0b6dfSMatthew G. Knepley Input Parameter: 119720f4b53cSBarry Smith . label - the `DMLabel` 119884f0b6dfSMatthew G. Knepley 119901d2d390SJose E. Roman Output Parameter: 120084f0b6dfSMatthew G. Knepley . numValues - the number of values 120184f0b6dfSMatthew G. Knepley 120284f0b6dfSMatthew G. Knepley Level: intermediate 120384f0b6dfSMatthew G. Knepley 120420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 120584f0b6dfSMatthew G. Knepley @*/ 1206d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1207d71ae5a4SJacob Faibussowitsch { 1208c58f1c22SToby Isaac PetscFunctionBegin; 1209d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12104f572ea9SToby Isaac PetscAssertPointer(numValues, 2); 1211c58f1c22SToby Isaac *numValues = label->numStrata; 12123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1213c58f1c22SToby Isaac } 1214c58f1c22SToby Isaac 121584f0b6dfSMatthew G. Knepley /*@ 121620f4b53cSBarry Smith DMLabelGetValueIS - Get an `IS` of all values that the `DMlabel` takes 121784f0b6dfSMatthew G. Knepley 121820f4b53cSBarry Smith Not Collective 12195b5e7992SMatthew G. Knepley 122084f0b6dfSMatthew G. Knepley Input Parameter: 122120f4b53cSBarry Smith . label - the `DMLabel` 122284f0b6dfSMatthew G. Knepley 122301d2d390SJose E. Roman Output Parameter: 122460225df5SJacob Faibussowitsch . values - the value `IS` 122584f0b6dfSMatthew G. Knepley 122684f0b6dfSMatthew G. Knepley Level: intermediate 122784f0b6dfSMatthew G. Knepley 12281d04cbbeSVaclav Hapla Notes: 122920f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 123020f4b53cSBarry Smith Strata which are allocated but empty [`DMLabelGetStratumSize()` yields 0] are counted. 123120f4b53cSBarry Smith If you need to count only nonempty strata, use `DMLabelGetNonEmptyStratumValuesIS()`. 12321d04cbbeSVaclav Hapla 123320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 123484f0b6dfSMatthew G. Knepley @*/ 1235d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1236d71ae5a4SJacob Faibussowitsch { 1237c58f1c22SToby Isaac PetscFunctionBegin; 1238d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12394f572ea9SToby Isaac PetscAssertPointer(values, 2); 12409566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1242c58f1c22SToby Isaac } 1243c58f1c22SToby Isaac 124484f0b6dfSMatthew G. Knepley /*@ 12458696263dSMatthew G. Knepley DMLabelGetValueBounds - Return the smallest and largest value in the label 12468696263dSMatthew G. Knepley 12478696263dSMatthew G. Knepley Not Collective 12488696263dSMatthew G. Knepley 12498696263dSMatthew G. Knepley Input Parameter: 12508696263dSMatthew G. Knepley . label - the `DMLabel` 12518696263dSMatthew G. Knepley 12528696263dSMatthew G. Knepley Output Parameters: 12538696263dSMatthew G. Knepley + minValue - The smallest value 12548696263dSMatthew G. Knepley - maxValue - The largest value 12558696263dSMatthew G. Knepley 12568696263dSMatthew G. Knepley Level: intermediate 12578696263dSMatthew G. Knepley 12588696263dSMatthew G. Knepley .seealso: `DMLabel`, `DM`, `DMLabelGetBounds()`, `DMLabelGetValue()`, `DMLabelSetValue()` 12598696263dSMatthew G. Knepley @*/ 12608696263dSMatthew G. Knepley PetscErrorCode DMLabelGetValueBounds(DMLabel label, PetscInt *minValue, PetscInt *maxValue) 12618696263dSMatthew G. Knepley { 12621690c2aeSBarry Smith PetscInt min = PETSC_INT_MAX, max = PETSC_INT_MIN; 12638696263dSMatthew G. Knepley 12648696263dSMatthew G. Knepley PetscFunctionBegin; 12658696263dSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12668696263dSMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 12678696263dSMatthew G. Knepley min = PetscMin(min, label->stratumValues[v]); 12688696263dSMatthew G. Knepley max = PetscMax(max, label->stratumValues[v]); 12698696263dSMatthew G. Knepley } 12708696263dSMatthew G. Knepley if (minValue) { 12718696263dSMatthew G. Knepley PetscAssertPointer(minValue, 2); 12728696263dSMatthew G. Knepley *minValue = min; 12738696263dSMatthew G. Knepley } 12748696263dSMatthew G. Knepley if (maxValue) { 12758696263dSMatthew G. Knepley PetscAssertPointer(maxValue, 3); 12768696263dSMatthew G. Knepley *maxValue = max; 12778696263dSMatthew G. Knepley } 12788696263dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 12798696263dSMatthew G. Knepley } 12808696263dSMatthew G. Knepley 12818696263dSMatthew G. Knepley /*@ 128220f4b53cSBarry Smith DMLabelGetNonEmptyStratumValuesIS - Get an `IS` of all values that the `DMlabel` takes 12831d04cbbeSVaclav Hapla 128420f4b53cSBarry Smith Not Collective 12851d04cbbeSVaclav Hapla 12861d04cbbeSVaclav Hapla Input Parameter: 128720f4b53cSBarry Smith . label - the `DMLabel` 12881d04cbbeSVaclav Hapla 1289d5b43468SJose E. Roman Output Parameter: 129060225df5SJacob Faibussowitsch . values - the value `IS` 12911d04cbbeSVaclav Hapla 12921d04cbbeSVaclav Hapla Level: intermediate 12931d04cbbeSVaclav Hapla 12941d04cbbeSVaclav Hapla Notes: 129520f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 129620f4b53cSBarry Smith This is similar to `DMLabelGetValueIS()` but counts only nonempty strata. 12971d04cbbeSVaclav Hapla 129820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 12991d04cbbeSVaclav Hapla @*/ 1300d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 1301d71ae5a4SJacob Faibussowitsch { 13021d04cbbeSVaclav Hapla PetscInt i, j; 13031d04cbbeSVaclav Hapla PetscInt *valuesArr; 13041d04cbbeSVaclav Hapla 13051d04cbbeSVaclav Hapla PetscFunctionBegin; 13061d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13074f572ea9SToby Isaac PetscAssertPointer(values, 2); 13089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 13091d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 13101d04cbbeSVaclav Hapla PetscInt n; 13111d04cbbeSVaclav Hapla 13129566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 13131d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 13141d04cbbeSVaclav Hapla } 13151d04cbbeSVaclav Hapla if (j == label->numStrata) { 13169566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 13171d04cbbeSVaclav Hapla } else { 13189566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 13191d04cbbeSVaclav Hapla } 13209566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 13213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13221d04cbbeSVaclav Hapla } 13231d04cbbeSVaclav Hapla 13241d04cbbeSVaclav Hapla /*@ 132520f4b53cSBarry Smith DMLabelGetValueIndex - Get the index of a given value in the list of values for the `DMlabel`, or -1 if it is not present 1326d123abd9SMatthew G. Knepley 132720f4b53cSBarry Smith Not Collective 1328d123abd9SMatthew G. Knepley 1329d123abd9SMatthew G. Knepley Input Parameters: 133020f4b53cSBarry Smith + label - the `DMLabel` 133197bb3fdcSJose E. Roman - value - the value 1332d123abd9SMatthew G. Knepley 133301d2d390SJose E. Roman Output Parameter: 1334d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1335d123abd9SMatthew G. Knepley 1336d123abd9SMatthew G. Knepley Level: intermediate 1337d123abd9SMatthew G. Knepley 133820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1339d123abd9SMatthew G. Knepley @*/ 1340d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1341d71ae5a4SJacob Faibussowitsch { 1342d123abd9SMatthew G. Knepley PetscInt v; 1343d123abd9SMatthew G. Knepley 1344d123abd9SMatthew G. Knepley PetscFunctionBegin; 1345d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13464f572ea9SToby Isaac PetscAssertPointer(index, 3); 1347d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 13489371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 13499371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1350d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1351d123abd9SMatthew G. Knepley else *index = v; 13523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1353d123abd9SMatthew G. Knepley } 1354d123abd9SMatthew G. Knepley 1355d123abd9SMatthew G. Knepley /*@ 135684f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 135784f0b6dfSMatthew G. Knepley 135820f4b53cSBarry Smith Not Collective 13595b5e7992SMatthew G. Knepley 136084f0b6dfSMatthew G. Knepley Input Parameters: 136120f4b53cSBarry Smith + label - the `DMLabel` 136284f0b6dfSMatthew G. Knepley - value - the stratum value 136384f0b6dfSMatthew G. Knepley 136401d2d390SJose E. Roman Output Parameter: 136584f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 136684f0b6dfSMatthew G. Knepley 136784f0b6dfSMatthew G. Knepley Level: intermediate 136884f0b6dfSMatthew G. Knepley 136920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 137084f0b6dfSMatthew G. Knepley @*/ 1371d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1372d71ae5a4SJacob Faibussowitsch { 1373fada774cSMatthew G. Knepley PetscInt v; 1374fada774cSMatthew G. Knepley 1375fada774cSMatthew G. Knepley PetscFunctionBegin; 1376d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13774f572ea9SToby Isaac PetscAssertPointer(exists, 3); 13789566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13790c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 13803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1381fada774cSMatthew G. Knepley } 1382fada774cSMatthew G. Knepley 138384f0b6dfSMatthew G. Knepley /*@ 138484f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 138584f0b6dfSMatthew G. Knepley 138620f4b53cSBarry Smith Not Collective 13875b5e7992SMatthew G. Knepley 138884f0b6dfSMatthew G. Knepley Input Parameters: 138920f4b53cSBarry Smith + label - the `DMLabel` 139084f0b6dfSMatthew G. Knepley - value - the stratum value 139184f0b6dfSMatthew G. Knepley 139201d2d390SJose E. Roman Output Parameter: 139384f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 139484f0b6dfSMatthew G. Knepley 139584f0b6dfSMatthew G. Knepley Level: intermediate 139684f0b6dfSMatthew G. Knepley 139720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 139884f0b6dfSMatthew G. Knepley @*/ 1399d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1400d71ae5a4SJacob Faibussowitsch { 1401c58f1c22SToby Isaac PetscInt v; 1402c58f1c22SToby Isaac 1403c58f1c22SToby Isaac PetscFunctionBegin; 1404d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14054f572ea9SToby Isaac PetscAssertPointer(size, 3); 14069566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14079566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 14083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1409c58f1c22SToby Isaac } 1410c58f1c22SToby Isaac 141184f0b6dfSMatthew G. Knepley /*@ 141284f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 141384f0b6dfSMatthew G. Knepley 141420f4b53cSBarry Smith Not Collective 14155b5e7992SMatthew G. Knepley 141684f0b6dfSMatthew G. Knepley Input Parameters: 141720f4b53cSBarry Smith + label - the `DMLabel` 141884f0b6dfSMatthew G. Knepley - value - the stratum value 141984f0b6dfSMatthew G. Knepley 142001d2d390SJose E. Roman Output Parameters: 142184f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 142284f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 142384f0b6dfSMatthew G. Knepley 142484f0b6dfSMatthew G. Knepley Level: intermediate 142584f0b6dfSMatthew G. Knepley 142620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 142784f0b6dfSMatthew G. Knepley @*/ 1428d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1429d71ae5a4SJacob Faibussowitsch { 14309f6c5813SMatthew G. Knepley IS is; 14310c3c4a36SLisandro Dalcin PetscInt v, min, max; 1432c58f1c22SToby Isaac 1433c58f1c22SToby Isaac PetscFunctionBegin; 1434d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14359371c9d4SSatish Balay if (start) { 14364f572ea9SToby Isaac PetscAssertPointer(start, 3); 14379371c9d4SSatish Balay *start = -1; 14389371c9d4SSatish Balay } 14399371c9d4SSatish Balay if (end) { 14404f572ea9SToby Isaac PetscAssertPointer(end, 4); 14419371c9d4SSatish Balay *end = -1; 14429371c9d4SSatish Balay } 14439566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14443ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14459566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14463ba16761SJacob Faibussowitsch if (label->stratumSizes[v] <= 0) PetscFunctionReturn(PETSC_SUCCESS); 14479f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 14489f6c5813SMatthew G. Knepley PetscCall(ISGetMinMax(is, &min, &max)); 14499f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1450d6cb179aSToby Isaac if (start) *start = min; 1451d6cb179aSToby Isaac if (end) *end = max + 1; 14523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1453c58f1c22SToby Isaac } 1454c58f1c22SToby Isaac 145566976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelGetStratumIS_Concrete(DMLabel label, PetscInt v, IS *pointIS) 14569f6c5813SMatthew G. Knepley { 14579f6c5813SMatthew G. Knepley PetscFunctionBegin; 14589f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)label->points[v])); 14599f6c5813SMatthew G. Knepley *pointIS = label->points[v]; 14603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14619f6c5813SMatthew G. Knepley } 14629f6c5813SMatthew G. Knepley 146384f0b6dfSMatthew G. Knepley /*@ 146420f4b53cSBarry Smith DMLabelGetStratumIS - Get an `IS` with the stratum points 146584f0b6dfSMatthew G. Knepley 146620f4b53cSBarry Smith Not Collective 14675b5e7992SMatthew G. Knepley 146884f0b6dfSMatthew G. Knepley Input Parameters: 146920f4b53cSBarry Smith + label - the `DMLabel` 147084f0b6dfSMatthew G. Knepley - value - the stratum value 147184f0b6dfSMatthew G. Knepley 147201d2d390SJose E. Roman Output Parameter: 147384f0b6dfSMatthew G. Knepley . points - The stratum points 147484f0b6dfSMatthew G. Knepley 147584f0b6dfSMatthew G. Knepley Level: intermediate 147684f0b6dfSMatthew G. Knepley 1477593ce467SVaclav Hapla Notes: 147820f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 147920f4b53cSBarry Smith Returns `NULL` if the stratum is empty. 1480593ce467SVaclav Hapla 148120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 148284f0b6dfSMatthew G. Knepley @*/ 1483d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1484d71ae5a4SJacob Faibussowitsch { 1485c58f1c22SToby Isaac PetscInt v; 1486c58f1c22SToby Isaac 1487c58f1c22SToby Isaac PetscFunctionBegin; 1488d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14894f572ea9SToby Isaac PetscAssertPointer(points, 3); 1490c58f1c22SToby Isaac *points = NULL; 14919566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14923ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14939566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14949f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, points); 14953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1496c58f1c22SToby Isaac } 1497c58f1c22SToby Isaac 149884f0b6dfSMatthew G. Knepley /*@ 149920f4b53cSBarry Smith DMLabelSetStratumIS - Set the stratum points using an `IS` 150084f0b6dfSMatthew G. Knepley 150120f4b53cSBarry Smith Not Collective 15025b5e7992SMatthew G. Knepley 150384f0b6dfSMatthew G. Knepley Input Parameters: 150420f4b53cSBarry Smith + label - the `DMLabel` 150584f0b6dfSMatthew G. Knepley . value - the stratum value 150660225df5SJacob Faibussowitsch - is - The stratum points 150784f0b6dfSMatthew G. Knepley 150884f0b6dfSMatthew G. Knepley Level: intermediate 150984f0b6dfSMatthew G. Knepley 151020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 151184f0b6dfSMatthew G. Knepley @*/ 1512d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 1513d71ae5a4SJacob Faibussowitsch { 15140c3c4a36SLisandro Dalcin PetscInt v; 15154de306b1SToby Isaac 15164de306b1SToby Isaac PetscFunctionBegin; 1517d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1518d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 15199f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 15209566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 15213ba16761SJacob Faibussowitsch if (is == label->points[v]) PetscFunctionReturn(PETSC_SUCCESS); 15229566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 1523f4f49eeaSPierre Jolivet PetscCall(ISGetLocalSize(is, &label->stratumSizes[v])); 15249566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 1525f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 15260c3c4a36SLisandro Dalcin label->points[v] = is; 15270c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 15289566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 15294de306b1SToby Isaac if (label->bt) { 15304de306b1SToby Isaac const PetscInt *points; 15314de306b1SToby Isaac PetscInt p; 15324de306b1SToby Isaac 15339566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 15344de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 15354de306b1SToby Isaac const PetscInt point = points[p]; 15364de306b1SToby Isaac 153763a3b9bcSJacob 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); 15389566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 15394de306b1SToby Isaac } 15404de306b1SToby Isaac } 15413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15424de306b1SToby Isaac } 15434de306b1SToby Isaac 154484f0b6dfSMatthew G. Knepley /*@ 154584f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 15464de306b1SToby Isaac 154720f4b53cSBarry Smith Not Collective 15485b5e7992SMatthew G. Knepley 154984f0b6dfSMatthew G. Knepley Input Parameters: 155020f4b53cSBarry Smith + label - the `DMLabel` 155184f0b6dfSMatthew G. Knepley - value - the stratum value 155284f0b6dfSMatthew G. Knepley 155384f0b6dfSMatthew G. Knepley Level: intermediate 155484f0b6dfSMatthew G. Knepley 155520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 155684f0b6dfSMatthew G. Knepley @*/ 1557d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1558d71ae5a4SJacob Faibussowitsch { 1559c58f1c22SToby Isaac PetscInt v; 1560c58f1c22SToby Isaac 1561c58f1c22SToby Isaac PetscFunctionBegin; 1562d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15639f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 15649566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15653ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15664de306b1SToby Isaac if (label->validIS[v]) { 15674de306b1SToby Isaac if (label->bt) { 1568c58f1c22SToby Isaac PetscInt i; 1569ad8374ffSToby Isaac const PetscInt *points; 1570c58f1c22SToby Isaac 15719566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1572c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1573ad8374ffSToby Isaac const PetscInt point = points[i]; 1574c58f1c22SToby Isaac 157563a3b9bcSJacob 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); 15769566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1577c58f1c22SToby Isaac } 15789566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1579c58f1c22SToby Isaac } 1580c58f1c22SToby Isaac label->stratumSizes[v] = 0; 15819566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 15829566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 15839566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 15849566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1585c58f1c22SToby Isaac } else { 15869566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1587c58f1c22SToby Isaac } 15883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1589c58f1c22SToby Isaac } 1590c58f1c22SToby Isaac 159184f0b6dfSMatthew G. Knepley /*@ 1592412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1593412e9a14SMatthew G. Knepley 159420f4b53cSBarry Smith Not Collective 1595412e9a14SMatthew G. Knepley 1596412e9a14SMatthew G. Knepley Input Parameters: 159720f4b53cSBarry Smith + label - The `DMLabel` 1598412e9a14SMatthew G. Knepley . value - The label value for all points 1599412e9a14SMatthew G. Knepley . pStart - The first point 1600412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1601412e9a14SMatthew G. Knepley 1602412e9a14SMatthew G. Knepley Level: intermediate 1603412e9a14SMatthew G. Knepley 160420f4b53cSBarry Smith Note: 160520f4b53cSBarry Smith The marks points are [`pStart`, `pEnd`), and only the bounds are stored. 160620f4b53cSBarry Smith 160720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1608412e9a14SMatthew G. Knepley @*/ 1609d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1610d71ae5a4SJacob Faibussowitsch { 1611412e9a14SMatthew G. Knepley IS pIS; 1612412e9a14SMatthew G. Knepley 1613412e9a14SMatthew G. Knepley PetscFunctionBegin; 16149566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 16159566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 16169566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 16173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1618412e9a14SMatthew G. Knepley } 1619412e9a14SMatthew G. Knepley 1620412e9a14SMatthew G. Knepley /*@ 1621d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1622d123abd9SMatthew G. Knepley 162320f4b53cSBarry Smith Not Collective 1624d123abd9SMatthew G. Knepley 1625d123abd9SMatthew G. Knepley Input Parameters: 162620f4b53cSBarry Smith + label - The `DMLabel` 1627d123abd9SMatthew G. Knepley . value - The label value 1628d123abd9SMatthew G. Knepley - p - A point with this value 1629d123abd9SMatthew G. Knepley 1630d123abd9SMatthew G. Knepley Output Parameter: 1631d123abd9SMatthew 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 1632d123abd9SMatthew G. Knepley 1633d123abd9SMatthew G. Knepley Level: intermediate 1634d123abd9SMatthew G. Knepley 163520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1636d123abd9SMatthew G. Knepley @*/ 1637d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1638d71ae5a4SJacob Faibussowitsch { 16399f6c5813SMatthew G. Knepley IS pointIS; 1640d123abd9SMatthew G. Knepley PetscInt v; 1641d123abd9SMatthew G. Knepley 1642d123abd9SMatthew G. Knepley PetscFunctionBegin; 1643d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16444f572ea9SToby Isaac PetscAssertPointer(index, 4); 1645d123abd9SMatthew G. Knepley *index = -1; 16469566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 16473ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 16489566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 16499f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 1650f622de60SMatthew G. Knepley PetscCall(ISLocate(pointIS, p, index)); 16519f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 16523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1653d123abd9SMatthew G. Knepley } 1654d123abd9SMatthew G. Knepley 1655d123abd9SMatthew G. Knepley /*@ 165620f4b53cSBarry Smith DMLabelFilter - Remove all points outside of [`start`, `end`) 165784f0b6dfSMatthew G. Knepley 165820f4b53cSBarry Smith Not Collective 16595b5e7992SMatthew G. Knepley 166084f0b6dfSMatthew G. Knepley Input Parameters: 166120f4b53cSBarry Smith + label - the `DMLabel` 166222cd2cdaSVaclav Hapla . start - the first point kept 166322cd2cdaSVaclav Hapla - end - one more than the last point kept 166484f0b6dfSMatthew G. Knepley 166584f0b6dfSMatthew G. Knepley Level: intermediate 166684f0b6dfSMatthew G. Knepley 166720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 166884f0b6dfSMatthew G. Knepley @*/ 1669d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1670d71ae5a4SJacob Faibussowitsch { 1671c58f1c22SToby Isaac PetscInt v; 1672c58f1c22SToby Isaac 1673c58f1c22SToby Isaac PetscFunctionBegin; 1674d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16759f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16769566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 16779566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16789f6c5813SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 16799f6c5813SMatthew G. Knepley PetscCall(ISGeneralFilter(label->points[v], start, end)); 16809f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(label->points[v], &label->stratumSizes[v])); 16819f6c5813SMatthew G. Knepley } 16829566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 16833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1684c58f1c22SToby Isaac } 1685c58f1c22SToby Isaac 168684f0b6dfSMatthew G. Knepley /*@ 168784f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 168884f0b6dfSMatthew G. Knepley 168920f4b53cSBarry Smith Not Collective 16905b5e7992SMatthew G. Knepley 169184f0b6dfSMatthew G. Knepley Input Parameters: 169220f4b53cSBarry Smith + label - the `DMLabel` 169384f0b6dfSMatthew G. Knepley - permutation - the point permutation 169484f0b6dfSMatthew G. Knepley 169584f0b6dfSMatthew G. Knepley Output Parameter: 169660225df5SJacob Faibussowitsch . labelNew - the new label containing the permuted points 169784f0b6dfSMatthew G. Knepley 169884f0b6dfSMatthew G. Knepley Level: intermediate 169984f0b6dfSMatthew G. Knepley 170020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 170184f0b6dfSMatthew G. Knepley @*/ 1702d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1703d71ae5a4SJacob Faibussowitsch { 1704c58f1c22SToby Isaac const PetscInt *perm; 1705c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1706c58f1c22SToby Isaac 1707c58f1c22SToby Isaac PetscFunctionBegin; 1708d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1709d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 17109f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 17119566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 17129566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 17139566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 17149566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 17159566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1716c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1717c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1718ad8374ffSToby Isaac const PetscInt *points; 1719ad8374ffSToby Isaac PetscInt *pointsNew; 1720c58f1c22SToby Isaac 17219566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 17229f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(size, &pointsNew)); 1723c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1724ad8374ffSToby Isaac const PetscInt point = points[q]; 1725c58f1c22SToby Isaac 172663a3b9bcSJacob 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); 1727ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1728c58f1c22SToby Isaac } 17299566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 17309566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 173157508eceSPierre Jolivet PetscCall(ISDestroy(&(*labelNew)->points[v])); 1732fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 17339566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 17349566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1735fa8e8ae5SToby Isaac } else { 17369566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1737fa8e8ae5SToby Isaac } 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1739c58f1c22SToby Isaac } 17409566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1741c58f1c22SToby Isaac if (label->bt) { 17429566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 17439566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1744c58f1c22SToby Isaac } 17453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1746c58f1c22SToby Isaac } 1747c58f1c22SToby Isaac 17485552b385SBrandon /*@ 17495552b385SBrandon DMLabelPermuteValues - Permute the values in a label 17505552b385SBrandon 17515552b385SBrandon Not collective 17525552b385SBrandon 17535552b385SBrandon Input Parameters: 17545552b385SBrandon + label - the `DMLabel` 17555552b385SBrandon - permutation - the value permutation, permutation[old value] = new value 17565552b385SBrandon 17575552b385SBrandon Output Parameter: 17585552b385SBrandon . label - the `DMLabel` now with permuted values 17595552b385SBrandon 17605552b385SBrandon Note: 17615552b385SBrandon The modification is done in-place 17625552b385SBrandon 17635552b385SBrandon Level: intermediate 17645552b385SBrandon 17655552b385SBrandon .seealso: `DMLabelRewriteValues()`, `DMLabel`, `DM`, `DMLabelPermute()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 17665552b385SBrandon @*/ 17675552b385SBrandon PetscErrorCode DMLabelPermuteValues(DMLabel label, IS permutation) 17685552b385SBrandon { 17695552b385SBrandon PetscInt Nv, Np; 17705552b385SBrandon 17715552b385SBrandon PetscFunctionBegin; 17725552b385SBrandon PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 17735552b385SBrandon PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 17745552b385SBrandon PetscCall(DMLabelGetNumValues(label, &Nv)); 17755552b385SBrandon PetscCall(ISGetLocalSize(permutation, &Np)); 17765552b385SBrandon PetscCheck(Np == Nv, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_SIZ, "Permutation has size %" PetscInt_FMT " != %" PetscInt_FMT " number of label values", Np, Nv); 17775552b385SBrandon if (PetscDefined(USE_DEBUG)) { 17785552b385SBrandon PetscBool flg; 17795552b385SBrandon PetscCall(ISGetInfo(permutation, IS_PERMUTATION, IS_LOCAL, PETSC_TRUE, &flg)); 17805552b385SBrandon PetscCheck(flg, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "IS is not a permutation"); 17815552b385SBrandon } 17825552b385SBrandon PetscCall(DMLabelRewriteValues(label, permutation)); 17835552b385SBrandon PetscFunctionReturn(PETSC_SUCCESS); 17845552b385SBrandon } 17855552b385SBrandon 17865552b385SBrandon /*@ 17875552b385SBrandon DMLabelRewriteValues - Permute the values in a label, but some may be omitted 17885552b385SBrandon 17895552b385SBrandon Not collective 17905552b385SBrandon 17915552b385SBrandon Input Parameters: 17925552b385SBrandon + label - the `DMLabel` 17935552b385SBrandon - permutation - the value permutation, permutation[old value] = new value, but some maybe omitted 17945552b385SBrandon 17955552b385SBrandon Output Parameter: 17965552b385SBrandon . label - the `DMLabel` now with permuted values 17975552b385SBrandon 17985552b385SBrandon Note: 17995552b385SBrandon The modification is done in-place 18005552b385SBrandon 18015552b385SBrandon Level: intermediate 18025552b385SBrandon 18035552b385SBrandon .seealso: `DMLabelPermuteValues()`, `DMLabel`, `DM`, `DMLabelPermute()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 18045552b385SBrandon @*/ 18055552b385SBrandon PetscErrorCode DMLabelRewriteValues(DMLabel label, IS permutation) 18065552b385SBrandon { 18075552b385SBrandon const PetscInt *perm; 18085552b385SBrandon PetscInt Nv, Np; 18095552b385SBrandon 18105552b385SBrandon PetscFunctionBegin; 18115552b385SBrandon PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 18125552b385SBrandon PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 18135552b385SBrandon PetscCall(DMLabelMakeAllValid_Private(label)); 18145552b385SBrandon PetscCall(DMLabelGetNumValues(label, &Nv)); 18155552b385SBrandon PetscCall(ISGetLocalSize(permutation, &Np)); 18165552b385SBrandon PetscCheck(Np >= Nv, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_SIZ, "Permutation has size %" PetscInt_FMT " < %" PetscInt_FMT " number of label values", Np, Nv); 18175552b385SBrandon PetscCall(ISGetIndices(permutation, &perm)); 18185552b385SBrandon for (PetscInt v = 0; v < Nv; ++v) label->stratumValues[v] = perm[label->stratumValues[v]]; 18195552b385SBrandon PetscCall(ISRestoreIndices(permutation, &perm)); 18205552b385SBrandon PetscFunctionReturn(PETSC_SUCCESS); 18215552b385SBrandon } 18225552b385SBrandon 182366976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 1824d71ae5a4SJacob Faibussowitsch { 182526c55118SMichael Lange MPI_Comm comm; 1826eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 182726c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 182826c55118SMichael Lange PetscSection rootSection; 182926c55118SMichael Lange PetscSF labelSF; 183026c55118SMichael Lange 183126c55118SMichael Lange PetscFunctionBegin; 18329566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 18339566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 183426c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 183526c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 18369566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 18379566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 18389566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 183926c55118SMichael Lange if (label) { 184026c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1841ad8374ffSToby Isaac const PetscInt *points; 1842ad8374ffSToby Isaac 18439566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 184448a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 18459566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 184626c55118SMichael Lange } 184726c55118SMichael Lange } 18489566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 184926c55118SMichael Lange /* Create a point-wise array of stratum values */ 18509566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 18519566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 18529566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 185326c55118SMichael Lange if (label) { 185426c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1855ad8374ffSToby Isaac const PetscInt *points; 1856ad8374ffSToby Isaac 18579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 185826c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1859ad8374ffSToby Isaac const PetscInt p = points[l]; 18609566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 186126c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 186226c55118SMichael Lange } 18639566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 186426c55118SMichael Lange } 186526c55118SMichael Lange } 186626c55118SMichael Lange /* Build SF that maps label points to remote processes */ 18679566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 18689566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 18699566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 18709566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 187126c55118SMichael Lange /* Send the strata for each point over the derived SF */ 18729566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 18739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 18749566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 18759566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 187626c55118SMichael Lange /* Clean up */ 18779566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 18789566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 18799566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 18809566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 18813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 188226c55118SMichael Lange } 188326c55118SMichael Lange 188484f0b6dfSMatthew G. Knepley /*@ 188520f4b53cSBarry Smith DMLabelDistribute - Create a new label pushed forward over the `PetscSF` 188684f0b6dfSMatthew G. Knepley 188720f4b53cSBarry Smith Collective 18885b5e7992SMatthew G. Knepley 188984f0b6dfSMatthew G. Knepley Input Parameters: 189020f4b53cSBarry Smith + label - the `DMLabel` 189184f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 189284f0b6dfSMatthew G. Knepley 189384f0b6dfSMatthew G. Knepley Output Parameter: 189460225df5SJacob Faibussowitsch . labelNew - the new redistributed label 189584f0b6dfSMatthew G. Knepley 189684f0b6dfSMatthew G. Knepley Level: intermediate 189784f0b6dfSMatthew G. Knepley 189820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 189984f0b6dfSMatthew G. Knepley @*/ 1900d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1901d71ae5a4SJacob Faibussowitsch { 1902c58f1c22SToby Isaac MPI_Comm comm; 190326c55118SMichael Lange PetscSection leafSection; 190426c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 190526c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1906ad8374ffSToby Isaac PetscInt **points; 1907d67d17b1SMatthew G. Knepley const char *lname = NULL; 1908c58f1c22SToby Isaac char *name; 1909835f2295SStefano Zampini PetscMPIInt nameSize; 1910e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1911c58f1c22SToby Isaac size_t len = 0; 191226c55118SMichael Lange PetscMPIInt rank; 1913c58f1c22SToby Isaac 1914c58f1c22SToby Isaac PetscFunctionBegin; 1915d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1916f018e600SMatthew G. Knepley if (label) { 1917f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 19189f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 19199566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1920f018e600SMatthew G. Knepley } 19219566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 19229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1923c58f1c22SToby Isaac /* Bcast name */ 1924dd400576SPatrick Sanan if (rank == 0) { 19259566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 19269566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1927d67d17b1SMatthew G. Knepley } 1928835f2295SStefano Zampini PetscCall(PetscMPIIntCast(len, &nameSize)); 1929835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(&nameSize, 1, MPI_INT, 0, comm)); 19309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 19319566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 1932835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 19339566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 19349566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 193577d236dfSMichael Lange /* Bcast defaultValue */ 1936dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 19379566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 193826c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 19399566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 19405cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 19419566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 19429566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 19439566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 19449566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 19459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1946ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 19479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 19485cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 19495cbdf6fcSMichael Lange offset = 0; 19509566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 19519566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 195248a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 19535cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1954231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 19559371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 19569371c9d4SSatish Balay leafStrata[p] = s; 19579371c9d4SSatish Balay break; 19589371c9d4SSatish Balay } 19595cbdf6fcSMichael Lange } 19605cbdf6fcSMichael Lange } 1961c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 19629566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 19639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1964c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 19659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 19669566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1967ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1968c58f1c22SToby Isaac } 19699566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 19709f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 19719f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &points)); 1972c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 19739566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 1974f4f49eeaSPierre Jolivet PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &points[s])); 1975c58f1c22SToby Isaac } 1976c58f1c22SToby Isaac /* Insert points into new strata */ 19779566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 19789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1979c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 19809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 19819566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1982c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1983c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1984ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1985c58f1c22SToby Isaac } 1986c58f1c22SToby Isaac } 1987ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1988f4f49eeaSPierre Jolivet PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &points[s][0], PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 19899566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1990ad8374ffSToby Isaac } 19919566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 19929566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 19939566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 19949566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 19959566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 19963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1997c58f1c22SToby Isaac } 1998c58f1c22SToby Isaac 19997937d9ceSMichael Lange /*@ 20007937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 20017937d9ceSMichael Lange 200220f4b53cSBarry Smith Collective 20035b5e7992SMatthew G. Knepley 20047937d9ceSMichael Lange Input Parameters: 200520f4b53cSBarry Smith + label - the `DMLabel` 200620f4b53cSBarry Smith - sf - the `PetscSF` communication map 20077937d9ceSMichael Lange 20082fe279fdSBarry Smith Output Parameter: 200920f4b53cSBarry Smith . labelNew - the new `DMLabel` with localised leaf values 20107937d9ceSMichael Lange 20117937d9ceSMichael Lange Level: developer 20127937d9ceSMichael Lange 201320f4b53cSBarry Smith Note: 201420f4b53cSBarry Smith This is the inverse operation to `DMLabelDistribute()`. 20157937d9ceSMichael Lange 201620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 20177937d9ceSMichael Lange @*/ 2018d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 2019d71ae5a4SJacob Faibussowitsch { 20207937d9ceSMichael Lange MPI_Comm comm; 20217937d9ceSMichael Lange PetscSection rootSection; 20227937d9ceSMichael Lange PetscSF sfLabel; 20237937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 20247937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 20257937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 20267937d9ceSMichael Lange PetscInt *rootStrata; 2027d67d17b1SMatthew G. Knepley const char *lname; 20287937d9ceSMichael Lange char *name; 2029835f2295SStefano Zampini PetscMPIInt nameSize; 20307937d9ceSMichael Lange size_t len = 0; 20319852e123SBarry Smith PetscMPIInt rank, size; 20327937d9ceSMichael Lange 20337937d9ceSMichael Lange PetscFunctionBegin; 2034d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 2035d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 20369f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 20379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 20389566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 20399566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 20407937d9ceSMichael Lange /* Bcast name */ 2041dd400576SPatrick Sanan if (rank == 0) { 20429566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 20439566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 2044d67d17b1SMatthew G. Knepley } 2045835f2295SStefano Zampini PetscCall(PetscMPIIntCast(len, &nameSize)); 2046835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(&nameSize, 1, MPI_INT, 0, comm)); 20479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 20489566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 2049835f2295SStefano Zampini PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 20509566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 20519566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 20527937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 20537937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 20547937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 20559566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 20569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 2057dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 20587937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 20598212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 20608212dd46SStefano Zampini 20618212dd46SStefano Zampini leafPoints[ilp].index = ilp; 20628212dd46SStefano Zampini leafPoints[ilp].rank = rank; 20637937d9ceSMichael Lange } 20649566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 20659566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 20667937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 20679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 20686497c311SBarry Smith PetscCall(PetscSFGatherBegin(sf, MPIU_SF_NODE, leafPoints, rootPoints)); 20696497c311SBarry Smith PetscCall(PetscSFGatherEnd(sf, MPIU_SF_NODE, leafPoints, rootPoints)); 20709566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 20719566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 20727937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 20739566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 20747937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 20757937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 20767937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 20779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 20789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 20799566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 20807937d9ceSMichael Lange } 20817937d9ceSMichael Lange idx += rootDegree[p]; 20827937d9ceSMichael Lange } 20839566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 20849566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 20859566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 20869566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 20873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20887937d9ceSMichael Lange } 20897937d9ceSMichael Lange 2090d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 2091d71ae5a4SJacob Faibussowitsch { 2092d42890abSMatthew G. Knepley const PetscInt *degree; 2093d42890abSMatthew G. Knepley const PetscInt *points; 2094d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 2095d42890abSMatthew G. Knepley 2096d42890abSMatthew G. Knepley PetscFunctionBegin; 2097d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2098d42890abSMatthew G. Knepley /* Add in leaves */ 2099d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 2100d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 2101d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 2102d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 2103d42890abSMatthew G. Knepley } 2104d42890abSMatthew G. Knepley /* Add in shared roots */ 2105d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2106d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2107d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2108d42890abSMatthew G. Knepley if (degree[r]) { 2109d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2110d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 2111d42890abSMatthew G. Knepley } 2112d42890abSMatthew G. Knepley } 21133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2114d42890abSMatthew G. Knepley } 2115d42890abSMatthew G. Knepley 2116d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 2117d71ae5a4SJacob Faibussowitsch { 2118d42890abSMatthew G. Knepley const PetscInt *degree; 2119d42890abSMatthew G. Knepley const PetscInt *points; 2120d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 2121d42890abSMatthew G. Knepley 2122d42890abSMatthew G. Knepley PetscFunctionBegin; 2123d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2124d42890abSMatthew G. Knepley /* Read out leaves */ 2125d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 2126d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 2127d42890abSMatthew G. Knepley const PetscInt p = points[l]; 2128d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 2129d42890abSMatthew G. Knepley 2130d42890abSMatthew G. Knepley if (cval != defVal) { 2131d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 2132d42890abSMatthew G. Knepley if (val == defVal) { 2133d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 213448a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 2135d42890abSMatthew G. Knepley } 2136d42890abSMatthew G. Knepley } 2137d42890abSMatthew G. Knepley } 2138d42890abSMatthew G. Knepley /* Read out shared roots */ 2139d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2140d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2141d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2142d42890abSMatthew G. Knepley if (degree[r]) { 2143d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 2144d42890abSMatthew G. Knepley 2145d42890abSMatthew G. Knepley if (cval != defVal) { 2146d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2147d42890abSMatthew G. Knepley if (val == defVal) { 2148d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 214948a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 2150d42890abSMatthew G. Knepley } 2151d42890abSMatthew G. Knepley } 2152d42890abSMatthew G. Knepley } 2153d42890abSMatthew G. Knepley } 21543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2155d42890abSMatthew G. Knepley } 2156d42890abSMatthew G. Knepley 2157d42890abSMatthew G. Knepley /*@ 2158d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 2159d42890abSMatthew G. Knepley 216020f4b53cSBarry Smith Collective 2161d42890abSMatthew G. Knepley 2162d42890abSMatthew G. Knepley Input Parameters: 216320f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 216420f4b53cSBarry Smith - sf - The `PetscSF` describing parallel layout of the label points 2165d42890abSMatthew G. Knepley 2166d42890abSMatthew G. Knepley Level: intermediate 2167d42890abSMatthew G. Knepley 216820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 2169d42890abSMatthew G. Knepley @*/ 2170d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 2171d71ae5a4SJacob Faibussowitsch { 2172d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 2173d42890abSMatthew G. Knepley PetscMPIInt size; 2174d42890abSMatthew G. Knepley 2175d42890abSMatthew G. Knepley PetscFunctionBegin; 21769f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2177d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 2178d42890abSMatthew G. Knepley if (size > 1) { 2179d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2180d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 2181d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 2182d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 2183d42890abSMatthew G. Knepley } 21843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2185d42890abSMatthew G. Knepley } 2186d42890abSMatthew G. Knepley 2187d42890abSMatthew G. Knepley /*@ 2188d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 2189d42890abSMatthew G. Knepley 219020f4b53cSBarry Smith Collective 2191d42890abSMatthew G. Knepley 2192d42890abSMatthew G. Knepley Input Parameters: 219320f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 219460225df5SJacob Faibussowitsch - pointSF - The `PetscSF` describing parallel layout of the label points 2195d42890abSMatthew G. Knepley 2196d42890abSMatthew G. Knepley Level: intermediate 2197d42890abSMatthew G. Knepley 219820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 2199d42890abSMatthew G. Knepley @*/ 2200d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 2201d71ae5a4SJacob Faibussowitsch { 2202d42890abSMatthew G. Knepley PetscFunctionBegin; 22039f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2204d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 2205d42890abSMatthew G. Knepley label->propArray = NULL; 22063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2207d42890abSMatthew G. Knepley } 2208d42890abSMatthew G. Knepley 2209d42890abSMatthew G. Knepley /*@C 2210d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 2211d42890abSMatthew G. Knepley 221220f4b53cSBarry Smith Collective 2213d42890abSMatthew G. Knepley 2214d42890abSMatthew G. Knepley Input Parameters: 221520f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 2216a4e35b19SJacob Faibussowitsch . pointSF - The `PetscSF` describing parallel layout of the label points 221720f4b53cSBarry Smith . markPoint - An optional callback that is called when a point is marked, or `NULL` 221820f4b53cSBarry Smith - ctx - An optional user context for the callback, or `NULL` 2219d42890abSMatthew G. Knepley 222020f4b53cSBarry Smith Calling sequence of `markPoint`: 222120f4b53cSBarry Smith + label - The `DMLabel` 2222d42890abSMatthew G. Knepley . p - The point being marked 2223a4e35b19SJacob Faibussowitsch . val - The label value for `p` 2224d42890abSMatthew G. Knepley - ctx - An optional user context 2225d42890abSMatthew G. Knepley 2226d42890abSMatthew G. Knepley Level: intermediate 2227d42890abSMatthew G. Knepley 222820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2229d42890abSMatthew G. Knepley @*/ 2230a4e35b19SJacob Faibussowitsch PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel label, PetscInt p, PetscInt val, void *ctx), void *ctx) 2231d71ae5a4SJacob Faibussowitsch { 2232c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2233d42890abSMatthew G. Knepley PetscMPIInt size; 2234d42890abSMatthew G. Knepley 2235d42890abSMatthew G. Knepley PetscFunctionBegin; 22369f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2237d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 2238c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2239c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2240d42890abSMatthew G. Knepley /* Communicate marked edges 2241d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2242d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2243d42890abSMatthew G. Knepley 2244d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2245d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2246d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2247d42890abSMatthew G. Knepley 2248d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2249d42890abSMatthew 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 2250d42890abSMatthew G. Knepley edge to the queue. 2251d42890abSMatthew G. Knepley */ 2252d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2253d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2254d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2255d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2256d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2257d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2258d42890abSMatthew G. Knepley } 22593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2260d42890abSMatthew G. Knepley } 2261d42890abSMatthew G. Knepley 226284f0b6dfSMatthew G. Knepley /*@ 226320f4b53cSBarry Smith DMLabelConvertToSection - Make a `PetscSection`/`IS` pair that encodes the label 226484f0b6dfSMatthew G. Knepley 226520f4b53cSBarry Smith Not Collective 22665b5e7992SMatthew G. Knepley 226784f0b6dfSMatthew G. Knepley Input Parameter: 226820f4b53cSBarry Smith . label - the `DMLabel` 226984f0b6dfSMatthew G. Knepley 227084f0b6dfSMatthew G. Knepley Output Parameters: 227184f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 227220f4b53cSBarry Smith - is - An `IS` containing all the label points 227384f0b6dfSMatthew G. Knepley 227484f0b6dfSMatthew G. Knepley Level: developer 227584f0b6dfSMatthew G. Knepley 227620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 227784f0b6dfSMatthew G. Knepley @*/ 2278d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2279d71ae5a4SJacob Faibussowitsch { 2280c58f1c22SToby Isaac IS vIS; 2281c58f1c22SToby Isaac const PetscInt *values; 2282c58f1c22SToby Isaac PetscInt *points; 2283c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2284c58f1c22SToby Isaac 2285c58f1c22SToby Isaac PetscFunctionBegin; 2286d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 22879566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 22889566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 22899566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 22909371c9d4SSatish Balay if (nV) { 22919371c9d4SSatish Balay vS = values[0]; 22929371c9d4SSatish Balay vE = values[0] + 1; 22939371c9d4SSatish Balay } 2294c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2295c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2296c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2297c58f1c22SToby Isaac } 22989566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 22999566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2300c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2301c58f1c22SToby Isaac PetscInt n; 2302c58f1c22SToby Isaac 23039566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 23049566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2305c58f1c22SToby Isaac } 23069566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 23079566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 23089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2309c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2310c58f1c22SToby Isaac IS is; 2311c58f1c22SToby Isaac const PetscInt *spoints; 2312c58f1c22SToby Isaac PetscInt dof, off, p; 2313c58f1c22SToby Isaac 23149566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 23159566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 23169566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 23179566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2318c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 23199566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 23209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2321c58f1c22SToby Isaac } 23229566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 23239566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 23249566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 23253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2326c58f1c22SToby Isaac } 2327c58f1c22SToby Isaac 23289f6c5813SMatthew G. Knepley /*@C 23299f6c5813SMatthew G. Knepley DMLabelRegister - Adds a new label component implementation 23309f6c5813SMatthew G. Knepley 23319f6c5813SMatthew G. Knepley Not Collective 23329f6c5813SMatthew G. Knepley 23339f6c5813SMatthew G. Knepley Input Parameters: 23349f6c5813SMatthew G. Knepley + name - The name of a new user-defined creation routine 23359f6c5813SMatthew G. Knepley - create_func - The creation routine itself 23369f6c5813SMatthew G. Knepley 23379f6c5813SMatthew G. Knepley Notes: 23389f6c5813SMatthew G. Knepley `DMLabelRegister()` may be called multiple times to add several user-defined labels 23399f6c5813SMatthew G. Knepley 234060225df5SJacob Faibussowitsch Example Usage: 23419f6c5813SMatthew G. Knepley .vb 23429f6c5813SMatthew G. Knepley DMLabelRegister("my_label", MyLabelCreate); 23439f6c5813SMatthew G. Knepley .ve 23449f6c5813SMatthew G. Knepley 23459f6c5813SMatthew G. Knepley Then, your label type can be chosen with the procedural interface via 23469f6c5813SMatthew G. Knepley .vb 23479f6c5813SMatthew G. Knepley DMLabelCreate(MPI_Comm, DMLabel *); 23489f6c5813SMatthew G. Knepley DMLabelSetType(DMLabel, "my_label"); 23499f6c5813SMatthew G. Knepley .ve 23509f6c5813SMatthew G. Knepley or at runtime via the option 23519f6c5813SMatthew G. Knepley .vb 23529f6c5813SMatthew G. Knepley -dm_label_type my_label 23539f6c5813SMatthew G. Knepley .ve 23549f6c5813SMatthew G. Knepley 23559f6c5813SMatthew G. Knepley Level: advanced 23569f6c5813SMatthew G. Knepley 235760225df5SJacob Faibussowitsch .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelRegisterAll()`, `DMLabelRegisterDestroy()` 23589f6c5813SMatthew G. Knepley @*/ 23599f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegister(const char name[], PetscErrorCode (*create_func)(DMLabel)) 23609f6c5813SMatthew G. Knepley { 23619f6c5813SMatthew G. Knepley PetscFunctionBegin; 23629f6c5813SMatthew G. Knepley PetscCall(DMInitializePackage()); 23639f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListAdd(&DMLabelList, name, create_func)); 23643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23659f6c5813SMatthew G. Knepley } 23669f6c5813SMatthew G. Knepley 23679f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel); 23689f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel); 23699f6c5813SMatthew G. Knepley 23709f6c5813SMatthew G. Knepley /*@C 23719f6c5813SMatthew G. Knepley DMLabelRegisterAll - Registers all of the `DMLabel` implementations in the `DM` package. 23729f6c5813SMatthew G. Knepley 23739f6c5813SMatthew G. Knepley Not Collective 23749f6c5813SMatthew G. Knepley 23759f6c5813SMatthew G. Knepley Level: advanced 23769f6c5813SMatthew G. Knepley 237720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMRegisterAll()`, `DMLabelRegisterDestroy()` 23789f6c5813SMatthew G. Knepley @*/ 23799f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterAll(void) 23809f6c5813SMatthew G. Knepley { 23819f6c5813SMatthew G. Knepley PetscFunctionBegin; 23823ba16761SJacob Faibussowitsch if (DMLabelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 23839f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_TRUE; 23849f6c5813SMatthew G. Knepley 23859f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELCONCRETE, DMLabelCreate_Concrete)); 23869f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELEPHEMERAL, DMLabelCreate_Ephemeral)); 23873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23889f6c5813SMatthew G. Knepley } 23899f6c5813SMatthew G. Knepley 23909f6c5813SMatthew G. Knepley /*@C 23919f6c5813SMatthew G. Knepley DMLabelRegisterDestroy - This function destroys the `DMLabel` registry. It is called from `PetscFinalize()`. 23929f6c5813SMatthew G. Knepley 23939f6c5813SMatthew G. Knepley Level: developer 23949f6c5813SMatthew G. Knepley 239520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscInitialize()` 23969f6c5813SMatthew G. Knepley @*/ 23979f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterDestroy(void) 23989f6c5813SMatthew G. Knepley { 23999f6c5813SMatthew G. Knepley PetscFunctionBegin; 24009f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMLabelList)); 24019f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_FALSE; 24023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24039f6c5813SMatthew G. Knepley } 24049f6c5813SMatthew G. Knepley 2405cc4c1da9SBarry Smith /*@ 24069f6c5813SMatthew G. Knepley DMLabelSetType - Sets the particular implementation for a label. 24079f6c5813SMatthew G. Knepley 240820f4b53cSBarry Smith Collective 24099f6c5813SMatthew G. Knepley 24109f6c5813SMatthew G. Knepley Input Parameters: 24119f6c5813SMatthew G. Knepley + label - The label 24129f6c5813SMatthew G. Knepley - method - The name of the label type 24139f6c5813SMatthew G. Knepley 24149f6c5813SMatthew G. Knepley Options Database Key: 241520f4b53cSBarry Smith . -dm_label_type <type> - Sets the label type; use -help for a list of available types or see `DMLabelType` 24169f6c5813SMatthew G. Knepley 24179f6c5813SMatthew G. Knepley Level: intermediate 24189f6c5813SMatthew G. Knepley 241920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetType()`, `DMLabelCreate()` 24209f6c5813SMatthew G. Knepley @*/ 24219f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetType(DMLabel label, DMLabelType method) 24229f6c5813SMatthew G. Knepley { 24239f6c5813SMatthew G. Knepley PetscErrorCode (*r)(DMLabel); 24249f6c5813SMatthew G. Knepley PetscBool match; 24259f6c5813SMatthew G. Knepley 24269f6c5813SMatthew G. Knepley PetscFunctionBegin; 24279f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 24289f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)label, method, &match)); 24293ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 24309f6c5813SMatthew G. Knepley 24319f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 24329f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListFind(DMLabelList, method, &r)); 24339f6c5813SMatthew G. Knepley PetscCheck(r, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMLabel type: %s", method); 24349f6c5813SMatthew G. Knepley 24359f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, destroy); 24369f6c5813SMatthew G. Knepley PetscCall(PetscMemzero(label->ops, sizeof(*label->ops))); 24379f6c5813SMatthew G. Knepley PetscCall(PetscObjectChangeTypeName((PetscObject)label, method)); 24389f6c5813SMatthew G. Knepley PetscCall((*r)(label)); 24393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24409f6c5813SMatthew G. Knepley } 24419f6c5813SMatthew G. Knepley 2442cc4c1da9SBarry Smith /*@ 24439f6c5813SMatthew G. Knepley DMLabelGetType - Gets the type name (as a string) from the label. 24449f6c5813SMatthew G. Knepley 24459f6c5813SMatthew G. Knepley Not Collective 24469f6c5813SMatthew G. Knepley 24479f6c5813SMatthew G. Knepley Input Parameter: 244820f4b53cSBarry Smith . label - The `DMLabel` 24499f6c5813SMatthew G. Knepley 24509f6c5813SMatthew G. Knepley Output Parameter: 245120f4b53cSBarry Smith . type - The `DMLabel` type name 24529f6c5813SMatthew G. Knepley 24539f6c5813SMatthew G. Knepley Level: intermediate 24549f6c5813SMatthew G. Knepley 245520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetType()`, `DMLabelCreate()` 24569f6c5813SMatthew G. Knepley @*/ 24579f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetType(DMLabel label, DMLabelType *type) 24589f6c5813SMatthew G. Knepley { 24599f6c5813SMatthew G. Knepley PetscFunctionBegin; 24609f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 24614f572ea9SToby Isaac PetscAssertPointer(type, 2); 24629f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 24639f6c5813SMatthew G. Knepley *type = ((PetscObject)label)->type_name; 24643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24659f6c5813SMatthew G. Knepley } 24669f6c5813SMatthew G. Knepley 24679f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Concrete(DMLabel label) 24689f6c5813SMatthew G. Knepley { 24699f6c5813SMatthew G. Knepley PetscFunctionBegin; 24709f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Concrete; 24719f6c5813SMatthew G. Knepley label->ops->setup = NULL; 24729f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Concrete; 24739f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Concrete; 24743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24759f6c5813SMatthew G. Knepley } 24769f6c5813SMatthew G. Knepley 24779f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel label) 24789f6c5813SMatthew G. Knepley { 24799f6c5813SMatthew G. Knepley PetscFunctionBegin; 24809f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 24819f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Concrete(label)); 24823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24839f6c5813SMatthew G. Knepley } 24849f6c5813SMatthew G. Knepley 248584f0b6dfSMatthew G. Knepley /*@ 2486c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 248720f4b53cSBarry Smith the local section and an `PetscSF` describing the section point overlap. 2488c58f1c22SToby Isaac 248920f4b53cSBarry Smith Collective 24905b5e7992SMatthew G. Knepley 2491c58f1c22SToby Isaac Input Parameters: 249220f4b53cSBarry Smith + s - The `PetscSection` for the local field layout 249320f4b53cSBarry Smith . sf - The `PetscSF` describing parallel layout of the section points 249420f4b53cSBarry Smith . includeConstraints - By default this is `PETSC_FALSE`, meaning that the global field vector will not possess constrained dofs 2495c58f1c22SToby Isaac . label - The label specifying the points 2496c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2497c58f1c22SToby Isaac 2498c58f1c22SToby Isaac Output Parameter: 249920f4b53cSBarry Smith . gsection - The `PetscSection` for the global field layout 2500c58f1c22SToby Isaac 2501c58f1c22SToby Isaac Level: developer 2502c58f1c22SToby Isaac 250320f4b53cSBarry Smith Note: 250420f4b53cSBarry Smith This gives negative sizes and offsets to points not owned by this process 250520f4b53cSBarry Smith 250620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionCreate()` 2507c58f1c22SToby Isaac @*/ 2508d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2509d71ae5a4SJacob Faibussowitsch { 2510c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2511c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2512c58f1c22SToby Isaac 2513c58f1c22SToby Isaac PetscFunctionBegin; 2514d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2515d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2516d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 25179566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 25189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 25199566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 25209566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2521c58f1c22SToby Isaac if (nroots >= 0) { 252263a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 25239566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2524c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 25259566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2526c58f1c22SToby Isaac } else { 2527c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2528c58f1c22SToby Isaac } 2529c58f1c22SToby Isaac } 2530c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2531c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2532c58f1c22SToby Isaac PetscInt value; 2533c58f1c22SToby Isaac 25349566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2535c58f1c22SToby Isaac if (value != labelValue) continue; 25369566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 25379566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 25389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 25399566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2540c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2541c58f1c22SToby Isaac } 25429566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2543c58f1c22SToby Isaac if (nroots >= 0) { 25449566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 25459566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2546c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 25479371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 25489371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 25499371c9d4SSatish Balay } 2550c58f1c22SToby Isaac } 2551c58f1c22SToby Isaac } 255235cb6cd3SPierre Jolivet /* Calculate new sizes, get process offset, and calculate point offsets */ 2553c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2554c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2555c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2556c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2557c58f1c22SToby Isaac } 25589566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2559c58f1c22SToby Isaac globalOff -= off; 2560c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2561c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2562c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2563c58f1c22SToby Isaac } 2564c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2565c58f1c22SToby Isaac if (nroots >= 0) { 25669566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 25679566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2568c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 25699371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 25709371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 25719371c9d4SSatish Balay } 2572c58f1c22SToby Isaac } 2573c58f1c22SToby Isaac } 25749566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 25759566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 25763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2577c58f1c22SToby Isaac } 2578c58f1c22SToby Isaac 25799371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 25805fdea053SToby Isaac DMLabel label; 25815fdea053SToby Isaac PetscCopyMode *modes; 25825fdea053SToby Isaac PetscInt *sizes; 25835fdea053SToby Isaac const PetscInt ***perms; 25845fdea053SToby Isaac const PetscScalar ***rots; 25855fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 25865fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 25875fdea053SToby Isaac } PetscSectionSym_Label; 25885fdea053SToby Isaac 2589d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 2590d71ae5a4SJacob Faibussowitsch { 25915fdea053SToby Isaac PetscInt i, j; 25925fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 25935fdea053SToby Isaac 25945fdea053SToby Isaac PetscFunctionBegin; 25955fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 25965fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 25975fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 25989566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 25999566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 26005fdea053SToby Isaac } 26015fdea053SToby Isaac if (sl->perms[i]) { 26025fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 26035fdea053SToby Isaac 26049566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 26055fdea053SToby Isaac } 26065fdea053SToby Isaac if (sl->rots[i]) { 26075fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 26085fdea053SToby Isaac 26099566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 26105fdea053SToby Isaac } 26115fdea053SToby Isaac } 26125fdea053SToby Isaac } 26139566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 26149566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 26155fdea053SToby Isaac sl->numStrata = 0; 26163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26175fdea053SToby Isaac } 26185fdea053SToby Isaac 2619d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 2620d71ae5a4SJacob Faibussowitsch { 26215fdea053SToby Isaac PetscFunctionBegin; 26229566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 26239566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 26243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26255fdea053SToby Isaac } 26265fdea053SToby Isaac 2627d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 2628d71ae5a4SJacob Faibussowitsch { 26295fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 26305fdea053SToby Isaac PetscBool isAscii; 26315fdea053SToby Isaac DMLabel label = sl->label; 2632d67d17b1SMatthew G. Knepley const char *name; 26335fdea053SToby Isaac 26345fdea053SToby Isaac PetscFunctionBegin; 26359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 26365fdea053SToby Isaac if (isAscii) { 26375fdea053SToby Isaac PetscInt i, j, k; 26385fdea053SToby Isaac PetscViewerFormat format; 26395fdea053SToby Isaac 26409566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 26415fdea053SToby Isaac if (label) { 26429566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 26435fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 26449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 26459566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 26469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 26475fdea053SToby Isaac } else { 26489566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 26499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 26505fdea053SToby Isaac } 26515fdea053SToby Isaac } else { 26529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 26535fdea053SToby Isaac } 26549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 26555fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 26565fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 26575fdea053SToby Isaac 26585fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 265963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 26605fdea053SToby Isaac } else { 266163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 26629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 266363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 26645fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 26659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 26665fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 26675fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 266863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 26695fdea053SToby Isaac } else { 26705fdea053SToby Isaac PetscInt tab; 26715fdea053SToby Isaac 267263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 26739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 26749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 26755fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 26769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 26779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 267863a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 26799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 26809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 26815fdea053SToby Isaac } 26825fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 26839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 26849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 26855fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 268663a3b9bcSJacob 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]))); 26875fdea053SToby Isaac #else 268863a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 26895fdea053SToby Isaac #endif 26909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 26919566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 26925fdea053SToby Isaac } 26939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 26945fdea053SToby Isaac } 26955fdea053SToby Isaac } 26969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 26975fdea053SToby Isaac } 26989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 26995fdea053SToby Isaac } 27005fdea053SToby Isaac } 27019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 27025fdea053SToby Isaac } 27033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27045fdea053SToby Isaac } 27055fdea053SToby Isaac 27065fdea053SToby Isaac /*@ 27075fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 27085fdea053SToby Isaac 270920f4b53cSBarry Smith Logically 27105fdea053SToby Isaac 271160225df5SJacob Faibussowitsch Input Parameters: 27125fdea053SToby Isaac + sym - the section symmetries 271320f4b53cSBarry Smith - label - the `DMLabel` describing the types of points 27145fdea053SToby Isaac 27155fdea053SToby Isaac Level: developer: 27165fdea053SToby Isaac 271720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 27185fdea053SToby Isaac @*/ 2719d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 2720d71ae5a4SJacob Faibussowitsch { 27215fdea053SToby Isaac PetscSectionSym_Label *sl; 27225fdea053SToby Isaac 27235fdea053SToby Isaac PetscFunctionBegin; 27245fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 27255fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 27269566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 27275fdea053SToby Isaac if (label) { 27285fdea053SToby Isaac sl->label = label; 27299566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 27309566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 27319566063dSJacob 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)); 27329566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 27339566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 27349566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 27359566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 27369566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 27375fdea053SToby Isaac } 27383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27395fdea053SToby Isaac } 27405fdea053SToby Isaac 27415fdea053SToby Isaac /*@C 2742b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2743b004864fSMatthew G. Knepley 274420f4b53cSBarry Smith Logically Collective 2745b004864fSMatthew G. Knepley 2746b004864fSMatthew G. Knepley Input Parameters: 2747b004864fSMatthew G. Knepley + sym - the section symmetries 2748b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2749b004864fSMatthew G. Knepley 2750b004864fSMatthew G. Knepley Output Parameters: 275120f4b53cSBarry Smith + size - the number of dofs for points in the `stratum` of the label 275220f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 275320f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a ppoint in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 275420f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 275520f4b53cSBarry 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 2756b004864fSMatthew G. Knepley 2757b004864fSMatthew G. Knepley Level: developer 2758b004864fSMatthew G. Knepley 275920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2760b004864fSMatthew G. Knepley @*/ 2761d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2762d71ae5a4SJacob Faibussowitsch { 2763b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2764b004864fSMatthew G. Knepley const char *name; 2765b004864fSMatthew G. Knepley PetscInt i; 2766b004864fSMatthew G. Knepley 2767b004864fSMatthew G. Knepley PetscFunctionBegin; 2768b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2769b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2770b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2771b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2772b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2773b004864fSMatthew G. Knepley 2774b004864fSMatthew G. Knepley if (stratum == value) break; 2775b004864fSMatthew G. Knepley } 27769566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2777b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 27789371c9d4SSatish Balay if (size) { 27794f572ea9SToby Isaac PetscAssertPointer(size, 3); 27809371c9d4SSatish Balay *size = sl->sizes[i]; 27819371c9d4SSatish Balay } 27829371c9d4SSatish Balay if (minOrient) { 27834f572ea9SToby Isaac PetscAssertPointer(minOrient, 4); 27849371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 27859371c9d4SSatish Balay } 27869371c9d4SSatish Balay if (maxOrient) { 27874f572ea9SToby Isaac PetscAssertPointer(maxOrient, 5); 27889371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 27899371c9d4SSatish Balay } 27909371c9d4SSatish Balay if (perms) { 27914f572ea9SToby Isaac PetscAssertPointer(perms, 6); 27928e3a54c0SPierre Jolivet *perms = PetscSafePointerPlusOffset(sl->perms[i], sl->minMaxOrients[i][0]); 27939371c9d4SSatish Balay } 27949371c9d4SSatish Balay if (rots) { 27954f572ea9SToby Isaac PetscAssertPointer(rots, 7); 27968e3a54c0SPierre Jolivet *rots = PetscSafePointerPlusOffset(sl->rots[i], sl->minMaxOrients[i][0]); 27979371c9d4SSatish Balay } 27983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2799b004864fSMatthew G. Knepley } 2800b004864fSMatthew G. Knepley 2801b004864fSMatthew G. Knepley /*@C 28025fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 28035fdea053SToby Isaac 280420f4b53cSBarry Smith Logically 28055fdea053SToby Isaac 28065fdea053SToby Isaac Input Parameters: 28075b5e7992SMatthew G. Knepley + sym - the section symmetries 28085fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 280920f4b53cSBarry Smith . size - the number of dofs for points in the `stratum` of the label 281020f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 281120f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a point in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 281220f4b53cSBarry Smith . mode - how `sym` should copy the `perms` and `rots` arrays 281320f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 281420f4b53cSBarry 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 28155fdea053SToby Isaac 28165fdea053SToby Isaac Level: developer 28175fdea053SToby Isaac 281820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 28195fdea053SToby Isaac @*/ 2820d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 2821d71ae5a4SJacob Faibussowitsch { 28225fdea053SToby Isaac PetscSectionSym_Label *sl; 2823d67d17b1SMatthew G. Knepley const char *name; 2824d67d17b1SMatthew G. Knepley PetscInt i, j, k; 28255fdea053SToby Isaac 28265fdea053SToby Isaac PetscFunctionBegin; 28275fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 28285fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2829b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 28305fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 28315fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 28325fdea053SToby Isaac 28335fdea053SToby Isaac if (stratum == value) break; 28345fdea053SToby Isaac } 28359566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 283663a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 28375fdea053SToby Isaac sl->sizes[i] = size; 28385fdea053SToby Isaac sl->modes[i] = mode; 28395fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 28405fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 28415fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 28425fdea053SToby Isaac if (perms) { 28435fdea053SToby Isaac PetscInt **ownPerms; 28445fdea053SToby Isaac 28459566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 28465fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 28475fdea053SToby Isaac if (perms[j]) { 28489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2849ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 28505fdea053SToby Isaac } 28515fdea053SToby Isaac } 28525fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 28535fdea053SToby Isaac } 28545fdea053SToby Isaac if (rots) { 28555fdea053SToby Isaac PetscScalar **ownRots; 28565fdea053SToby Isaac 28579566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 28585fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 28595fdea053SToby Isaac if (rots[j]) { 28609566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2861ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 28625fdea053SToby Isaac } 28635fdea053SToby Isaac } 28645fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 28655fdea053SToby Isaac } 28665fdea053SToby Isaac } else { 28678e3a54c0SPierre Jolivet sl->perms[i] = PetscSafePointerPlusOffset(perms, -minOrient); 28688e3a54c0SPierre Jolivet sl->rots[i] = PetscSafePointerPlusOffset(rots, -minOrient); 28695fdea053SToby Isaac } 28703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28715fdea053SToby Isaac } 28725fdea053SToby Isaac 2873d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 2874d71ae5a4SJacob Faibussowitsch { 28755fdea053SToby Isaac PetscInt i, j, numStrata; 28765fdea053SToby Isaac PetscSectionSym_Label *sl; 28775fdea053SToby Isaac DMLabel label; 28785fdea053SToby Isaac 28795fdea053SToby Isaac PetscFunctionBegin; 28805fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 28815fdea053SToby Isaac numStrata = sl->numStrata; 28825fdea053SToby Isaac label = sl->label; 28835fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 28845fdea053SToby Isaac PetscInt point = points[2 * i]; 28855fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 28865fdea053SToby Isaac 28875fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 28885fdea053SToby Isaac if (label->validIS[j]) { 28895fdea053SToby Isaac PetscInt k; 28905fdea053SToby Isaac 28912b4d18a0SMatthew G. Knepley PetscCall(ISLocate(label->points[j], point, &k)); 28925fdea053SToby Isaac if (k >= 0) break; 28935fdea053SToby Isaac } else { 28945fdea053SToby Isaac PetscBool has; 28955fdea053SToby Isaac 28969566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 28975fdea053SToby Isaac if (has) break; 28985fdea053SToby Isaac } 28995fdea053SToby Isaac } 29009371c9d4SSatish 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], 29019371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2902ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2903ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 29045fdea053SToby Isaac } 29053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29065fdea053SToby Isaac } 29075fdea053SToby Isaac 2908d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2909d71ae5a4SJacob Faibussowitsch { 2910b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2911b004864fSMatthew G. Knepley IS valIS; 2912b004864fSMatthew G. Knepley const PetscInt *values; 2913b004864fSMatthew G. Knepley PetscInt Nv, v; 2914b004864fSMatthew G. Knepley 2915b004864fSMatthew G. Knepley PetscFunctionBegin; 29169566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 29179566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 29189566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2919b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2920b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2921b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2922b004864fSMatthew G. Knepley const PetscInt **perms; 2923b004864fSMatthew G. Knepley const PetscScalar **rots; 2924b004864fSMatthew G. Knepley 29259566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 29269566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2927b004864fSMatthew G. Knepley } 29289566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 29293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2930b004864fSMatthew G. Knepley } 2931b004864fSMatthew G. Knepley 2932d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2933d71ae5a4SJacob Faibussowitsch { 2934b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2935b004864fSMatthew G. Knepley DMLabel dlabel; 2936b004864fSMatthew G. Knepley 2937b004864fSMatthew G. Knepley PetscFunctionBegin; 29389566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 29399566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 29409566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 29419566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 29423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2943b004864fSMatthew G. Knepley } 2944b004864fSMatthew G. Knepley 2945d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 2946d71ae5a4SJacob Faibussowitsch { 29475fdea053SToby Isaac PetscSectionSym_Label *sl; 29485fdea053SToby Isaac 29495fdea053SToby Isaac PetscFunctionBegin; 29504dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 29515fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2952b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2953b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 29545fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 29555fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 29565fdea053SToby Isaac sym->data = (void *)sl; 29573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29585fdea053SToby Isaac } 29595fdea053SToby Isaac 29605fdea053SToby Isaac /*@ 29615fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 29625fdea053SToby Isaac 29635fdea053SToby Isaac Collective 29645fdea053SToby Isaac 29655fdea053SToby Isaac Input Parameters: 29665fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 29675fdea053SToby Isaac - label - the label defining the strata 29685fdea053SToby Isaac 29692fe279fdSBarry Smith Output Parameter: 29705fdea053SToby Isaac . sym - the section symmetries 29715fdea053SToby Isaac 29725fdea053SToby Isaac Level: developer 29735fdea053SToby Isaac 297420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 29755fdea053SToby Isaac @*/ 2976d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 2977d71ae5a4SJacob Faibussowitsch { 29785fdea053SToby Isaac PetscFunctionBegin; 29799566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 29809566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 29819566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 29829566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 29833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29845fdea053SToby Isaac } 2985