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 10c58f1c22SToby Isaac /*@C 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)); 37d67d17b1SMatthew G. Knepley 38c58f1c22SToby Isaac (*label)->numStrata = 0; 395aa44df4SToby Isaac (*label)->defaultValue = -1; 40c58f1c22SToby Isaac (*label)->stratumValues = NULL; 41ad8374ffSToby Isaac (*label)->validIS = NULL; 42c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 43c58f1c22SToby Isaac (*label)->points = NULL; 44c58f1c22SToby Isaac (*label)->ht = NULL; 45c58f1c22SToby Isaac (*label)->pStart = -1; 46c58f1c22SToby Isaac (*label)->pEnd = -1; 47c58f1c22SToby Isaac (*label)->bt = NULL; 489566063dSJacob Faibussowitsch PetscCall(PetscHMapICreate(&(*label)->hmap)); 499566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*label, name)); 509f6c5813SMatthew G. Knepley PetscCall(DMLabelSetType(*label, DMLABELCONCRETE)); 513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 529f6c5813SMatthew G. Knepley } 539f6c5813SMatthew G. Knepley 549f6c5813SMatthew G. Knepley /*@C 559f6c5813SMatthew G. Knepley DMLabelSetUp - SetUp a `DMLabel` object 569f6c5813SMatthew G. Knepley 579f6c5813SMatthew G. Knepley Collective 589f6c5813SMatthew G. Knepley 5960225df5SJacob Faibussowitsch Input Parameters: 609f6c5813SMatthew G. Knepley . label - The `DMLabel` 619f6c5813SMatthew G. Knepley 629f6c5813SMatthew G. Knepley Level: intermediate 639f6c5813SMatthew G. Knepley 6420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 659f6c5813SMatthew G. Knepley @*/ 669f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetUp(DMLabel label) 679f6c5813SMatthew G. Knepley { 689f6c5813SMatthew G. Knepley PetscFunctionBegin; 699f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 709f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, setup); 713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 72c58f1c22SToby Isaac } 73c58f1c22SToby Isaac 74c58f1c22SToby Isaac /* 75c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 76c58f1c22SToby Isaac 775b5e7992SMatthew G. Knepley Not collective 785b5e7992SMatthew G. Knepley 79c58f1c22SToby Isaac Input parameter: 8020f4b53cSBarry Smith + label - The `DMLabel` 81c58f1c22SToby Isaac - v - The stratum value 82c58f1c22SToby Isaac 83c58f1c22SToby Isaac Output parameter: 8420f4b53cSBarry Smith . label - The `DMLabel` with stratum in sorted list format 85c58f1c22SToby Isaac 86c58f1c22SToby Isaac Level: developer 87c58f1c22SToby Isaac 8820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()` 89c58f1c22SToby Isaac */ 90d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) 91d71ae5a4SJacob Faibussowitsch { 92277ea44aSLisandro Dalcin IS is; 93b9907514SLisandro Dalcin PetscInt off = 0, *pointArray, p; 94c58f1c22SToby Isaac 953ba16761SJacob Faibussowitsch if ((PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) || label->readonly) return PETSC_SUCCESS; 96c58f1c22SToby Isaac PetscFunctionBegin; 971dca8a05SBarry 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); 989566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v])); 999566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->stratumSizes[v], &pointArray)); 1009566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(label->ht[v], &off, pointArray)); 1019566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1029566063dSJacob Faibussowitsch PetscCall(PetscSortInt(label->stratumSizes[v], pointArray)); 103c58f1c22SToby Isaac if (label->bt) { 104c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 105ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 10663a3b9bcSJacob 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); 1079566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 108c58f1c22SToby Isaac } 109c58f1c22SToby Isaac } 110ba2698f1SMatthew G. Knepley if (label->stratumSizes[v] > 0 && pointArray[label->stratumSizes[v] - 1] == pointArray[0] + label->stratumSizes[v] - 1) { 1119566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, label->stratumSizes[v], pointArray[0], 1, &is)); 1129566063dSJacob Faibussowitsch PetscCall(PetscFree(pointArray)); 113ba2698f1SMatthew G. Knepley } else { 1149566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is)); 115ba2698f1SMatthew G. Knepley } 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 1683ba16761SJacob Faibussowitsch if ((PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) || label->readonly) return PETSC_SUCCESS; 169c58f1c22SToby Isaac PetscFunctionBegin; 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)); 1759566063dSJacob Faibussowitsch 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 4479f6c5813SMatthew G. Knepley PetscErrorCode DMLabelView_Concrete(DMLabel label, PetscViewer viewer) 4489f6c5813SMatthew G. Knepley { 4499f6c5813SMatthew G. Knepley PetscBool iascii; 4509f6c5813SMatthew G. Knepley 4519f6c5813SMatthew G. Knepley PetscFunctionBegin; 4529f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4539f6c5813SMatthew G. Knepley if (iascii) PetscCall(DMLabelView_Concrete_Ascii(label, viewer)); 4543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4559f6c5813SMatthew G. Knepley } 4569f6c5813SMatthew G. Knepley 457c58f1c22SToby Isaac /*@C 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 /*@ 48220f4b53cSBarry Smith DMLabelReset - Destroys internal data structures in a `DMLabel` 483d67d17b1SMatthew G. Knepley 48420f4b53cSBarry Smith Not Collective 4855b5e7992SMatthew G. Knepley 486d67d17b1SMatthew G. Knepley Input Parameter: 48720f4b53cSBarry Smith . label - The `DMLabel` 488d67d17b1SMatthew G. Knepley 489d67d17b1SMatthew G. Knepley Level: beginner 490d67d17b1SMatthew G. Knepley 49120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDestroy()`, `DMLabelCreate()` 492d67d17b1SMatthew G. Knepley @*/ 493d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelReset(DMLabel label) 494d71ae5a4SJacob Faibussowitsch { 495d67d17b1SMatthew G. Knepley PetscInt v; 496d67d17b1SMatthew G. Knepley 497d67d17b1SMatthew G. Knepley PetscFunctionBegin; 498d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 499d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 5009f6c5813SMatthew G. Knepley if (label->ht[v]) PetscCall(PetscHSetIDestroy(&label->ht[v])); 5019566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 502d67d17b1SMatthew G. Knepley } 503b9907514SLisandro Dalcin label->numStrata = 0; 5049566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues)); 5059566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes)); 5069566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht)); 5079566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points)); 5089566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS)); 509f9244615SMatthew G. Knepley label->stratumValues = NULL; 510f9244615SMatthew G. Knepley label->stratumSizes = NULL; 511f9244615SMatthew G. Knepley label->ht = NULL; 512f9244615SMatthew G. Knepley label->points = NULL; 513f9244615SMatthew G. Knepley label->validIS = NULL; 5149566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 515b9907514SLisandro Dalcin label->pStart = -1; 516b9907514SLisandro Dalcin label->pEnd = -1; 5179566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 5183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 519d67d17b1SMatthew G. Knepley } 520d67d17b1SMatthew G. Knepley 521d67d17b1SMatthew G. Knepley /*@ 52220f4b53cSBarry Smith DMLabelDestroy - Destroys a `DMLabel` 52384f0b6dfSMatthew G. Knepley 52420f4b53cSBarry Smith Collective 5255b5e7992SMatthew G. Knepley 52684f0b6dfSMatthew G. Knepley Input Parameter: 52720f4b53cSBarry Smith . label - The `DMLabel` 52884f0b6dfSMatthew G. Knepley 52984f0b6dfSMatthew G. Knepley Level: beginner 53084f0b6dfSMatthew G. Knepley 53120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelReset()`, `DMLabelCreate()` 53284f0b6dfSMatthew G. Knepley @*/ 533d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroy(DMLabel *label) 534d71ae5a4SJacob Faibussowitsch { 535c58f1c22SToby Isaac PetscFunctionBegin; 5363ba16761SJacob Faibussowitsch if (!*label) PetscFunctionReturn(PETSC_SUCCESS); 537d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label), DMLABEL_CLASSID, 1); 5389371c9d4SSatish Balay if (--((PetscObject)(*label))->refct > 0) { 5399371c9d4SSatish Balay *label = NULL; 5403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5419371c9d4SSatish Balay } 5429566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 5439566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 5449566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 5453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 546c58f1c22SToby Isaac } 547c58f1c22SToby Isaac 5489f6c5813SMatthew G. Knepley PetscErrorCode DMLabelDuplicate_Concrete(DMLabel label, DMLabel *labelnew) 5499f6c5813SMatthew G. Knepley { 5509f6c5813SMatthew G. Knepley PetscFunctionBegin; 5519f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 5529f6c5813SMatthew G. Knepley PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 5539f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)(label->points[v]))); 5549f6c5813SMatthew G. Knepley (*labelnew)->points[v] = label->points[v]; 5559f6c5813SMatthew G. Knepley } 5569f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5579f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDuplicate(label->hmap, &(*labelnew)->hmap)); 5583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5599f6c5813SMatthew G. Knepley } 5609f6c5813SMatthew G. Knepley 56184f0b6dfSMatthew G. Knepley /*@ 56220f4b53cSBarry Smith DMLabelDuplicate - Duplicates a `DMLabel` 56384f0b6dfSMatthew G. Knepley 56420f4b53cSBarry Smith Collective 5655b5e7992SMatthew G. Knepley 56684f0b6dfSMatthew G. Knepley Input Parameter: 56720f4b53cSBarry Smith . label - The `DMLabel` 56884f0b6dfSMatthew G. Knepley 56984f0b6dfSMatthew G. Knepley Output Parameter: 57020f4b53cSBarry Smith . labelnew - new label 57184f0b6dfSMatthew G. Knepley 57284f0b6dfSMatthew G. Knepley Level: intermediate 57384f0b6dfSMatthew G. Knepley 57420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 57584f0b6dfSMatthew G. Knepley @*/ 576d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 577d71ae5a4SJacob Faibussowitsch { 578d67d17b1SMatthew G. Knepley const char *name; 579c58f1c22SToby Isaac 580c58f1c22SToby Isaac PetscFunctionBegin; 581d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 5829566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 5839566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 5849566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)label), name, labelnew)); 585c58f1c22SToby Isaac 586c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5875aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 5888dcf10e8SMatthew G. Knepley (*labelnew)->readonly = label->readonly; 5899566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 5909566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 5919f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->ht)); 5929f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->points)); 5939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 5949f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 595c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 596c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 597b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 598c58f1c22SToby Isaac } 599c58f1c22SToby Isaac (*labelnew)->pStart = -1; 600c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 601c58f1c22SToby Isaac (*labelnew)->bt = NULL; 6029f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, duplicate, labelnew); 6033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 604c58f1c22SToby Isaac } 605c58f1c22SToby Isaac 606609dae6eSVaclav Hapla /*@C 60720f4b53cSBarry Smith DMLabelCompare - Compare two `DMLabel` objects 608609dae6eSVaclav Hapla 60920f4b53cSBarry Smith Collective; No Fortran Support 610609dae6eSVaclav Hapla 611609dae6eSVaclav Hapla Input Parameters: 612f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 61320f4b53cSBarry Smith . l0 - First `DMLabel` 61420f4b53cSBarry Smith - l1 - Second `DMLabel` 615609dae6eSVaclav Hapla 616*a4e35b19SJacob Faibussowitsch Output Parameters: 6175efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 6185efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 619609dae6eSVaclav Hapla 620609dae6eSVaclav Hapla Level: intermediate 621609dae6eSVaclav Hapla 622609dae6eSVaclav Hapla Notes: 6235efe38ccSVaclav Hapla The output flag equal is the same on all processes. 62420f4b53cSBarry Smith If it is passed as `NULL` and difference is found, an error is thrown on all processes. 62520f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 626609dae6eSVaclav Hapla 6275efe38ccSVaclav Hapla The output message is set independently on each rank. 62820f4b53cSBarry Smith It is set to `NULL` if no difference was found on the current rank. It must be freed by user. 62920f4b53cSBarry Smith If message is passed as `NULL` and difference is found, the difference description is printed to stderr in synchronized manner. 63020f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 631609dae6eSVaclav Hapla 632609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 633609dae6eSVaclav Hapla 63420f4b53cSBarry Smith The communicator needs to be specified because currently `DMLabel` can live on `PETSC_COMM_SELF` even if the underlying `DM` is parallel. 6355efe38ccSVaclav Hapla 63620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 637609dae6eSVaclav Hapla @*/ 638d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 639d71ae5a4SJacob Faibussowitsch { 640609dae6eSVaclav Hapla const char *name0, *name1; 641609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 6425efe38ccSVaclav Hapla PetscBool eq; 6435efe38ccSVaclav Hapla PetscMPIInt rank; 644609dae6eSVaclav Hapla 645609dae6eSVaclav Hapla PetscFunctionBegin; 6465efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 6475efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6484f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 4); 6494f572ea9SToby Isaac if (message) PetscAssertPointer(message, 5); 6509566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6519566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6529566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 653609dae6eSVaclav Hapla { 654609dae6eSVaclav Hapla PetscInt v0, v1; 655609dae6eSVaclav Hapla 6569566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6579566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6585efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 65948a46eb9SPierre 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)); 660712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6615efe38ccSVaclav Hapla if (!eq) goto finish; 662609dae6eSVaclav Hapla } 663609dae6eSVaclav Hapla { 664609dae6eSVaclav Hapla IS is0, is1; 665609dae6eSVaclav Hapla 6669566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6679566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6689566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6699566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6709566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 67148a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 672712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6735efe38ccSVaclav Hapla if (!eq) goto finish; 674609dae6eSVaclav Hapla } 675609dae6eSVaclav Hapla { 676609dae6eSVaclav Hapla PetscInt i, nValues; 677609dae6eSVaclav Hapla 6789566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 679609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 680609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 681609dae6eSVaclav Hapla PetscInt n; 682609dae6eSVaclav Hapla IS is0, is1; 683609dae6eSVaclav Hapla 6849566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 685609dae6eSVaclav Hapla if (!n) continue; 6869566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6879566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6889566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6899566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6909566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6915efe38ccSVaclav Hapla if (!eq) { 69263a3b9bcSJacob 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)); 6935efe38ccSVaclav Hapla break; 694609dae6eSVaclav Hapla } 695609dae6eSVaclav Hapla } 696712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 697609dae6eSVaclav Hapla } 698609dae6eSVaclav Hapla finish: 6995efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 700609dae6eSVaclav Hapla if (message) { 701609dae6eSVaclav Hapla *message = NULL; 70248a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 7035efe38ccSVaclav Hapla } else { 70448a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 7059566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 7065efe38ccSVaclav Hapla } 7075efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 7085efe38ccSVaclav Hapla if (equal) *equal = eq; 70963a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 7103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 711609dae6eSVaclav Hapla } 712609dae6eSVaclav Hapla 713c6a43d28SMatthew G. Knepley /*@ 714c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 715c6a43d28SMatthew G. Knepley 71620f4b53cSBarry Smith Not Collective 7175b5e7992SMatthew G. Knepley 718c6a43d28SMatthew G. Knepley Input Parameter: 71920f4b53cSBarry Smith . label - The `DMLabel` 720c6a43d28SMatthew G. Knepley 721c6a43d28SMatthew G. Knepley Level: intermediate 722c6a43d28SMatthew G. Knepley 72320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 724c6a43d28SMatthew G. Knepley @*/ 725d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label) 726d71ae5a4SJacob Faibussowitsch { 727c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 728c6a43d28SMatthew G. Knepley 729c6a43d28SMatthew G. Knepley PetscFunctionBegin; 730c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7319566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 732c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 733c6a43d28SMatthew G. Knepley const PetscInt *points; 734c6a43d28SMatthew G. Knepley PetscInt i; 735c6a43d28SMatthew G. Knepley 7369566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 737c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 738c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 739c6a43d28SMatthew G. Knepley 740c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 741c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 742c6a43d28SMatthew G. Knepley } 7439566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 744c6a43d28SMatthew G. Knepley } 745c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 746c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7479566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 7483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 749c6a43d28SMatthew G. Knepley } 750c6a43d28SMatthew G. Knepley 751c6a43d28SMatthew G. Knepley /*@ 752c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 753c6a43d28SMatthew G. Knepley 75420f4b53cSBarry Smith Not Collective 7555b5e7992SMatthew G. Knepley 756c6a43d28SMatthew G. Knepley Input Parameters: 75720f4b53cSBarry Smith + label - The `DMLabel` 758c6a43d28SMatthew G. Knepley . pStart - The smallest point 759c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 760c6a43d28SMatthew G. Knepley 761c6a43d28SMatthew G. Knepley Level: intermediate 762c6a43d28SMatthew G. Knepley 76320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 764c6a43d28SMatthew G. Knepley @*/ 765d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 766d71ae5a4SJacob Faibussowitsch { 767c58f1c22SToby Isaac PetscInt v; 768c58f1c22SToby Isaac 769c58f1c22SToby Isaac PetscFunctionBegin; 770d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7719566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7729566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 773c58f1c22SToby Isaac label->pStart = pStart; 774c58f1c22SToby Isaac label->pEnd = pEnd; 775c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7769566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 777c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 7789f6c5813SMatthew G. Knepley IS pointIS; 779ad8374ffSToby Isaac const PetscInt *points; 780c58f1c22SToby Isaac PetscInt i; 781c58f1c22SToby Isaac 7829f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 7839f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points)); 784c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 785ad8374ffSToby Isaac const PetscInt point = points[i]; 786c58f1c22SToby Isaac 7879f6c5813SMatthew 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); 7889566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 789c58f1c22SToby Isaac } 7909566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 7919f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 792c58f1c22SToby Isaac } 7933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 794c58f1c22SToby Isaac } 795c58f1c22SToby Isaac 796c6a43d28SMatthew G. Knepley /*@ 797c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 798c6a43d28SMatthew G. Knepley 79920f4b53cSBarry Smith Not Collective 8005b5e7992SMatthew G. Knepley 801c6a43d28SMatthew G. Knepley Input Parameter: 80220f4b53cSBarry Smith . label - the `DMLabel` 803c6a43d28SMatthew G. Knepley 804c6a43d28SMatthew G. Knepley Level: intermediate 805c6a43d28SMatthew G. Knepley 80620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 807c6a43d28SMatthew G. Knepley @*/ 808d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label) 809d71ae5a4SJacob Faibussowitsch { 810c58f1c22SToby Isaac PetscFunctionBegin; 811d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 812c58f1c22SToby Isaac label->pStart = -1; 813c58f1c22SToby Isaac label->pEnd = -1; 8149566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 8153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 816c58f1c22SToby Isaac } 817c58f1c22SToby Isaac 818c58f1c22SToby Isaac /*@ 819c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 820c6a43d28SMatthew G. Knepley 82120f4b53cSBarry Smith Not Collective 8225b5e7992SMatthew G. Knepley 823c6a43d28SMatthew G. Knepley Input Parameter: 82420f4b53cSBarry Smith . label - the `DMLabel` 825c6a43d28SMatthew G. Knepley 826c6a43d28SMatthew G. Knepley Output Parameters: 827c6a43d28SMatthew G. Knepley + pStart - The smallest point 828c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 829c6a43d28SMatthew G. Knepley 830c6a43d28SMatthew G. Knepley Level: intermediate 831c6a43d28SMatthew G. Knepley 83220f4b53cSBarry Smith Note: 83320f4b53cSBarry Smith This will compute an index for the label if one does not exist. 83420f4b53cSBarry Smith 83520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 836c6a43d28SMatthew G. Knepley @*/ 837d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 838d71ae5a4SJacob Faibussowitsch { 839c6a43d28SMatthew G. Knepley PetscFunctionBegin; 840c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8419566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 842c6a43d28SMatthew G. Knepley if (pStart) { 8434f572ea9SToby Isaac PetscAssertPointer(pStart, 2); 844c6a43d28SMatthew G. Knepley *pStart = label->pStart; 845c6a43d28SMatthew G. Knepley } 846c6a43d28SMatthew G. Knepley if (pEnd) { 8474f572ea9SToby Isaac PetscAssertPointer(pEnd, 3); 848c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 849c6a43d28SMatthew G. Knepley } 8503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 851c6a43d28SMatthew G. Knepley } 852c6a43d28SMatthew G. Knepley 853c6a43d28SMatthew G. Knepley /*@ 854c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 855c58f1c22SToby Isaac 85620f4b53cSBarry Smith Not Collective 8575b5e7992SMatthew G. Knepley 858c58f1c22SToby Isaac Input Parameters: 85920f4b53cSBarry Smith + label - the `DMLabel` 860c58f1c22SToby Isaac - value - the value 861c58f1c22SToby Isaac 862c58f1c22SToby Isaac Output Parameter: 863c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 864c58f1c22SToby Isaac 865c58f1c22SToby Isaac Level: developer 866c58f1c22SToby Isaac 86720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 868c58f1c22SToby Isaac @*/ 869d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 870d71ae5a4SJacob Faibussowitsch { 871c58f1c22SToby Isaac PetscInt v; 872c58f1c22SToby Isaac 873c58f1c22SToby Isaac PetscFunctionBegin; 874d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8754f572ea9SToby Isaac PetscAssertPointer(contains, 3); 8769566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8770c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 8783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 879c58f1c22SToby Isaac } 880c58f1c22SToby Isaac 881c58f1c22SToby Isaac /*@ 882c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 883c58f1c22SToby Isaac 88420f4b53cSBarry Smith Not Collective 8855b5e7992SMatthew G. Knepley 886c58f1c22SToby Isaac Input Parameters: 88720f4b53cSBarry Smith + label - the `DMLabel` 888c58f1c22SToby Isaac - point - the point 889c58f1c22SToby Isaac 890c58f1c22SToby Isaac Output Parameter: 891c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 892c58f1c22SToby Isaac 893c58f1c22SToby Isaac Level: developer 894c58f1c22SToby Isaac 89520f4b53cSBarry Smith Note: 89620f4b53cSBarry Smith The user must call `DMLabelCreateIndex()` before this function. 89720f4b53cSBarry Smith 89820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 899c58f1c22SToby Isaac @*/ 900d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 901d71ae5a4SJacob Faibussowitsch { 902c58f1c22SToby Isaac PetscFunctionBeginHot; 903d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9044f572ea9SToby Isaac PetscAssertPointer(contains, 3); 9059566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 90676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 90728b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 90863a3b9bcSJacob 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); 90976bd3646SJed Brown } 910c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 9113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 912c58f1c22SToby Isaac } 913c58f1c22SToby Isaac 914c58f1c22SToby Isaac /*@ 915c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 916c58f1c22SToby Isaac 91720f4b53cSBarry Smith Not Collective 9185b5e7992SMatthew G. Knepley 919c58f1c22SToby Isaac Input Parameters: 92020f4b53cSBarry Smith + label - the `DMLabel` 921c58f1c22SToby Isaac . value - the stratum value 922c58f1c22SToby Isaac - point - the point 923c58f1c22SToby Isaac 924c58f1c22SToby Isaac Output Parameter: 925c58f1c22SToby Isaac . contains - true if the stratum contains the point 926c58f1c22SToby Isaac 927c58f1c22SToby Isaac Level: intermediate 928c58f1c22SToby Isaac 92920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 930c58f1c22SToby Isaac @*/ 931d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 932d71ae5a4SJacob Faibussowitsch { 9330c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 934d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9354f572ea9SToby Isaac PetscAssertPointer(contains, 4); 936cffad2c9SToby Isaac if (value == label->defaultValue) { 937cffad2c9SToby Isaac PetscInt pointVal; 9380c3c4a36SLisandro Dalcin 939cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 940cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 941cffad2c9SToby Isaac } else { 942cffad2c9SToby Isaac PetscInt v; 943cffad2c9SToby Isaac 944cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 945cffad2c9SToby Isaac if (v >= 0) { 9469f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 9479f6c5813SMatthew G. Knepley IS is; 948c58f1c22SToby Isaac PetscInt i; 949c58f1c22SToby Isaac 9509f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 9519f6c5813SMatthew G. Knepley PetscCall(ISLocate(is, point, &i)); 9529f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 953cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 954c58f1c22SToby Isaac } else { 955cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 956cffad2c9SToby Isaac } 957cffad2c9SToby Isaac } else { // value is not present 958cffad2c9SToby Isaac *contains = PETSC_FALSE; 959cffad2c9SToby Isaac } 960c58f1c22SToby Isaac } 9613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 962c58f1c22SToby Isaac } 963c58f1c22SToby Isaac 96484f0b6dfSMatthew G. Knepley /*@ 96520f4b53cSBarry Smith DMLabelGetDefaultValue - Get the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9665aa44df4SToby Isaac When a label is created, it is initialized to -1. 9675aa44df4SToby Isaac 96820f4b53cSBarry Smith Not Collective 9695b5e7992SMatthew G. Knepley 97060225df5SJacob Faibussowitsch Input Parameter: 97120f4b53cSBarry Smith . label - a `DMLabel` object 9725aa44df4SToby Isaac 97360225df5SJacob Faibussowitsch Output Parameter: 9745aa44df4SToby Isaac . defaultValue - the default value 9755aa44df4SToby Isaac 9765aa44df4SToby Isaac Level: beginner 9775aa44df4SToby Isaac 97820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 97984f0b6dfSMatthew G. Knepley @*/ 980d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 981d71ae5a4SJacob Faibussowitsch { 9825aa44df4SToby Isaac PetscFunctionBegin; 983d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9845aa44df4SToby Isaac *defaultValue = label->defaultValue; 9853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9865aa44df4SToby Isaac } 9875aa44df4SToby Isaac 98884f0b6dfSMatthew G. Knepley /*@ 98920f4b53cSBarry Smith DMLabelSetDefaultValue - Set the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9905aa44df4SToby Isaac When a label is created, it is initialized to -1. 9915aa44df4SToby Isaac 99220f4b53cSBarry Smith Not Collective 9935b5e7992SMatthew G. Knepley 99460225df5SJacob Faibussowitsch Input Parameter: 99520f4b53cSBarry Smith . label - a `DMLabel` object 9965aa44df4SToby Isaac 99760225df5SJacob Faibussowitsch Output Parameter: 9985aa44df4SToby Isaac . defaultValue - the default value 9995aa44df4SToby Isaac 10005aa44df4SToby Isaac Level: beginner 10015aa44df4SToby Isaac 100220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 100384f0b6dfSMatthew G. Knepley @*/ 1004d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 1005d71ae5a4SJacob Faibussowitsch { 10065aa44df4SToby Isaac PetscFunctionBegin; 1007d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10085aa44df4SToby Isaac label->defaultValue = defaultValue; 10093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10105aa44df4SToby Isaac } 10115aa44df4SToby Isaac 1012c58f1c22SToby Isaac /*@ 101320f4b53cSBarry 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 101420f4b53cSBarry Smith `DMLabelSetDefaultValue()`) 1015c58f1c22SToby Isaac 101620f4b53cSBarry Smith Not Collective 10175b5e7992SMatthew G. Knepley 1018c58f1c22SToby Isaac Input Parameters: 101920f4b53cSBarry Smith + label - the `DMLabel` 1020c58f1c22SToby Isaac - point - the point 1021c58f1c22SToby Isaac 1022c58f1c22SToby Isaac Output Parameter: 10238e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 1024c58f1c22SToby Isaac 1025c58f1c22SToby Isaac Level: intermediate 1026c58f1c22SToby Isaac 102720f4b53cSBarry Smith Note: 102820f4b53cSBarry Smith A label may assign multiple values to a point. No guarantees are made about which value is returned in that case. 102920f4b53cSBarry Smith Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum. 103020f4b53cSBarry Smith 103120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1032c58f1c22SToby Isaac @*/ 1033d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 1034d71ae5a4SJacob Faibussowitsch { 1035c58f1c22SToby Isaac PetscInt v; 1036c58f1c22SToby Isaac 10370c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 1038d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10394f572ea9SToby Isaac PetscAssertPointer(value, 3); 10405aa44df4SToby Isaac *value = label->defaultValue; 1041c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 10429f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 10439f6c5813SMatthew G. Knepley IS is; 1044c58f1c22SToby Isaac PetscInt i; 1045c58f1c22SToby Isaac 10469f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 10479566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 10489f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1049c58f1c22SToby Isaac if (i >= 0) { 1050c58f1c22SToby Isaac *value = label->stratumValues[v]; 1051c58f1c22SToby Isaac break; 1052c58f1c22SToby Isaac } 1053c58f1c22SToby Isaac } else { 1054c58f1c22SToby Isaac PetscBool has; 1055c58f1c22SToby Isaac 10569566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 1057c58f1c22SToby Isaac if (has) { 1058c58f1c22SToby Isaac *value = label->stratumValues[v]; 1059c58f1c22SToby Isaac break; 1060c58f1c22SToby Isaac } 1061c58f1c22SToby Isaac } 1062c58f1c22SToby Isaac } 10633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1064c58f1c22SToby Isaac } 1065c58f1c22SToby Isaac 1066c58f1c22SToby Isaac /*@ 106720f4b53cSBarry 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 106820f4b53cSBarry Smith be changed with `DMLabelSetDefaultValue()` to something different), then this function will do nothing. 1069c58f1c22SToby Isaac 107020f4b53cSBarry Smith Not Collective 10715b5e7992SMatthew G. Knepley 1072c58f1c22SToby Isaac Input Parameters: 107320f4b53cSBarry Smith + label - the `DMLabel` 1074c58f1c22SToby Isaac . point - the point 1075c58f1c22SToby Isaac - value - The point value 1076c58f1c22SToby Isaac 1077c58f1c22SToby Isaac Level: intermediate 1078c58f1c22SToby Isaac 107920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1080c58f1c22SToby Isaac @*/ 1081d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1082d71ae5a4SJacob Faibussowitsch { 1083c58f1c22SToby Isaac PetscInt v; 1084c58f1c22SToby Isaac 1085c58f1c22SToby Isaac PetscFunctionBegin; 1086d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10870c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10883ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 10899f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 10909566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1091c58f1c22SToby Isaac /* Set key */ 10929566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10939566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 10943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1095c58f1c22SToby Isaac } 1096c58f1c22SToby Isaac 1097c58f1c22SToby Isaac /*@ 1098c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1099c58f1c22SToby Isaac 110020f4b53cSBarry Smith Not Collective 11015b5e7992SMatthew G. Knepley 1102c58f1c22SToby Isaac Input Parameters: 110320f4b53cSBarry Smith + label - the `DMLabel` 1104c58f1c22SToby Isaac . point - the point 1105c58f1c22SToby Isaac - value - The point value 1106c58f1c22SToby Isaac 1107c58f1c22SToby Isaac Level: intermediate 1108c58f1c22SToby Isaac 110920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1110c58f1c22SToby Isaac @*/ 1111d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1112d71ae5a4SJacob Faibussowitsch { 1113ad8374ffSToby Isaac PetscInt v; 1114c58f1c22SToby Isaac 1115c58f1c22SToby Isaac PetscFunctionBegin; 1116d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11179f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 1118c58f1c22SToby Isaac /* Find label value */ 11199566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 11203ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 11210c3c4a36SLisandro Dalcin 1122eeed21e7SToby Isaac if (label->bt) { 112363a3b9bcSJacob 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); 11249566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1125eeed21e7SToby Isaac } 11260c3c4a36SLisandro Dalcin 11270c3c4a36SLisandro Dalcin /* Delete key */ 11289566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11299566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 11303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1131c58f1c22SToby Isaac } 1132c58f1c22SToby Isaac 1133c58f1c22SToby Isaac /*@ 113420f4b53cSBarry Smith DMLabelInsertIS - Set all points in the `IS` to a value 1135c58f1c22SToby Isaac 113620f4b53cSBarry Smith Not Collective 11375b5e7992SMatthew G. Knepley 1138c58f1c22SToby Isaac Input Parameters: 113920f4b53cSBarry Smith + label - the `DMLabel` 11402fe279fdSBarry Smith . is - the point `IS` 1141c58f1c22SToby Isaac - value - The point value 1142c58f1c22SToby Isaac 1143c58f1c22SToby Isaac Level: intermediate 1144c58f1c22SToby Isaac 114520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1146c58f1c22SToby Isaac @*/ 1147d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1148d71ae5a4SJacob Faibussowitsch { 11490c3c4a36SLisandro Dalcin PetscInt v, n, p; 1150c58f1c22SToby Isaac const PetscInt *points; 1151c58f1c22SToby Isaac 1152c58f1c22SToby Isaac PetscFunctionBegin; 1153d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1154c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 11550c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11563ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 11579f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 11589566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 11590c3c4a36SLisandro Dalcin /* Set keys */ 11609566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11619566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 11629566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 11639566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 11649566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 11653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1166c58f1c22SToby Isaac } 1167c58f1c22SToby Isaac 116884f0b6dfSMatthew G. Knepley /*@ 116920f4b53cSBarry Smith DMLabelGetNumValues - Get the number of values that the `DMLabel` takes 117084f0b6dfSMatthew G. Knepley 117120f4b53cSBarry Smith Not Collective 11725b5e7992SMatthew G. Knepley 117384f0b6dfSMatthew G. Knepley Input Parameter: 117420f4b53cSBarry Smith . label - the `DMLabel` 117584f0b6dfSMatthew G. Knepley 117601d2d390SJose E. Roman Output Parameter: 117784f0b6dfSMatthew G. Knepley . numValues - the number of values 117884f0b6dfSMatthew G. Knepley 117984f0b6dfSMatthew G. Knepley Level: intermediate 118084f0b6dfSMatthew G. Knepley 118120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 118284f0b6dfSMatthew G. Knepley @*/ 1183d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1184d71ae5a4SJacob Faibussowitsch { 1185c58f1c22SToby Isaac PetscFunctionBegin; 1186d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11874f572ea9SToby Isaac PetscAssertPointer(numValues, 2); 1188c58f1c22SToby Isaac *numValues = label->numStrata; 11893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1190c58f1c22SToby Isaac } 1191c58f1c22SToby Isaac 119284f0b6dfSMatthew G. Knepley /*@ 119320f4b53cSBarry Smith DMLabelGetValueIS - Get an `IS` of all values that the `DMlabel` takes 119484f0b6dfSMatthew G. Knepley 119520f4b53cSBarry Smith Not Collective 11965b5e7992SMatthew G. Knepley 119784f0b6dfSMatthew G. Knepley Input Parameter: 119820f4b53cSBarry Smith . label - the `DMLabel` 119984f0b6dfSMatthew G. Knepley 120001d2d390SJose E. Roman Output Parameter: 120160225df5SJacob Faibussowitsch . values - the value `IS` 120284f0b6dfSMatthew G. Knepley 120384f0b6dfSMatthew G. Knepley Level: intermediate 120484f0b6dfSMatthew G. Knepley 12051d04cbbeSVaclav Hapla Notes: 120620f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 120720f4b53cSBarry Smith Strata which are allocated but empty [`DMLabelGetStratumSize()` yields 0] are counted. 120820f4b53cSBarry Smith If you need to count only nonempty strata, use `DMLabelGetNonEmptyStratumValuesIS()`. 12091d04cbbeSVaclav Hapla 121020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 121184f0b6dfSMatthew G. Knepley @*/ 1212d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1213d71ae5a4SJacob Faibussowitsch { 1214c58f1c22SToby Isaac PetscFunctionBegin; 1215d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12164f572ea9SToby Isaac PetscAssertPointer(values, 2); 12179566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1219c58f1c22SToby Isaac } 1220c58f1c22SToby Isaac 122184f0b6dfSMatthew G. Knepley /*@ 122220f4b53cSBarry Smith DMLabelGetNonEmptyStratumValuesIS - Get an `IS` of all values that the `DMlabel` takes 12231d04cbbeSVaclav Hapla 122420f4b53cSBarry Smith Not Collective 12251d04cbbeSVaclav Hapla 12261d04cbbeSVaclav Hapla Input Parameter: 122720f4b53cSBarry Smith . label - the `DMLabel` 12281d04cbbeSVaclav Hapla 1229d5b43468SJose E. Roman Output Parameter: 123060225df5SJacob Faibussowitsch . values - the value `IS` 12311d04cbbeSVaclav Hapla 12321d04cbbeSVaclav Hapla Level: intermediate 12331d04cbbeSVaclav Hapla 12341d04cbbeSVaclav Hapla Notes: 123520f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 123620f4b53cSBarry Smith This is similar to `DMLabelGetValueIS()` but counts only nonempty strata. 12371d04cbbeSVaclav Hapla 123820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 12391d04cbbeSVaclav Hapla @*/ 1240d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 1241d71ae5a4SJacob Faibussowitsch { 12421d04cbbeSVaclav Hapla PetscInt i, j; 12431d04cbbeSVaclav Hapla PetscInt *valuesArr; 12441d04cbbeSVaclav Hapla 12451d04cbbeSVaclav Hapla PetscFunctionBegin; 12461d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12474f572ea9SToby Isaac PetscAssertPointer(values, 2); 12489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 12491d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 12501d04cbbeSVaclav Hapla PetscInt n; 12511d04cbbeSVaclav Hapla 12529566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 12531d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 12541d04cbbeSVaclav Hapla } 12551d04cbbeSVaclav Hapla if (j == label->numStrata) { 12569566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12571d04cbbeSVaclav Hapla } else { 12589566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 12591d04cbbeSVaclav Hapla } 12609566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 12613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12621d04cbbeSVaclav Hapla } 12631d04cbbeSVaclav Hapla 12641d04cbbeSVaclav Hapla /*@ 126520f4b53cSBarry Smith DMLabelGetValueIndex - Get the index of a given value in the list of values for the `DMlabel`, or -1 if it is not present 1266d123abd9SMatthew G. Knepley 126720f4b53cSBarry Smith Not Collective 1268d123abd9SMatthew G. Knepley 1269d123abd9SMatthew G. Knepley Input Parameters: 127020f4b53cSBarry Smith + label - the `DMLabel` 127197bb3fdcSJose E. Roman - value - the value 1272d123abd9SMatthew G. Knepley 127301d2d390SJose E. Roman Output Parameter: 1274d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1275d123abd9SMatthew G. Knepley 1276d123abd9SMatthew G. Knepley Level: intermediate 1277d123abd9SMatthew G. Knepley 127820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1279d123abd9SMatthew G. Knepley @*/ 1280d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1281d71ae5a4SJacob Faibussowitsch { 1282d123abd9SMatthew G. Knepley PetscInt v; 1283d123abd9SMatthew G. Knepley 1284d123abd9SMatthew G. Knepley PetscFunctionBegin; 1285d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12864f572ea9SToby Isaac PetscAssertPointer(index, 3); 1287d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 12889371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 12899371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1290d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1291d123abd9SMatthew G. Knepley else *index = v; 12923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1293d123abd9SMatthew G. Knepley } 1294d123abd9SMatthew G. Knepley 1295d123abd9SMatthew G. Knepley /*@ 129684f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 129784f0b6dfSMatthew G. Knepley 129820f4b53cSBarry Smith Not Collective 12995b5e7992SMatthew G. Knepley 130084f0b6dfSMatthew G. Knepley Input Parameters: 130120f4b53cSBarry Smith + label - the `DMLabel` 130284f0b6dfSMatthew G. Knepley - value - the stratum value 130384f0b6dfSMatthew G. Knepley 130401d2d390SJose E. Roman Output Parameter: 130584f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 130684f0b6dfSMatthew G. Knepley 130784f0b6dfSMatthew G. Knepley Level: intermediate 130884f0b6dfSMatthew G. Knepley 130920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 131084f0b6dfSMatthew G. Knepley @*/ 1311d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1312d71ae5a4SJacob Faibussowitsch { 1313fada774cSMatthew G. Knepley PetscInt v; 1314fada774cSMatthew G. Knepley 1315fada774cSMatthew G. Knepley PetscFunctionBegin; 1316d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13174f572ea9SToby Isaac PetscAssertPointer(exists, 3); 13189566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13190c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 13203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1321fada774cSMatthew G. Knepley } 1322fada774cSMatthew G. Knepley 132384f0b6dfSMatthew G. Knepley /*@ 132484f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 132584f0b6dfSMatthew G. Knepley 132620f4b53cSBarry Smith Not Collective 13275b5e7992SMatthew G. Knepley 132884f0b6dfSMatthew G. Knepley Input Parameters: 132920f4b53cSBarry Smith + label - the `DMLabel` 133084f0b6dfSMatthew G. Knepley - value - the stratum value 133184f0b6dfSMatthew G. Knepley 133201d2d390SJose E. Roman Output Parameter: 133384f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 133484f0b6dfSMatthew G. Knepley 133584f0b6dfSMatthew G. Knepley Level: intermediate 133684f0b6dfSMatthew G. Knepley 133720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 133884f0b6dfSMatthew G. Knepley @*/ 1339d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1340d71ae5a4SJacob Faibussowitsch { 1341c58f1c22SToby Isaac PetscInt v; 1342c58f1c22SToby Isaac 1343c58f1c22SToby Isaac PetscFunctionBegin; 1344d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13454f572ea9SToby Isaac PetscAssertPointer(size, 3); 13469566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13479566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 13483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1349c58f1c22SToby Isaac } 1350c58f1c22SToby Isaac 135184f0b6dfSMatthew G. Knepley /*@ 135284f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 135384f0b6dfSMatthew G. Knepley 135420f4b53cSBarry Smith Not Collective 13555b5e7992SMatthew G. Knepley 135684f0b6dfSMatthew G. Knepley Input Parameters: 135720f4b53cSBarry Smith + label - the `DMLabel` 135884f0b6dfSMatthew G. Knepley - value - the stratum value 135984f0b6dfSMatthew G. Knepley 136001d2d390SJose E. Roman Output Parameters: 136184f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 136284f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 136384f0b6dfSMatthew G. Knepley 136484f0b6dfSMatthew G. Knepley Level: intermediate 136584f0b6dfSMatthew G. Knepley 136620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 136784f0b6dfSMatthew G. Knepley @*/ 1368d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1369d71ae5a4SJacob Faibussowitsch { 13709f6c5813SMatthew G. Knepley IS is; 13710c3c4a36SLisandro Dalcin PetscInt v, min, max; 1372c58f1c22SToby Isaac 1373c58f1c22SToby Isaac PetscFunctionBegin; 1374d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13759371c9d4SSatish Balay if (start) { 13764f572ea9SToby Isaac PetscAssertPointer(start, 3); 13779371c9d4SSatish Balay *start = -1; 13789371c9d4SSatish Balay } 13799371c9d4SSatish Balay if (end) { 13804f572ea9SToby Isaac PetscAssertPointer(end, 4); 13819371c9d4SSatish Balay *end = -1; 13829371c9d4SSatish Balay } 13839566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13843ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 13859566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13863ba16761SJacob Faibussowitsch if (label->stratumSizes[v] <= 0) PetscFunctionReturn(PETSC_SUCCESS); 13879f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 13889f6c5813SMatthew G. Knepley PetscCall(ISGetMinMax(is, &min, &max)); 13899f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1390d6cb179aSToby Isaac if (start) *start = min; 1391d6cb179aSToby Isaac if (end) *end = max + 1; 13923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1393c58f1c22SToby Isaac } 1394c58f1c22SToby Isaac 13959f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetStratumIS_Concrete(DMLabel label, PetscInt v, IS *pointIS) 13969f6c5813SMatthew G. Knepley { 13979f6c5813SMatthew G. Knepley PetscFunctionBegin; 13989f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)label->points[v])); 13999f6c5813SMatthew G. Knepley *pointIS = label->points[v]; 14003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14019f6c5813SMatthew G. Knepley } 14029f6c5813SMatthew G. Knepley 140384f0b6dfSMatthew G. Knepley /*@ 140420f4b53cSBarry Smith DMLabelGetStratumIS - Get an `IS` with the stratum points 140584f0b6dfSMatthew G. Knepley 140620f4b53cSBarry Smith Not Collective 14075b5e7992SMatthew G. Knepley 140884f0b6dfSMatthew G. Knepley Input Parameters: 140920f4b53cSBarry Smith + label - the `DMLabel` 141084f0b6dfSMatthew G. Knepley - value - the stratum value 141184f0b6dfSMatthew G. Knepley 141201d2d390SJose E. Roman Output Parameter: 141384f0b6dfSMatthew G. Knepley . points - The stratum points 141484f0b6dfSMatthew G. Knepley 141584f0b6dfSMatthew G. Knepley Level: intermediate 141684f0b6dfSMatthew G. Knepley 1417593ce467SVaclav Hapla Notes: 141820f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 141920f4b53cSBarry Smith Returns `NULL` if the stratum is empty. 1420593ce467SVaclav Hapla 142120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 142284f0b6dfSMatthew G. Knepley @*/ 1423d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1424d71ae5a4SJacob Faibussowitsch { 1425c58f1c22SToby Isaac PetscInt v; 1426c58f1c22SToby Isaac 1427c58f1c22SToby Isaac PetscFunctionBegin; 1428d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14294f572ea9SToby Isaac PetscAssertPointer(points, 3); 1430c58f1c22SToby Isaac *points = NULL; 14319566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14323ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14339566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14349f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, points); 14353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1436c58f1c22SToby Isaac } 1437c58f1c22SToby Isaac 143884f0b6dfSMatthew G. Knepley /*@ 143920f4b53cSBarry Smith DMLabelSetStratumIS - Set the stratum points using an `IS` 144084f0b6dfSMatthew G. Knepley 144120f4b53cSBarry Smith Not Collective 14425b5e7992SMatthew G. Knepley 144384f0b6dfSMatthew G. Knepley Input Parameters: 144420f4b53cSBarry Smith + label - the `DMLabel` 144584f0b6dfSMatthew G. Knepley . value - the stratum value 144660225df5SJacob Faibussowitsch - is - The stratum points 144784f0b6dfSMatthew G. Knepley 144884f0b6dfSMatthew G. Knepley Level: intermediate 144984f0b6dfSMatthew G. Knepley 145020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 145184f0b6dfSMatthew G. Knepley @*/ 1452d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 1453d71ae5a4SJacob Faibussowitsch { 14540c3c4a36SLisandro Dalcin PetscInt v; 14554de306b1SToby Isaac 14564de306b1SToby Isaac PetscFunctionBegin; 1457d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1458d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 14599f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 14609566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 14613ba16761SJacob Faibussowitsch if (is == label->points[v]) PetscFunctionReturn(PETSC_SUCCESS); 14629566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 14639566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &(label->stratumSizes[v]))); 14649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 14659566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 14660c3c4a36SLisandro Dalcin label->points[v] = is; 14670c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 14689566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 14694de306b1SToby Isaac if (label->bt) { 14704de306b1SToby Isaac const PetscInt *points; 14714de306b1SToby Isaac PetscInt p; 14724de306b1SToby Isaac 14739566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 14744de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 14754de306b1SToby Isaac const PetscInt point = points[p]; 14764de306b1SToby Isaac 147763a3b9bcSJacob 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); 14789566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 14794de306b1SToby Isaac } 14804de306b1SToby Isaac } 14813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14824de306b1SToby Isaac } 14834de306b1SToby Isaac 148484f0b6dfSMatthew G. Knepley /*@ 148584f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 14864de306b1SToby Isaac 148720f4b53cSBarry Smith Not Collective 14885b5e7992SMatthew G. Knepley 148984f0b6dfSMatthew G. Knepley Input Parameters: 149020f4b53cSBarry Smith + label - the `DMLabel` 149184f0b6dfSMatthew G. Knepley - value - the stratum value 149284f0b6dfSMatthew G. Knepley 149384f0b6dfSMatthew G. Knepley Level: intermediate 149484f0b6dfSMatthew G. Knepley 149520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 149684f0b6dfSMatthew G. Knepley @*/ 1497d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1498d71ae5a4SJacob Faibussowitsch { 1499c58f1c22SToby Isaac PetscInt v; 1500c58f1c22SToby Isaac 1501c58f1c22SToby Isaac PetscFunctionBegin; 1502d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15039f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 15049566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15053ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15064de306b1SToby Isaac if (label->validIS[v]) { 15074de306b1SToby Isaac if (label->bt) { 1508c58f1c22SToby Isaac PetscInt i; 1509ad8374ffSToby Isaac const PetscInt *points; 1510c58f1c22SToby Isaac 15119566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1512c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1513ad8374ffSToby Isaac const PetscInt point = points[i]; 1514c58f1c22SToby Isaac 151563a3b9bcSJacob 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); 15169566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1517c58f1c22SToby Isaac } 15189566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1519c58f1c22SToby Isaac } 1520c58f1c22SToby Isaac label->stratumSizes[v] = 0; 15219566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 15229566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 15239566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 15249566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1525c58f1c22SToby Isaac } else { 15269566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1527c58f1c22SToby Isaac } 15283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1529c58f1c22SToby Isaac } 1530c58f1c22SToby Isaac 153184f0b6dfSMatthew G. Knepley /*@ 1532412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1533412e9a14SMatthew G. Knepley 153420f4b53cSBarry Smith Not Collective 1535412e9a14SMatthew G. Knepley 1536412e9a14SMatthew G. Knepley Input Parameters: 153720f4b53cSBarry Smith + label - The `DMLabel` 1538412e9a14SMatthew G. Knepley . value - The label value for all points 1539412e9a14SMatthew G. Knepley . pStart - The first point 1540412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1541412e9a14SMatthew G. Knepley 1542412e9a14SMatthew G. Knepley Level: intermediate 1543412e9a14SMatthew G. Knepley 154420f4b53cSBarry Smith Note: 154520f4b53cSBarry Smith The marks points are [`pStart`, `pEnd`), and only the bounds are stored. 154620f4b53cSBarry Smith 154720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1548412e9a14SMatthew G. Knepley @*/ 1549d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1550d71ae5a4SJacob Faibussowitsch { 1551412e9a14SMatthew G. Knepley IS pIS; 1552412e9a14SMatthew G. Knepley 1553412e9a14SMatthew G. Knepley PetscFunctionBegin; 15549566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 15559566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 15569566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 15573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1558412e9a14SMatthew G. Knepley } 1559412e9a14SMatthew G. Knepley 1560412e9a14SMatthew G. Knepley /*@ 1561d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1562d123abd9SMatthew G. Knepley 156320f4b53cSBarry Smith Not Collective 1564d123abd9SMatthew G. Knepley 1565d123abd9SMatthew G. Knepley Input Parameters: 156620f4b53cSBarry Smith + label - The `DMLabel` 1567d123abd9SMatthew G. Knepley . value - The label value 1568d123abd9SMatthew G. Knepley - p - A point with this value 1569d123abd9SMatthew G. Knepley 1570d123abd9SMatthew G. Knepley Output Parameter: 1571d123abd9SMatthew 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 1572d123abd9SMatthew G. Knepley 1573d123abd9SMatthew G. Knepley Level: intermediate 1574d123abd9SMatthew G. Knepley 157520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1576d123abd9SMatthew G. Knepley @*/ 1577d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1578d71ae5a4SJacob Faibussowitsch { 15799f6c5813SMatthew G. Knepley IS pointIS; 1580d123abd9SMatthew G. Knepley const PetscInt *indices; 1581d123abd9SMatthew G. Knepley PetscInt v; 1582d123abd9SMatthew G. Knepley 1583d123abd9SMatthew G. Knepley PetscFunctionBegin; 1584d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15854f572ea9SToby Isaac PetscAssertPointer(index, 4); 1586d123abd9SMatthew G. Knepley *index = -1; 15879566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15883ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15899566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 15909f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 15919f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &indices)); 15929566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 15939f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(pointIS, &indices)); 15949f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 15953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1596d123abd9SMatthew G. Knepley } 1597d123abd9SMatthew G. Knepley 1598d123abd9SMatthew G. Knepley /*@ 159920f4b53cSBarry Smith DMLabelFilter - Remove all points outside of [`start`, `end`) 160084f0b6dfSMatthew G. Knepley 160120f4b53cSBarry Smith Not Collective 16025b5e7992SMatthew G. Knepley 160384f0b6dfSMatthew G. Knepley Input Parameters: 160420f4b53cSBarry Smith + label - the `DMLabel` 160522cd2cdaSVaclav Hapla . start - the first point kept 160622cd2cdaSVaclav Hapla - end - one more than the last point kept 160784f0b6dfSMatthew G. Knepley 160884f0b6dfSMatthew G. Knepley Level: intermediate 160984f0b6dfSMatthew G. Knepley 161020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 161184f0b6dfSMatthew G. Knepley @*/ 1612d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1613d71ae5a4SJacob Faibussowitsch { 1614c58f1c22SToby Isaac PetscInt v; 1615c58f1c22SToby Isaac 1616c58f1c22SToby Isaac PetscFunctionBegin; 1617d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16189f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16199566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 16209566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16219f6c5813SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 16229f6c5813SMatthew G. Knepley PetscCall(ISGeneralFilter(label->points[v], start, end)); 16239f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(label->points[v], &label->stratumSizes[v])); 16249f6c5813SMatthew G. Knepley } 16259566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 16263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1627c58f1c22SToby Isaac } 1628c58f1c22SToby Isaac 162984f0b6dfSMatthew G. Knepley /*@ 163084f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 163184f0b6dfSMatthew G. Knepley 163220f4b53cSBarry Smith Not Collective 16335b5e7992SMatthew G. Knepley 163484f0b6dfSMatthew G. Knepley Input Parameters: 163520f4b53cSBarry Smith + label - the `DMLabel` 163684f0b6dfSMatthew G. Knepley - permutation - the point permutation 163784f0b6dfSMatthew G. Knepley 163884f0b6dfSMatthew G. Knepley Output Parameter: 163960225df5SJacob Faibussowitsch . labelNew - the new label containing the permuted points 164084f0b6dfSMatthew G. Knepley 164184f0b6dfSMatthew G. Knepley Level: intermediate 164284f0b6dfSMatthew G. Knepley 164320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 164484f0b6dfSMatthew G. Knepley @*/ 1645d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1646d71ae5a4SJacob Faibussowitsch { 1647c58f1c22SToby Isaac const PetscInt *perm; 1648c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1649c58f1c22SToby Isaac 1650c58f1c22SToby Isaac PetscFunctionBegin; 1651d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1652d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 16539f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16549566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16559566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 16569566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 16579566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 16589566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1659c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1660c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1661ad8374ffSToby Isaac const PetscInt *points; 1662ad8374ffSToby Isaac PetscInt *pointsNew; 1663c58f1c22SToby Isaac 16649566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 16659f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(size, &pointsNew)); 1666c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1667ad8374ffSToby Isaac const PetscInt point = points[q]; 1668c58f1c22SToby Isaac 166963a3b9bcSJacob 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); 1670ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1671c58f1c22SToby Isaac } 16729566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 16739566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 16749566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1675fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 16769566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 16779566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1678fa8e8ae5SToby Isaac } else { 16799566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1680fa8e8ae5SToby Isaac } 16819566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1682c58f1c22SToby Isaac } 16839566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1684c58f1c22SToby Isaac if (label->bt) { 16859566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 16869566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1687c58f1c22SToby Isaac } 16883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1689c58f1c22SToby Isaac } 1690c58f1c22SToby Isaac 1691d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 1692d71ae5a4SJacob Faibussowitsch { 169326c55118SMichael Lange MPI_Comm comm; 1694eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 169526c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 169626c55118SMichael Lange PetscSection rootSection; 169726c55118SMichael Lange PetscSF labelSF; 169826c55118SMichael Lange 169926c55118SMichael Lange PetscFunctionBegin; 17009566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 17019566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 170226c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 170326c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 17049566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 17059566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 17069566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 170726c55118SMichael Lange if (label) { 170826c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1709ad8374ffSToby Isaac const PetscInt *points; 1710ad8374ffSToby Isaac 17119566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 171248a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 17139566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 171426c55118SMichael Lange } 171526c55118SMichael Lange } 17169566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 171726c55118SMichael Lange /* Create a point-wise array of stratum values */ 17189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 17199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 17209566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 172126c55118SMichael Lange if (label) { 172226c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1723ad8374ffSToby Isaac const PetscInt *points; 1724ad8374ffSToby Isaac 17259566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 172626c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1727ad8374ffSToby Isaac const PetscInt p = points[l]; 17289566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 172926c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 173026c55118SMichael Lange } 17319566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 173226c55118SMichael Lange } 173326c55118SMichael Lange } 173426c55118SMichael Lange /* Build SF that maps label points to remote processes */ 17359566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 17369566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 17379566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 17389566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 173926c55118SMichael Lange /* Send the strata for each point over the derived SF */ 17409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 17419566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 17429566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 17439566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 174426c55118SMichael Lange /* Clean up */ 17459566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 17469566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 17479566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 17489566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 17493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 175026c55118SMichael Lange } 175126c55118SMichael Lange 175284f0b6dfSMatthew G. Knepley /*@ 175320f4b53cSBarry Smith DMLabelDistribute - Create a new label pushed forward over the `PetscSF` 175484f0b6dfSMatthew G. Knepley 175520f4b53cSBarry Smith Collective 17565b5e7992SMatthew G. Knepley 175784f0b6dfSMatthew G. Knepley Input Parameters: 175820f4b53cSBarry Smith + label - the `DMLabel` 175984f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 176084f0b6dfSMatthew G. Knepley 176184f0b6dfSMatthew G. Knepley Output Parameter: 176260225df5SJacob Faibussowitsch . labelNew - the new redistributed label 176384f0b6dfSMatthew G. Knepley 176484f0b6dfSMatthew G. Knepley Level: intermediate 176584f0b6dfSMatthew G. Knepley 176620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 176784f0b6dfSMatthew G. Knepley @*/ 1768d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1769d71ae5a4SJacob Faibussowitsch { 1770c58f1c22SToby Isaac MPI_Comm comm; 177126c55118SMichael Lange PetscSection leafSection; 177226c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 177326c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1774ad8374ffSToby Isaac PetscInt **points; 1775d67d17b1SMatthew G. Knepley const char *lname = NULL; 1776c58f1c22SToby Isaac char *name; 1777c58f1c22SToby Isaac PetscInt nameSize; 1778e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1779c58f1c22SToby Isaac size_t len = 0; 178026c55118SMichael Lange PetscMPIInt rank; 1781c58f1c22SToby Isaac 1782c58f1c22SToby Isaac PetscFunctionBegin; 1783d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1784f018e600SMatthew G. Knepley if (label) { 1785f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 17869f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 17879566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1788f018e600SMatthew G. Knepley } 17899566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 17909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1791c58f1c22SToby Isaac /* Bcast name */ 1792dd400576SPatrick Sanan if (rank == 0) { 17939566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 17949566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1795d67d17b1SMatthew G. Knepley } 1796c58f1c22SToby Isaac nameSize = len; 17979566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 17989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 17999566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 18009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 18019566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 18029566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 180377d236dfSMichael Lange /* Bcast defaultValue */ 1804dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 18059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 180626c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 18079566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 18085cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 18099566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 18109566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 18119566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 18129566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 18139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1814ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 18159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 18165cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 18175cbdf6fcSMichael Lange offset = 0; 18189566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 18199566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 182048a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 18215cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1822231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 18239371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 18249371c9d4SSatish Balay leafStrata[p] = s; 18259371c9d4SSatish Balay break; 18269371c9d4SSatish Balay } 18275cbdf6fcSMichael Lange } 18285cbdf6fcSMichael Lange } 1829c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 18309566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 18319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1832c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18339566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18349566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1835ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1836c58f1c22SToby Isaac } 18379566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 18389f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 18399f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &points)); 1840c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 18419566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 18429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]))); 1843c58f1c22SToby Isaac } 1844c58f1c22SToby Isaac /* Insert points into new strata */ 18459566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 18469566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1847c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18489566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18499566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1850c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1851c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1852ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1853c58f1c22SToby Isaac } 1854c58f1c22SToby Isaac } 1855ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 18569566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &(points[s][0]), PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 18579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1858ad8374ffSToby Isaac } 18599566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 18609566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 18619566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 18629566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 18639566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 18643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1865c58f1c22SToby Isaac } 1866c58f1c22SToby Isaac 18677937d9ceSMichael Lange /*@ 18687937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 18697937d9ceSMichael Lange 187020f4b53cSBarry Smith Collective 18715b5e7992SMatthew G. Knepley 18727937d9ceSMichael Lange Input Parameters: 187320f4b53cSBarry Smith + label - the `DMLabel` 187420f4b53cSBarry Smith - sf - the `PetscSF` communication map 18757937d9ceSMichael Lange 18762fe279fdSBarry Smith Output Parameter: 187720f4b53cSBarry Smith . labelNew - the new `DMLabel` with localised leaf values 18787937d9ceSMichael Lange 18797937d9ceSMichael Lange Level: developer 18807937d9ceSMichael Lange 188120f4b53cSBarry Smith Note: 188220f4b53cSBarry Smith This is the inverse operation to `DMLabelDistribute()`. 18837937d9ceSMichael Lange 188420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 18857937d9ceSMichael Lange @*/ 1886d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 1887d71ae5a4SJacob Faibussowitsch { 18887937d9ceSMichael Lange MPI_Comm comm; 18897937d9ceSMichael Lange PetscSection rootSection; 18907937d9ceSMichael Lange PetscSF sfLabel; 18917937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 18927937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 18937937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 18947937d9ceSMichael Lange PetscInt *rootStrata; 1895d67d17b1SMatthew G. Knepley const char *lname; 18967937d9ceSMichael Lange char *name; 18977937d9ceSMichael Lange PetscInt nameSize; 18987937d9ceSMichael Lange size_t len = 0; 18999852e123SBarry Smith PetscMPIInt rank, size; 19007937d9ceSMichael Lange 19017937d9ceSMichael Lange PetscFunctionBegin; 1902d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1903d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 19049f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 19059566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 19069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 19079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 19087937d9ceSMichael Lange /* Bcast name */ 1909dd400576SPatrick Sanan if (rank == 0) { 19109566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 19119566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1912d67d17b1SMatthew G. Knepley } 19137937d9ceSMichael Lange nameSize = len; 19149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 19159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 19169566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 19179566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 19189566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 19199566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 19207937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 19217937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 19227937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 19239566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 19249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1925dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 19267937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 19278212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 19288212dd46SStefano Zampini 19298212dd46SStefano Zampini leafPoints[ilp].index = ilp; 19308212dd46SStefano Zampini leafPoints[ilp].rank = rank; 19317937d9ceSMichael Lange } 19329566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 19339566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 19347937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 19359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 19369566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 19379566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 19389566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 19399566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 19407937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 19419566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 19427937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 19437937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 19447937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 19459566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 19469566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 19479566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 19487937d9ceSMichael Lange } 19497937d9ceSMichael Lange idx += rootDegree[p]; 19507937d9ceSMichael Lange } 19519566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 19529566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 19539566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 19549566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 19553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19567937d9ceSMichael Lange } 19577937d9ceSMichael Lange 1958d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1959d71ae5a4SJacob Faibussowitsch { 1960d42890abSMatthew G. Knepley const PetscInt *degree; 1961d42890abSMatthew G. Knepley const PetscInt *points; 1962d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1963d42890abSMatthew G. Knepley 1964d42890abSMatthew G. Knepley PetscFunctionBegin; 1965d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1966d42890abSMatthew G. Knepley /* Add in leaves */ 1967d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1968d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1969d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 1970d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 1971d42890abSMatthew G. Knepley } 1972d42890abSMatthew G. Knepley /* Add in shared roots */ 1973d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1974d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1975d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1976d42890abSMatthew G. Knepley if (degree[r]) { 1977d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1978d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 1979d42890abSMatthew G. Knepley } 1980d42890abSMatthew G. Knepley } 19813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1982d42890abSMatthew G. Knepley } 1983d42890abSMatthew G. Knepley 1984d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 1985d71ae5a4SJacob Faibussowitsch { 1986d42890abSMatthew G. Knepley const PetscInt *degree; 1987d42890abSMatthew G. Knepley const PetscInt *points; 1988d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1989d42890abSMatthew G. Knepley 1990d42890abSMatthew G. Knepley PetscFunctionBegin; 1991d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1992d42890abSMatthew G. Knepley /* Read out leaves */ 1993d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1994d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1995d42890abSMatthew G. Knepley const PetscInt p = points[l]; 1996d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 1997d42890abSMatthew G. Knepley 1998d42890abSMatthew G. Knepley if (cval != defVal) { 1999d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 2000d42890abSMatthew G. Knepley if (val == defVal) { 2001d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 200248a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 2003d42890abSMatthew G. Knepley } 2004d42890abSMatthew G. Knepley } 2005d42890abSMatthew G. Knepley } 2006d42890abSMatthew G. Knepley /* Read out shared roots */ 2007d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2008d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2009d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2010d42890abSMatthew G. Knepley if (degree[r]) { 2011d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 2012d42890abSMatthew G. Knepley 2013d42890abSMatthew G. Knepley if (cval != defVal) { 2014d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2015d42890abSMatthew G. Knepley if (val == defVal) { 2016d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 201748a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 2018d42890abSMatthew G. Knepley } 2019d42890abSMatthew G. Knepley } 2020d42890abSMatthew G. Knepley } 2021d42890abSMatthew G. Knepley } 20223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2023d42890abSMatthew G. Knepley } 2024d42890abSMatthew G. Knepley 2025d42890abSMatthew G. Knepley /*@ 2026d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 2027d42890abSMatthew G. Knepley 202820f4b53cSBarry Smith Collective 2029d42890abSMatthew G. Knepley 2030d42890abSMatthew G. Knepley Input Parameters: 203120f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 203220f4b53cSBarry Smith - sf - The `PetscSF` describing parallel layout of the label points 2033d42890abSMatthew G. Knepley 2034d42890abSMatthew G. Knepley Level: intermediate 2035d42890abSMatthew G. Knepley 203620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 2037d42890abSMatthew G. Knepley @*/ 2038d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 2039d71ae5a4SJacob Faibussowitsch { 2040d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 2041d42890abSMatthew G. Knepley PetscMPIInt size; 2042d42890abSMatthew G. Knepley 2043d42890abSMatthew G. Knepley PetscFunctionBegin; 20449f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2045d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 2046d42890abSMatthew G. Knepley if (size > 1) { 2047d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2048d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 2049d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 2050d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 2051d42890abSMatthew G. Knepley } 20523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2053d42890abSMatthew G. Knepley } 2054d42890abSMatthew G. Knepley 2055d42890abSMatthew G. Knepley /*@ 2056d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 2057d42890abSMatthew G. Knepley 205820f4b53cSBarry Smith Collective 2059d42890abSMatthew G. Knepley 2060d42890abSMatthew G. Knepley Input Parameters: 206120f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 206260225df5SJacob Faibussowitsch - pointSF - The `PetscSF` describing parallel layout of the label points 2063d42890abSMatthew G. Knepley 2064d42890abSMatthew G. Knepley Level: intermediate 2065d42890abSMatthew G. Knepley 206620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 2067d42890abSMatthew G. Knepley @*/ 2068d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 2069d71ae5a4SJacob Faibussowitsch { 2070d42890abSMatthew G. Knepley PetscFunctionBegin; 20719f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2072d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 2073d42890abSMatthew G. Knepley label->propArray = NULL; 20743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2075d42890abSMatthew G. Knepley } 2076d42890abSMatthew G. Knepley 2077d42890abSMatthew G. Knepley /*@C 2078d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 2079d42890abSMatthew G. Knepley 208020f4b53cSBarry Smith Collective 2081d42890abSMatthew G. Knepley 2082d42890abSMatthew G. Knepley Input Parameters: 208320f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 2084*a4e35b19SJacob Faibussowitsch . pointSF - The `PetscSF` describing parallel layout of the label points 208520f4b53cSBarry Smith . markPoint - An optional callback that is called when a point is marked, or `NULL` 208620f4b53cSBarry Smith - ctx - An optional user context for the callback, or `NULL` 2087d42890abSMatthew G. Knepley 208820f4b53cSBarry Smith Calling sequence of `markPoint`: 208920f4b53cSBarry Smith + label - The `DMLabel` 2090d42890abSMatthew G. Knepley . p - The point being marked 2091*a4e35b19SJacob Faibussowitsch . val - The label value for `p` 2092d42890abSMatthew G. Knepley - ctx - An optional user context 2093d42890abSMatthew G. Knepley 2094d42890abSMatthew G. Knepley Level: intermediate 2095d42890abSMatthew G. Knepley 209620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2097d42890abSMatthew G. Knepley @*/ 2098*a4e35b19SJacob Faibussowitsch PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel label, PetscInt p, PetscInt val, void *ctx), void *ctx) 2099d71ae5a4SJacob Faibussowitsch { 2100c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2101d42890abSMatthew G. Knepley PetscMPIInt size; 2102d42890abSMatthew G. Knepley 2103d42890abSMatthew G. Knepley PetscFunctionBegin; 21049f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2105d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 2106c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2107c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2108d42890abSMatthew G. Knepley /* Communicate marked edges 2109d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2110d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2111d42890abSMatthew G. Knepley 2112d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2113d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2114d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2115d42890abSMatthew G. Knepley 2116d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2117d42890abSMatthew 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 2118d42890abSMatthew G. Knepley edge to the queue. 2119d42890abSMatthew G. Knepley */ 2120d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2121d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2122d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2123d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2124d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2125d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2126d42890abSMatthew G. Knepley } 21273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2128d42890abSMatthew G. Knepley } 2129d42890abSMatthew G. Knepley 213084f0b6dfSMatthew G. Knepley /*@ 213120f4b53cSBarry Smith DMLabelConvertToSection - Make a `PetscSection`/`IS` pair that encodes the label 213284f0b6dfSMatthew G. Knepley 213320f4b53cSBarry Smith Not Collective 21345b5e7992SMatthew G. Knepley 213584f0b6dfSMatthew G. Knepley Input Parameter: 213620f4b53cSBarry Smith . label - the `DMLabel` 213784f0b6dfSMatthew G. Knepley 213884f0b6dfSMatthew G. Knepley Output Parameters: 213984f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 214020f4b53cSBarry Smith - is - An `IS` containing all the label points 214184f0b6dfSMatthew G. Knepley 214284f0b6dfSMatthew G. Knepley Level: developer 214384f0b6dfSMatthew G. Knepley 214420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 214584f0b6dfSMatthew G. Knepley @*/ 2146d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2147d71ae5a4SJacob Faibussowitsch { 2148c58f1c22SToby Isaac IS vIS; 2149c58f1c22SToby Isaac const PetscInt *values; 2150c58f1c22SToby Isaac PetscInt *points; 2151c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2152c58f1c22SToby Isaac 2153c58f1c22SToby Isaac PetscFunctionBegin; 2154d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 21559566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 21569566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 21579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 21589371c9d4SSatish Balay if (nV) { 21599371c9d4SSatish Balay vS = values[0]; 21609371c9d4SSatish Balay vE = values[0] + 1; 21619371c9d4SSatish Balay } 2162c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2163c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2164c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2165c58f1c22SToby Isaac } 21669566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 21679566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2168c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2169c58f1c22SToby Isaac PetscInt n; 2170c58f1c22SToby Isaac 21719566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 21729566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2173c58f1c22SToby Isaac } 21749566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 21759566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 21769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2177c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2178c58f1c22SToby Isaac IS is; 2179c58f1c22SToby Isaac const PetscInt *spoints; 2180c58f1c22SToby Isaac PetscInt dof, off, p; 2181c58f1c22SToby Isaac 21829566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 21839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 21849566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 21859566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2186c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 21879566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 21889566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2189c58f1c22SToby Isaac } 21909566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 21919566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 21929566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 21933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2194c58f1c22SToby Isaac } 2195c58f1c22SToby Isaac 21969f6c5813SMatthew G. Knepley /*@C 21979f6c5813SMatthew G. Knepley DMLabelRegister - Adds a new label component implementation 21989f6c5813SMatthew G. Knepley 21999f6c5813SMatthew G. Knepley Not Collective 22009f6c5813SMatthew G. Knepley 22019f6c5813SMatthew G. Knepley Input Parameters: 22029f6c5813SMatthew G. Knepley + name - The name of a new user-defined creation routine 22039f6c5813SMatthew G. Knepley - create_func - The creation routine itself 22049f6c5813SMatthew G. Knepley 22059f6c5813SMatthew G. Knepley Notes: 22069f6c5813SMatthew G. Knepley `DMLabelRegister()` may be called multiple times to add several user-defined labels 22079f6c5813SMatthew G. Knepley 220860225df5SJacob Faibussowitsch Example Usage: 22099f6c5813SMatthew G. Knepley .vb 22109f6c5813SMatthew G. Knepley DMLabelRegister("my_label", MyLabelCreate); 22119f6c5813SMatthew G. Knepley .ve 22129f6c5813SMatthew G. Knepley 22139f6c5813SMatthew G. Knepley Then, your label type can be chosen with the procedural interface via 22149f6c5813SMatthew G. Knepley .vb 22159f6c5813SMatthew G. Knepley DMLabelCreate(MPI_Comm, DMLabel *); 22169f6c5813SMatthew G. Knepley DMLabelSetType(DMLabel, "my_label"); 22179f6c5813SMatthew G. Knepley .ve 22189f6c5813SMatthew G. Knepley or at runtime via the option 22199f6c5813SMatthew G. Knepley .vb 22209f6c5813SMatthew G. Knepley -dm_label_type my_label 22219f6c5813SMatthew G. Knepley .ve 22229f6c5813SMatthew G. Knepley 22239f6c5813SMatthew G. Knepley Level: advanced 22249f6c5813SMatthew G. Knepley 222560225df5SJacob Faibussowitsch .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelRegisterAll()`, `DMLabelRegisterDestroy()` 22269f6c5813SMatthew G. Knepley @*/ 22279f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegister(const char name[], PetscErrorCode (*create_func)(DMLabel)) 22289f6c5813SMatthew G. Knepley { 22299f6c5813SMatthew G. Knepley PetscFunctionBegin; 22309f6c5813SMatthew G. Knepley PetscCall(DMInitializePackage()); 22319f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListAdd(&DMLabelList, name, create_func)); 22323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22339f6c5813SMatthew G. Knepley } 22349f6c5813SMatthew G. Knepley 22359f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel); 22369f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel); 22379f6c5813SMatthew G. Knepley 22389f6c5813SMatthew G. Knepley /*@C 22399f6c5813SMatthew G. Knepley DMLabelRegisterAll - Registers all of the `DMLabel` implementations in the `DM` package. 22409f6c5813SMatthew G. Knepley 22419f6c5813SMatthew G. Knepley Not Collective 22429f6c5813SMatthew G. Knepley 22439f6c5813SMatthew G. Knepley Level: advanced 22449f6c5813SMatthew G. Knepley 224520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMRegisterAll()`, `DMLabelRegisterDestroy()` 22469f6c5813SMatthew G. Knepley @*/ 22479f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterAll(void) 22489f6c5813SMatthew G. Knepley { 22499f6c5813SMatthew G. Knepley PetscFunctionBegin; 22503ba16761SJacob Faibussowitsch if (DMLabelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 22519f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_TRUE; 22529f6c5813SMatthew G. Knepley 22539f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELCONCRETE, DMLabelCreate_Concrete)); 22549f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELEPHEMERAL, DMLabelCreate_Ephemeral)); 22553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22569f6c5813SMatthew G. Knepley } 22579f6c5813SMatthew G. Knepley 22589f6c5813SMatthew G. Knepley /*@C 22599f6c5813SMatthew G. Knepley DMLabelRegisterDestroy - This function destroys the `DMLabel` registry. It is called from `PetscFinalize()`. 22609f6c5813SMatthew G. Knepley 22619f6c5813SMatthew G. Knepley Level: developer 22629f6c5813SMatthew G. Knepley 226320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscInitialize()` 22649f6c5813SMatthew G. Knepley @*/ 22659f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterDestroy(void) 22669f6c5813SMatthew G. Knepley { 22679f6c5813SMatthew G. Knepley PetscFunctionBegin; 22689f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMLabelList)); 22699f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_FALSE; 22703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22719f6c5813SMatthew G. Knepley } 22729f6c5813SMatthew G. Knepley 22739f6c5813SMatthew G. Knepley /*@C 22749f6c5813SMatthew G. Knepley DMLabelSetType - Sets the particular implementation for a label. 22759f6c5813SMatthew G. Knepley 227620f4b53cSBarry Smith Collective 22779f6c5813SMatthew G. Knepley 22789f6c5813SMatthew G. Knepley Input Parameters: 22799f6c5813SMatthew G. Knepley + label - The label 22809f6c5813SMatthew G. Knepley - method - The name of the label type 22819f6c5813SMatthew G. Knepley 22829f6c5813SMatthew G. Knepley Options Database Key: 228320f4b53cSBarry Smith . -dm_label_type <type> - Sets the label type; use -help for a list of available types or see `DMLabelType` 22849f6c5813SMatthew G. Knepley 22859f6c5813SMatthew G. Knepley Level: intermediate 22869f6c5813SMatthew G. Knepley 228720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetType()`, `DMLabelCreate()` 22889f6c5813SMatthew G. Knepley @*/ 22899f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetType(DMLabel label, DMLabelType method) 22909f6c5813SMatthew G. Knepley { 22919f6c5813SMatthew G. Knepley PetscErrorCode (*r)(DMLabel); 22929f6c5813SMatthew G. Knepley PetscBool match; 22939f6c5813SMatthew G. Knepley 22949f6c5813SMatthew G. Knepley PetscFunctionBegin; 22959f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 22969f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)label, method, &match)); 22973ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 22989f6c5813SMatthew G. Knepley 22999f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23009f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListFind(DMLabelList, method, &r)); 23019f6c5813SMatthew G. Knepley PetscCheck(r, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMLabel type: %s", method); 23029f6c5813SMatthew G. Knepley 23039f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, destroy); 23049f6c5813SMatthew G. Knepley PetscCall(PetscMemzero(label->ops, sizeof(*label->ops))); 23059f6c5813SMatthew G. Knepley PetscCall(PetscObjectChangeTypeName((PetscObject)label, method)); 23069f6c5813SMatthew G. Knepley PetscCall((*r)(label)); 23073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23089f6c5813SMatthew G. Knepley } 23099f6c5813SMatthew G. Knepley 23109f6c5813SMatthew G. Knepley /*@C 23119f6c5813SMatthew G. Knepley DMLabelGetType - Gets the type name (as a string) from the label. 23129f6c5813SMatthew G. Knepley 23139f6c5813SMatthew G. Knepley Not Collective 23149f6c5813SMatthew G. Knepley 23159f6c5813SMatthew G. Knepley Input Parameter: 231620f4b53cSBarry Smith . label - The `DMLabel` 23179f6c5813SMatthew G. Knepley 23189f6c5813SMatthew G. Knepley Output Parameter: 231920f4b53cSBarry Smith . type - The `DMLabel` type name 23209f6c5813SMatthew G. Knepley 23219f6c5813SMatthew G. Knepley Level: intermediate 23229f6c5813SMatthew G. Knepley 232320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetType()`, `DMLabelCreate()` 23249f6c5813SMatthew G. Knepley @*/ 23259f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetType(DMLabel label, DMLabelType *type) 23269f6c5813SMatthew G. Knepley { 23279f6c5813SMatthew G. Knepley PetscFunctionBegin; 23289f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23294f572ea9SToby Isaac PetscAssertPointer(type, 2); 23309f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23319f6c5813SMatthew G. Knepley *type = ((PetscObject)label)->type_name; 23323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23339f6c5813SMatthew G. Knepley } 23349f6c5813SMatthew G. Knepley 23359f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Concrete(DMLabel label) 23369f6c5813SMatthew G. Knepley { 23379f6c5813SMatthew G. Knepley PetscFunctionBegin; 23389f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Concrete; 23399f6c5813SMatthew G. Knepley label->ops->setup = NULL; 23409f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Concrete; 23419f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Concrete; 23423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23439f6c5813SMatthew G. Knepley } 23449f6c5813SMatthew G. Knepley 23459f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel label) 23469f6c5813SMatthew G. Knepley { 23479f6c5813SMatthew G. Knepley PetscFunctionBegin; 23489f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23499f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Concrete(label)); 23503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23519f6c5813SMatthew G. Knepley } 23529f6c5813SMatthew G. Knepley 235384f0b6dfSMatthew G. Knepley /*@ 2354c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 235520f4b53cSBarry Smith the local section and an `PetscSF` describing the section point overlap. 2356c58f1c22SToby Isaac 235720f4b53cSBarry Smith Collective 23585b5e7992SMatthew G. Knepley 2359c58f1c22SToby Isaac Input Parameters: 236020f4b53cSBarry Smith + s - The `PetscSection` for the local field layout 236120f4b53cSBarry Smith . sf - The `PetscSF` describing parallel layout of the section points 236220f4b53cSBarry Smith . includeConstraints - By default this is `PETSC_FALSE`, meaning that the global field vector will not possess constrained dofs 2363c58f1c22SToby Isaac . label - The label specifying the points 2364c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2365c58f1c22SToby Isaac 2366c58f1c22SToby Isaac Output Parameter: 236720f4b53cSBarry Smith . gsection - The `PetscSection` for the global field layout 2368c58f1c22SToby Isaac 2369c58f1c22SToby Isaac Level: developer 2370c58f1c22SToby Isaac 237120f4b53cSBarry Smith Note: 237220f4b53cSBarry Smith This gives negative sizes and offsets to points not owned by this process 237320f4b53cSBarry Smith 237420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionCreate()` 2375c58f1c22SToby Isaac @*/ 2376d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2377d71ae5a4SJacob Faibussowitsch { 2378c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2379c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2380c58f1c22SToby Isaac 2381c58f1c22SToby Isaac PetscFunctionBegin; 2382d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2383d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2384d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 23859566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 23869566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 23879566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 23889566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2389c58f1c22SToby Isaac if (nroots >= 0) { 239063a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 23919566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2392c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 23939566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2394c58f1c22SToby Isaac } else { 2395c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2396c58f1c22SToby Isaac } 2397c58f1c22SToby Isaac } 2398c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2399c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2400c58f1c22SToby Isaac PetscInt value; 2401c58f1c22SToby Isaac 24029566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2403c58f1c22SToby Isaac if (value != labelValue) continue; 24049566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 24059566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 24069566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 24079566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2408c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2409c58f1c22SToby Isaac } 24109566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2411c58f1c22SToby Isaac if (nroots >= 0) { 24129566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24139566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2414c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24159371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24169371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 24179371c9d4SSatish Balay } 2418c58f1c22SToby Isaac } 2419c58f1c22SToby Isaac } 242035cb6cd3SPierre Jolivet /* Calculate new sizes, get process offset, and calculate point offsets */ 2421c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2422c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2423c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2424c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2425c58f1c22SToby Isaac } 24269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2427c58f1c22SToby Isaac globalOff -= off; 2428c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2429c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2430c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2431c58f1c22SToby Isaac } 2432c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2433c58f1c22SToby Isaac if (nroots >= 0) { 24349566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24359566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2436c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24379371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24389371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 24399371c9d4SSatish Balay } 2440c58f1c22SToby Isaac } 2441c58f1c22SToby Isaac } 24429566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 24439566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 24443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2445c58f1c22SToby Isaac } 2446c58f1c22SToby Isaac 24479371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 24485fdea053SToby Isaac DMLabel label; 24495fdea053SToby Isaac PetscCopyMode *modes; 24505fdea053SToby Isaac PetscInt *sizes; 24515fdea053SToby Isaac const PetscInt ***perms; 24525fdea053SToby Isaac const PetscScalar ***rots; 24535fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 24545fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 24555fdea053SToby Isaac } PetscSectionSym_Label; 24565fdea053SToby Isaac 2457d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 2458d71ae5a4SJacob Faibussowitsch { 24595fdea053SToby Isaac PetscInt i, j; 24605fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24615fdea053SToby Isaac 24625fdea053SToby Isaac PetscFunctionBegin; 24635fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24645fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 24655fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 24669566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 24679566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 24685fdea053SToby Isaac } 24695fdea053SToby Isaac if (sl->perms[i]) { 24705fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 24715fdea053SToby Isaac 24729566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 24735fdea053SToby Isaac } 24745fdea053SToby Isaac if (sl->rots[i]) { 24755fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 24765fdea053SToby Isaac 24779566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 24785fdea053SToby Isaac } 24795fdea053SToby Isaac } 24805fdea053SToby Isaac } 24819566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 24829566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 24835fdea053SToby Isaac sl->numStrata = 0; 24843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24855fdea053SToby Isaac } 24865fdea053SToby Isaac 2487d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 2488d71ae5a4SJacob Faibussowitsch { 24895fdea053SToby Isaac PetscFunctionBegin; 24909566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 24919566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 24923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24935fdea053SToby Isaac } 24945fdea053SToby Isaac 2495d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 2496d71ae5a4SJacob Faibussowitsch { 24975fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24985fdea053SToby Isaac PetscBool isAscii; 24995fdea053SToby Isaac DMLabel label = sl->label; 2500d67d17b1SMatthew G. Knepley const char *name; 25015fdea053SToby Isaac 25025fdea053SToby Isaac PetscFunctionBegin; 25039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 25045fdea053SToby Isaac if (isAscii) { 25055fdea053SToby Isaac PetscInt i, j, k; 25065fdea053SToby Isaac PetscViewerFormat format; 25075fdea053SToby Isaac 25089566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25095fdea053SToby Isaac if (label) { 25109566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25115fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25139566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 25149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25155fdea053SToby Isaac } else { 25169566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 25179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 25185fdea053SToby Isaac } 25195fdea053SToby Isaac } else { 25209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 25215fdea053SToby Isaac } 25229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25235fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 25245fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 25255fdea053SToby Isaac 25265fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 252763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 25285fdea053SToby Isaac } else { 252963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 25309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 253163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 25325fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25345fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 25355fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 253663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 25375fdea053SToby Isaac } else { 25385fdea053SToby Isaac PetscInt tab; 25395fdea053SToby Isaac 254063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 25419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 25435fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 25449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 25459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 254663a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 25479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25489566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25495fdea053SToby Isaac } 25505fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 25519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 25529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 25535fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 255463a3b9bcSJacob 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]))); 25555fdea053SToby Isaac #else 255663a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 25575fdea053SToby Isaac #endif 25589566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25605fdea053SToby Isaac } 25619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25625fdea053SToby Isaac } 25635fdea053SToby Isaac } 25649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25655fdea053SToby Isaac } 25669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25675fdea053SToby Isaac } 25685fdea053SToby Isaac } 25699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25705fdea053SToby Isaac } 25713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25725fdea053SToby Isaac } 25735fdea053SToby Isaac 25745fdea053SToby Isaac /*@ 25755fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 25765fdea053SToby Isaac 257720f4b53cSBarry Smith Logically 25785fdea053SToby Isaac 257960225df5SJacob Faibussowitsch Input Parameters: 25805fdea053SToby Isaac + sym - the section symmetries 258120f4b53cSBarry Smith - label - the `DMLabel` describing the types of points 25825fdea053SToby Isaac 25835fdea053SToby Isaac Level: developer: 25845fdea053SToby Isaac 258520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 25865fdea053SToby Isaac @*/ 2587d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 2588d71ae5a4SJacob Faibussowitsch { 25895fdea053SToby Isaac PetscSectionSym_Label *sl; 25905fdea053SToby Isaac 25915fdea053SToby Isaac PetscFunctionBegin; 25925fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 25935fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 25949566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 25955fdea053SToby Isaac if (label) { 25965fdea053SToby Isaac sl->label = label; 25979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 25989566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 25999566063dSJacob 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)); 26009566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 26019566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 26029566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 26039566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 26049566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 26055fdea053SToby Isaac } 26063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26075fdea053SToby Isaac } 26085fdea053SToby Isaac 26095fdea053SToby Isaac /*@C 2610b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2611b004864fSMatthew G. Knepley 261220f4b53cSBarry Smith Logically Collective 2613b004864fSMatthew G. Knepley 2614b004864fSMatthew G. Knepley Input Parameters: 2615b004864fSMatthew G. Knepley + sym - the section symmetries 2616b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2617b004864fSMatthew G. Knepley 2618b004864fSMatthew G. Knepley Output Parameters: 261920f4b53cSBarry Smith + size - the number of dofs for points in the `stratum` of the label 262020f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 262120f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a ppoint in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 262220f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 262320f4b53cSBarry 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 2624b004864fSMatthew G. Knepley 2625b004864fSMatthew G. Knepley Level: developer 2626b004864fSMatthew G. Knepley 262720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2628b004864fSMatthew G. Knepley @*/ 2629d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2630d71ae5a4SJacob Faibussowitsch { 2631b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2632b004864fSMatthew G. Knepley const char *name; 2633b004864fSMatthew G. Knepley PetscInt i; 2634b004864fSMatthew G. Knepley 2635b004864fSMatthew G. Knepley PetscFunctionBegin; 2636b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2637b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2638b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2639b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2640b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2641b004864fSMatthew G. Knepley 2642b004864fSMatthew G. Knepley if (stratum == value) break; 2643b004864fSMatthew G. Knepley } 26449566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2645b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 26469371c9d4SSatish Balay if (size) { 26474f572ea9SToby Isaac PetscAssertPointer(size, 3); 26489371c9d4SSatish Balay *size = sl->sizes[i]; 26499371c9d4SSatish Balay } 26509371c9d4SSatish Balay if (minOrient) { 26514f572ea9SToby Isaac PetscAssertPointer(minOrient, 4); 26529371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 26539371c9d4SSatish Balay } 26549371c9d4SSatish Balay if (maxOrient) { 26554f572ea9SToby Isaac PetscAssertPointer(maxOrient, 5); 26569371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 26579371c9d4SSatish Balay } 26589371c9d4SSatish Balay if (perms) { 26594f572ea9SToby Isaac PetscAssertPointer(perms, 6); 26609371c9d4SSatish Balay *perms = sl->perms[i] ? &sl->perms[i][sl->minMaxOrients[i][0]] : NULL; 26619371c9d4SSatish Balay } 26629371c9d4SSatish Balay if (rots) { 26634f572ea9SToby Isaac PetscAssertPointer(rots, 7); 26649371c9d4SSatish Balay *rots = sl->rots[i] ? &sl->rots[i][sl->minMaxOrients[i][0]] : NULL; 26659371c9d4SSatish Balay } 26663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2667b004864fSMatthew G. Knepley } 2668b004864fSMatthew G. Knepley 2669b004864fSMatthew G. Knepley /*@C 26705fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 26715fdea053SToby Isaac 267220f4b53cSBarry Smith Logically 26735fdea053SToby Isaac 26745fdea053SToby Isaac Input Parameters: 26755b5e7992SMatthew G. Knepley + sym - the section symmetries 26765fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 267720f4b53cSBarry Smith . size - the number of dofs for points in the `stratum` of the label 267820f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 267920f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a point in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 268020f4b53cSBarry Smith . mode - how `sym` should copy the `perms` and `rots` arrays 268120f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 268220f4b53cSBarry 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 26835fdea053SToby Isaac 26845fdea053SToby Isaac Level: developer 26855fdea053SToby Isaac 268620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 26875fdea053SToby Isaac @*/ 2688d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 2689d71ae5a4SJacob Faibussowitsch { 26905fdea053SToby Isaac PetscSectionSym_Label *sl; 2691d67d17b1SMatthew G. Knepley const char *name; 2692d67d17b1SMatthew G. Knepley PetscInt i, j, k; 26935fdea053SToby Isaac 26945fdea053SToby Isaac PetscFunctionBegin; 26955fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 26965fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2697b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 26985fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 26995fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 27005fdea053SToby Isaac 27015fdea053SToby Isaac if (stratum == value) break; 27025fdea053SToby Isaac } 27039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 270463a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 27055fdea053SToby Isaac sl->sizes[i] = size; 27065fdea053SToby Isaac sl->modes[i] = mode; 27075fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 27085fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 27095fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 27105fdea053SToby Isaac if (perms) { 27115fdea053SToby Isaac PetscInt **ownPerms; 27125fdea053SToby Isaac 27139566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 27145fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27155fdea053SToby Isaac if (perms[j]) { 27169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2717ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 27185fdea053SToby Isaac } 27195fdea053SToby Isaac } 27205fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 27215fdea053SToby Isaac } 27225fdea053SToby Isaac if (rots) { 27235fdea053SToby Isaac PetscScalar **ownRots; 27245fdea053SToby Isaac 27259566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 27265fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27275fdea053SToby Isaac if (rots[j]) { 27289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2729ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 27305fdea053SToby Isaac } 27315fdea053SToby Isaac } 27325fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 27335fdea053SToby Isaac } 27345fdea053SToby Isaac } else { 27355fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 27365fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 27375fdea053SToby Isaac } 27383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27395fdea053SToby Isaac } 27405fdea053SToby Isaac 2741d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 2742d71ae5a4SJacob Faibussowitsch { 27435fdea053SToby Isaac PetscInt i, j, numStrata; 27445fdea053SToby Isaac PetscSectionSym_Label *sl; 27455fdea053SToby Isaac DMLabel label; 27465fdea053SToby Isaac 27475fdea053SToby Isaac PetscFunctionBegin; 27485fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 27495fdea053SToby Isaac numStrata = sl->numStrata; 27505fdea053SToby Isaac label = sl->label; 27515fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 27525fdea053SToby Isaac PetscInt point = points[2 * i]; 27535fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 27545fdea053SToby Isaac 27555fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 27565fdea053SToby Isaac if (label->validIS[j]) { 27575fdea053SToby Isaac PetscInt k; 27585fdea053SToby Isaac 27599566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j], point, &k)); 27605fdea053SToby Isaac if (k >= 0) break; 27615fdea053SToby Isaac } else { 27625fdea053SToby Isaac PetscBool has; 27635fdea053SToby Isaac 27649566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 27655fdea053SToby Isaac if (has) break; 27665fdea053SToby Isaac } 27675fdea053SToby Isaac } 27689371c9d4SSatish 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], 27699371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2770ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2771ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 27725fdea053SToby Isaac } 27733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27745fdea053SToby Isaac } 27755fdea053SToby Isaac 2776d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2777d71ae5a4SJacob Faibussowitsch { 2778b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2779b004864fSMatthew G. Knepley IS valIS; 2780b004864fSMatthew G. Knepley const PetscInt *values; 2781b004864fSMatthew G. Knepley PetscInt Nv, v; 2782b004864fSMatthew G. Knepley 2783b004864fSMatthew G. Knepley PetscFunctionBegin; 27849566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 27859566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 27869566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2787b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2788b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2789b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2790b004864fSMatthew G. Knepley const PetscInt **perms; 2791b004864fSMatthew G. Knepley const PetscScalar **rots; 2792b004864fSMatthew G. Knepley 27939566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 27949566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2795b004864fSMatthew G. Knepley } 27969566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 27973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2798b004864fSMatthew G. Knepley } 2799b004864fSMatthew G. Knepley 2800d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2801d71ae5a4SJacob Faibussowitsch { 2802b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2803b004864fSMatthew G. Knepley DMLabel dlabel; 2804b004864fSMatthew G. Knepley 2805b004864fSMatthew G. Knepley PetscFunctionBegin; 28069566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 28079566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 28089566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 28099566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 28103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2811b004864fSMatthew G. Knepley } 2812b004864fSMatthew G. Knepley 2813d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 2814d71ae5a4SJacob Faibussowitsch { 28155fdea053SToby Isaac PetscSectionSym_Label *sl; 28165fdea053SToby Isaac 28175fdea053SToby Isaac PetscFunctionBegin; 28184dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 28195fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2820b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2821b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 28225fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 28235fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 28245fdea053SToby Isaac sym->data = (void *)sl; 28253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28265fdea053SToby Isaac } 28275fdea053SToby Isaac 28285fdea053SToby Isaac /*@ 28295fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 28305fdea053SToby Isaac 28315fdea053SToby Isaac Collective 28325fdea053SToby Isaac 28335fdea053SToby Isaac Input Parameters: 28345fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 28355fdea053SToby Isaac - label - the label defining the strata 28365fdea053SToby Isaac 28372fe279fdSBarry Smith Output Parameter: 28385fdea053SToby Isaac . sym - the section symmetries 28395fdea053SToby Isaac 28405fdea053SToby Isaac Level: developer 28415fdea053SToby Isaac 284220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 28435fdea053SToby Isaac @*/ 2844d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 2845d71ae5a4SJacob Faibussowitsch { 28465fdea053SToby Isaac PetscFunctionBegin; 28479566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 28489566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 28499566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 28509566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 28513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28525fdea053SToby Isaac } 2853