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 95c58f1c22SToby Isaac PetscFunctionBegin; 964d86920dSPierre Jolivet if ((PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) || label->readonly) PetscFunctionReturn(PETSC_SUCCESS); 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 168c58f1c22SToby Isaac PetscFunctionBegin; 1694d86920dSPierre Jolivet if ((PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) || label->readonly) PetscFunctionReturn(PETSC_SUCCESS); 1701dca8a05SBarry Smith PetscCheck(v >= 0 && v < label->numStrata, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %" PetscInt_FMT " in DMLabelMakeInvalid_Private", v); 171ad8374ffSToby Isaac if (label->points[v]) { 1729566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 17348a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 1749566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 175*f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 176ad8374ffSToby Isaac } 177ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 179c58f1c22SToby Isaac } 180c58f1c22SToby Isaac 181d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelMakeAllInvalid_Internal(DMLabel label) 182d71ae5a4SJacob Faibussowitsch { 183695799ffSMatthew G. Knepley PetscInt v; 184695799ffSMatthew G. Knepley 185695799ffSMatthew G. Knepley PetscFunctionBegin; 18648a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeInvalid_Private(label, v)); 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 188695799ffSMatthew G. Knepley } 189695799ffSMatthew G. Knepley 190b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 191b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 192b9907514SLisandro Dalcin #endif 193b9907514SLisandro Dalcin 1949f6c5813SMatthew G. Knepley PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 195d71ae5a4SJacob Faibussowitsch { 1960c3c4a36SLisandro Dalcin PetscInt v; 1970e79e033SBarry Smith 1980c3c4a36SLisandro Dalcin PetscFunctionBegin; 1990e79e033SBarry Smith *index = -1; 2009f6c5813SMatthew G. Knepley if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD || label->readonly) { 201b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2029371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2039371c9d4SSatish Balay *index = v; 2049371c9d4SSatish Balay break; 2059371c9d4SSatish Balay } 206b9907514SLisandro Dalcin } else { 2079566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index)); 2080e79e033SBarry Smith } 2099f6c5813SMatthew G. Knepley if (PetscDefined(USE_DEBUG) && !label->readonly) { /* Check strata hash map consistency */ 21090e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 2119566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len)); 21208401ef6SPierre Jolivet PetscCheck(len == label->numStrata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 21390e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 2149566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc)); 21590e9b2aeSLisandro Dalcin } else { 21690e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2179371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2189371c9d4SSatish Balay loc = v; 2199371c9d4SSatish Balay break; 2209371c9d4SSatish Balay } 22190e9b2aeSLisandro Dalcin } 22208401ef6SPierre Jolivet PetscCheck(loc == *index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 22390e9b2aeSLisandro Dalcin } 2243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2250c3c4a36SLisandro Dalcin } 2260c3c4a36SLisandro Dalcin 227d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 228d71ae5a4SJacob Faibussowitsch { 229b9907514SLisandro Dalcin PetscInt v; 230b9907514SLisandro Dalcin PetscInt *tmpV; 231b9907514SLisandro Dalcin PetscInt *tmpS; 232b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 233b9907514SLisandro Dalcin IS *tmpP, is; 234c58f1c22SToby Isaac PetscBool *tmpB; 235b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 236c58f1c22SToby Isaac 237c58f1c22SToby Isaac PetscFunctionBegin; 238b9907514SLisandro Dalcin v = label->numStrata; 239b9907514SLisandro Dalcin tmpV = label->stratumValues; 240b9907514SLisandro Dalcin tmpS = label->stratumSizes; 241b9907514SLisandro Dalcin tmpH = label->ht; 242b9907514SLisandro Dalcin tmpP = label->points; 243b9907514SLisandro Dalcin tmpB = label->validIS; 2448e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2458e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2468e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2478e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2488e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2498e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2509566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpV), &tmpV)); 2519566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpS), &tmpS)); 2529f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpH), &tmpH)); 2539f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpP), &tmpP)); 2549566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpB), &tmpB)); 2559566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v)); 2569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v)); 2579566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v)); 2589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v)); 2599566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v)); 2609566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV)); 2619566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS)); 2629566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH)); 2639566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP)); 2649566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB)); 2658e1f8cf0SLisandro Dalcin } 266b9907514SLisandro Dalcin label->numStrata = v + 1; 267c58f1c22SToby Isaac label->stratumValues = tmpV; 268c58f1c22SToby Isaac label->stratumSizes = tmpS; 269c58f1c22SToby Isaac label->ht = tmpH; 270c58f1c22SToby Isaac label->points = tmpP; 271ad8374ffSToby Isaac label->validIS = tmpB; 2729566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 2739566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 2749566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v)); 275b9907514SLisandro Dalcin tmpV[v] = value; 276b9907514SLisandro Dalcin tmpS[v] = 0; 277b9907514SLisandro Dalcin tmpH[v] = ht; 278b9907514SLisandro Dalcin tmpP[v] = is; 279b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 2809566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 2810c3c4a36SLisandro Dalcin *index = v; 2823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2830c3c4a36SLisandro Dalcin } 2840c3c4a36SLisandro Dalcin 285d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 286d71ae5a4SJacob Faibussowitsch { 287b9907514SLisandro Dalcin PetscFunctionBegin; 2889566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index)); 2899566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index)); 2903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 291b9907514SLisandro Dalcin } 292b9907514SLisandro Dalcin 2939f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) 294d71ae5a4SJacob Faibussowitsch { 2959e63cc69SVaclav Hapla PetscFunctionBegin; 2969e63cc69SVaclav Hapla *size = 0; 2973ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 2989f6c5813SMatthew G. Knepley if (label->readonly || label->validIS[v]) { 2999e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 3009e63cc69SVaclav Hapla } else { 3019566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size)); 3029e63cc69SVaclav Hapla } 3033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3049e63cc69SVaclav Hapla } 3059e63cc69SVaclav Hapla 306b9907514SLisandro Dalcin /*@ 30720f4b53cSBarry Smith DMLabelAddStratum - Adds a new stratum value in a `DMLabel` 308b9907514SLisandro Dalcin 309d8d19677SJose E. Roman Input Parameters: 31020f4b53cSBarry Smith + label - The `DMLabel` 311b9907514SLisandro Dalcin - value - The stratum value 312b9907514SLisandro Dalcin 313b9907514SLisandro Dalcin Level: beginner 314b9907514SLisandro Dalcin 31520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 316b9907514SLisandro Dalcin @*/ 317d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 318d71ae5a4SJacob Faibussowitsch { 3190c3c4a36SLisandro Dalcin PetscInt v; 3200c3c4a36SLisandro Dalcin 3210c3c4a36SLisandro Dalcin PetscFunctionBegin; 322d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3239f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3249566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 3253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 326b9907514SLisandro Dalcin } 327b9907514SLisandro Dalcin 328b9907514SLisandro Dalcin /*@ 32920f4b53cSBarry Smith DMLabelAddStrata - Adds new stratum values in a `DMLabel` 330b9907514SLisandro Dalcin 33120f4b53cSBarry Smith Not Collective 3325b5e7992SMatthew G. Knepley 333d8d19677SJose E. Roman Input Parameters: 33420f4b53cSBarry Smith + label - The `DMLabel` 335b9907514SLisandro Dalcin . numStrata - The number of stratum values 336b9907514SLisandro Dalcin - stratumValues - The stratum values 337b9907514SLisandro Dalcin 338b9907514SLisandro Dalcin Level: beginner 339b9907514SLisandro Dalcin 34020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 341b9907514SLisandro Dalcin @*/ 342d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 343d71ae5a4SJacob Faibussowitsch { 344b9907514SLisandro Dalcin PetscInt *values, v; 345b9907514SLisandro Dalcin 346b9907514SLisandro Dalcin PetscFunctionBegin; 347b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3484f572ea9SToby Isaac if (numStrata) PetscAssertPointer(stratumValues, 3); 3499f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &values)); 3519566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(values, stratumValues, numStrata)); 3529566063dSJacob Faibussowitsch PetscCall(PetscSortRemoveDupsInt(&numStrata, values)); 353b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 354b9907514SLisandro Dalcin PetscInt *tmpV; 355b9907514SLisandro Dalcin PetscInt *tmpS; 356b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 357b9907514SLisandro Dalcin IS *tmpP, is; 358b9907514SLisandro Dalcin PetscBool *tmpB; 359b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 360b9907514SLisandro Dalcin 3619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpV)); 3629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpS)); 3639f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpH)); 3649f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpP)); 3659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpB)); 366b9907514SLisandro Dalcin label->numStrata = numStrata; 367b9907514SLisandro Dalcin label->stratumValues = tmpV; 368b9907514SLisandro Dalcin label->stratumSizes = tmpS; 369b9907514SLisandro Dalcin label->ht = tmpH; 370b9907514SLisandro Dalcin label->points = tmpP; 371b9907514SLisandro Dalcin label->validIS = tmpB; 372b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 3739566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 3749566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 3759566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, values[v], v)); 376b9907514SLisandro Dalcin tmpV[v] = values[v]; 377b9907514SLisandro Dalcin tmpS[v] = 0; 378b9907514SLisandro Dalcin tmpH[v] = ht; 379b9907514SLisandro Dalcin tmpP[v] = is; 380b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 381b9907514SLisandro Dalcin } 3829566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 383b9907514SLisandro Dalcin } else { 38448a46eb9SPierre Jolivet for (v = 0; v < numStrata; ++v) PetscCall(DMLabelAddStratum(label, values[v])); 385b9907514SLisandro Dalcin } 3869566063dSJacob Faibussowitsch PetscCall(PetscFree(values)); 3873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 388b9907514SLisandro Dalcin } 389b9907514SLisandro Dalcin 390b9907514SLisandro Dalcin /*@ 39120f4b53cSBarry Smith DMLabelAddStrataIS - Adds new stratum values in a `DMLabel` 392b9907514SLisandro Dalcin 39320f4b53cSBarry Smith Not Collective 3945b5e7992SMatthew G. Knepley 395d8d19677SJose E. Roman Input Parameters: 39620f4b53cSBarry Smith + label - The `DMLabel` 397b9907514SLisandro Dalcin - valueIS - Index set with stratum values 398b9907514SLisandro Dalcin 399b9907514SLisandro Dalcin Level: beginner 400b9907514SLisandro Dalcin 40120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 402b9907514SLisandro Dalcin @*/ 403d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 404d71ae5a4SJacob Faibussowitsch { 405b9907514SLisandro Dalcin PetscInt numStrata; 406b9907514SLisandro Dalcin const PetscInt *stratumValues; 407b9907514SLisandro Dalcin 408b9907514SLisandro Dalcin PetscFunctionBegin; 409b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 410b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 4119f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 4129566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata)); 4139566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues)); 4149566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues)); 4153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 416c58f1c22SToby Isaac } 417c58f1c22SToby Isaac 4189f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelView_Concrete_Ascii(DMLabel label, PetscViewer viewer) 419d71ae5a4SJacob Faibussowitsch { 420c58f1c22SToby Isaac PetscInt v; 421c58f1c22SToby Isaac PetscMPIInt rank; 422c58f1c22SToby Isaac 423c58f1c22SToby Isaac PetscFunctionBegin; 4249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 4259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 426c58f1c22SToby Isaac if (label) { 427d67d17b1SMatthew G. Knepley const char *name; 428d67d17b1SMatthew G. Knepley 4299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 4309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name)); 43163a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd)); 432c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 433c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 434ad8374ffSToby Isaac const PetscInt *points; 435c58f1c22SToby Isaac PetscInt p; 436c58f1c22SToby Isaac 4379566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 43848a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 4399566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 440c58f1c22SToby Isaac } 441c58f1c22SToby Isaac } 4429566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 4443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 445c58f1c22SToby Isaac } 446c58f1c22SToby Isaac 44766976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelView_Concrete(DMLabel label, PetscViewer viewer) 4489f6c5813SMatthew G. Knepley { 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)); 5099566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 510b9907514SLisandro Dalcin label->pStart = -1; 511b9907514SLisandro Dalcin label->pEnd = -1; 5129566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 5133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 514d67d17b1SMatthew G. Knepley } 515d67d17b1SMatthew G. Knepley 516d67d17b1SMatthew G. Knepley /*@ 51720f4b53cSBarry Smith DMLabelDestroy - Destroys a `DMLabel` 51884f0b6dfSMatthew G. Knepley 51920f4b53cSBarry Smith Collective 5205b5e7992SMatthew G. Knepley 52184f0b6dfSMatthew G. Knepley Input Parameter: 52220f4b53cSBarry Smith . label - The `DMLabel` 52384f0b6dfSMatthew G. Knepley 52484f0b6dfSMatthew G. Knepley Level: beginner 52584f0b6dfSMatthew G. Knepley 52620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelReset()`, `DMLabelCreate()` 52784f0b6dfSMatthew G. Knepley @*/ 528d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroy(DMLabel *label) 529d71ae5a4SJacob Faibussowitsch { 530c58f1c22SToby Isaac PetscFunctionBegin; 5313ba16761SJacob Faibussowitsch if (!*label) PetscFunctionReturn(PETSC_SUCCESS); 532*f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 1); 533*f4f49eeaSPierre Jolivet if (--((PetscObject)*label)->refct > 0) { 5349371c9d4SSatish Balay *label = NULL; 5353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5369371c9d4SSatish Balay } 5379566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 5389566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 5399566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 5403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 541c58f1c22SToby Isaac } 542c58f1c22SToby Isaac 54366976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDuplicate_Concrete(DMLabel label, DMLabel *labelnew) 5449f6c5813SMatthew G. Knepley { 5459f6c5813SMatthew G. Knepley PetscFunctionBegin; 5469f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 5479f6c5813SMatthew G. Knepley PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 548*f4f49eeaSPierre Jolivet PetscCall(PetscObjectReference((PetscObject)label->points[v])); 5499f6c5813SMatthew G. Knepley (*labelnew)->points[v] = label->points[v]; 5509f6c5813SMatthew G. Knepley } 5519f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5529f6c5813SMatthew G. Knepley PetscCall(PetscHMapIDuplicate(label->hmap, &(*labelnew)->hmap)); 5533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5549f6c5813SMatthew G. Knepley } 5559f6c5813SMatthew G. Knepley 55684f0b6dfSMatthew G. Knepley /*@ 55720f4b53cSBarry Smith DMLabelDuplicate - Duplicates a `DMLabel` 55884f0b6dfSMatthew G. Knepley 55920f4b53cSBarry Smith Collective 5605b5e7992SMatthew G. Knepley 56184f0b6dfSMatthew G. Knepley Input Parameter: 56220f4b53cSBarry Smith . label - The `DMLabel` 56384f0b6dfSMatthew G. Knepley 56484f0b6dfSMatthew G. Knepley Output Parameter: 56520f4b53cSBarry Smith . labelnew - new label 56684f0b6dfSMatthew G. Knepley 56784f0b6dfSMatthew G. Knepley Level: intermediate 56884f0b6dfSMatthew G. Knepley 56920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 57084f0b6dfSMatthew G. Knepley @*/ 571d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 572d71ae5a4SJacob Faibussowitsch { 573d67d17b1SMatthew G. Knepley const char *name; 574c58f1c22SToby Isaac 575c58f1c22SToby Isaac PetscFunctionBegin; 576d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 5779566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 5789566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 5799566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)label), name, labelnew)); 580c58f1c22SToby Isaac 581c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5825aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 5838dcf10e8SMatthew G. Knepley (*labelnew)->readonly = label->readonly; 5849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 5859566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 5869f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->ht)); 5879f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(label->numStrata, &(*labelnew)->points)); 5889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 5899f6c5813SMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 590c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 591c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 592b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 593c58f1c22SToby Isaac } 594c58f1c22SToby Isaac (*labelnew)->pStart = -1; 595c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 596c58f1c22SToby Isaac (*labelnew)->bt = NULL; 5979f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, duplicate, labelnew); 5983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 599c58f1c22SToby Isaac } 600c58f1c22SToby Isaac 601609dae6eSVaclav Hapla /*@C 60220f4b53cSBarry Smith DMLabelCompare - Compare two `DMLabel` objects 603609dae6eSVaclav Hapla 60420f4b53cSBarry Smith Collective; No Fortran Support 605609dae6eSVaclav Hapla 606609dae6eSVaclav Hapla Input Parameters: 607f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 60820f4b53cSBarry Smith . l0 - First `DMLabel` 60920f4b53cSBarry Smith - l1 - Second `DMLabel` 610609dae6eSVaclav Hapla 611a4e35b19SJacob Faibussowitsch Output Parameters: 6125efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 6135efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 614609dae6eSVaclav Hapla 615609dae6eSVaclav Hapla Level: intermediate 616609dae6eSVaclav Hapla 617609dae6eSVaclav Hapla Notes: 6185efe38ccSVaclav Hapla The output flag equal is the same on all processes. 61920f4b53cSBarry Smith If it is passed as `NULL` and difference is found, an error is thrown on all processes. 62020f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 621609dae6eSVaclav Hapla 6225efe38ccSVaclav Hapla The output message is set independently on each rank. 62320f4b53cSBarry Smith It is set to `NULL` if no difference was found on the current rank. It must be freed by user. 62420f4b53cSBarry Smith If message is passed as `NULL` and difference is found, the difference description is printed to stderr in synchronized manner. 62520f4b53cSBarry Smith Make sure to pass `NULL` on all processes. 626609dae6eSVaclav Hapla 627609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 628609dae6eSVaclav Hapla 62920f4b53cSBarry Smith The communicator needs to be specified because currently `DMLabel` can live on `PETSC_COMM_SELF` even if the underlying `DM` is parallel. 6305efe38ccSVaclav Hapla 63120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 632609dae6eSVaclav Hapla @*/ 633d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 634d71ae5a4SJacob Faibussowitsch { 635609dae6eSVaclav Hapla const char *name0, *name1; 636609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 6375efe38ccSVaclav Hapla PetscBool eq; 6385efe38ccSVaclav Hapla PetscMPIInt rank; 639609dae6eSVaclav Hapla 640609dae6eSVaclav Hapla PetscFunctionBegin; 6415efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 6425efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6434f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 4); 6444f572ea9SToby Isaac if (message) PetscAssertPointer(message, 5); 6459566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6469566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 648609dae6eSVaclav Hapla { 649609dae6eSVaclav Hapla PetscInt v0, v1; 650609dae6eSVaclav Hapla 6519566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6529566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6535efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 65448a46eb9SPierre 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)); 655712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6565efe38ccSVaclav Hapla if (!eq) goto finish; 657609dae6eSVaclav Hapla } 658609dae6eSVaclav Hapla { 659609dae6eSVaclav Hapla IS is0, is1; 660609dae6eSVaclav Hapla 6619566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6629566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6639566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6649566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6659566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 66648a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 667712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6685efe38ccSVaclav Hapla if (!eq) goto finish; 669609dae6eSVaclav Hapla } 670609dae6eSVaclav Hapla { 671609dae6eSVaclav Hapla PetscInt i, nValues; 672609dae6eSVaclav Hapla 6739566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 674609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 675609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 676609dae6eSVaclav Hapla PetscInt n; 677609dae6eSVaclav Hapla IS is0, is1; 678609dae6eSVaclav Hapla 6799566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 680609dae6eSVaclav Hapla if (!n) continue; 6819566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6829566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6839566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6849566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6859566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6865efe38ccSVaclav Hapla if (!eq) { 68763a3b9bcSJacob 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)); 6885efe38ccSVaclav Hapla break; 689609dae6eSVaclav Hapla } 690609dae6eSVaclav Hapla } 691712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 692609dae6eSVaclav Hapla } 693609dae6eSVaclav Hapla finish: 6945efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 695609dae6eSVaclav Hapla if (message) { 696609dae6eSVaclav Hapla *message = NULL; 69748a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 6985efe38ccSVaclav Hapla } else { 69948a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 7009566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 7015efe38ccSVaclav Hapla } 7025efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 7035efe38ccSVaclav Hapla if (equal) *equal = eq; 70463a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 7053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 706609dae6eSVaclav Hapla } 707609dae6eSVaclav Hapla 708c6a43d28SMatthew G. Knepley /*@ 709c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 710c6a43d28SMatthew G. Knepley 71120f4b53cSBarry Smith Not Collective 7125b5e7992SMatthew G. Knepley 713c6a43d28SMatthew G. Knepley Input Parameter: 71420f4b53cSBarry Smith . label - The `DMLabel` 715c6a43d28SMatthew G. Knepley 716c6a43d28SMatthew G. Knepley Level: intermediate 717c6a43d28SMatthew G. Knepley 71820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 719c6a43d28SMatthew G. Knepley @*/ 720d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label) 721d71ae5a4SJacob Faibussowitsch { 722c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 723c6a43d28SMatthew G. Knepley 724c6a43d28SMatthew G. Knepley PetscFunctionBegin; 725c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7269566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 727c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 728c6a43d28SMatthew G. Knepley const PetscInt *points; 729c6a43d28SMatthew G. Knepley PetscInt i; 730c6a43d28SMatthew G. Knepley 7319566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 732c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 733c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 734c6a43d28SMatthew G. Knepley 735c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 736c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 737c6a43d28SMatthew G. Knepley } 7389566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 739c6a43d28SMatthew G. Knepley } 740c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 741c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7429566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 7433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 744c6a43d28SMatthew G. Knepley } 745c6a43d28SMatthew G. Knepley 746c6a43d28SMatthew G. Knepley /*@ 747c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 748c6a43d28SMatthew G. Knepley 74920f4b53cSBarry Smith Not Collective 7505b5e7992SMatthew G. Knepley 751c6a43d28SMatthew G. Knepley Input Parameters: 75220f4b53cSBarry Smith + label - The `DMLabel` 753c6a43d28SMatthew G. Knepley . pStart - The smallest point 754c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 755c6a43d28SMatthew G. Knepley 756c6a43d28SMatthew G. Knepley Level: intermediate 757c6a43d28SMatthew G. Knepley 75820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 759c6a43d28SMatthew G. Knepley @*/ 760d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 761d71ae5a4SJacob Faibussowitsch { 762c58f1c22SToby Isaac PetscInt v; 763c58f1c22SToby Isaac 764c58f1c22SToby Isaac PetscFunctionBegin; 765d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7669566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7679566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 768c58f1c22SToby Isaac label->pStart = pStart; 769c58f1c22SToby Isaac label->pEnd = pEnd; 770c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7719566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 772c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 7739f6c5813SMatthew G. Knepley IS pointIS; 774ad8374ffSToby Isaac const PetscInt *points; 775c58f1c22SToby Isaac PetscInt i; 776c58f1c22SToby Isaac 7779f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 7789f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points)); 779c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 780ad8374ffSToby Isaac const PetscInt point = points[i]; 781c58f1c22SToby Isaac 7829f6c5813SMatthew 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); 7839566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 784c58f1c22SToby Isaac } 7859566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 7869f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 787c58f1c22SToby Isaac } 7883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 789c58f1c22SToby Isaac } 790c58f1c22SToby Isaac 791c6a43d28SMatthew G. Knepley /*@ 792c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 793c6a43d28SMatthew G. Knepley 79420f4b53cSBarry Smith Not Collective 7955b5e7992SMatthew G. Knepley 796c6a43d28SMatthew G. Knepley Input Parameter: 79720f4b53cSBarry Smith . label - the `DMLabel` 798c6a43d28SMatthew G. Knepley 799c6a43d28SMatthew G. Knepley Level: intermediate 800c6a43d28SMatthew G. Knepley 80120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 802c6a43d28SMatthew G. Knepley @*/ 803d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label) 804d71ae5a4SJacob Faibussowitsch { 805c58f1c22SToby Isaac PetscFunctionBegin; 806d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 807c58f1c22SToby Isaac label->pStart = -1; 808c58f1c22SToby Isaac label->pEnd = -1; 8099566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 8103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 811c58f1c22SToby Isaac } 812c58f1c22SToby Isaac 813c58f1c22SToby Isaac /*@ 814c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 815c6a43d28SMatthew G. Knepley 81620f4b53cSBarry Smith Not Collective 8175b5e7992SMatthew G. Knepley 818c6a43d28SMatthew G. Knepley Input Parameter: 81920f4b53cSBarry Smith . label - the `DMLabel` 820c6a43d28SMatthew G. Knepley 821c6a43d28SMatthew G. Knepley Output Parameters: 822c6a43d28SMatthew G. Knepley + pStart - The smallest point 823c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 824c6a43d28SMatthew G. Knepley 825c6a43d28SMatthew G. Knepley Level: intermediate 826c6a43d28SMatthew G. Knepley 82720f4b53cSBarry Smith Note: 82820f4b53cSBarry Smith This will compute an index for the label if one does not exist. 82920f4b53cSBarry Smith 83020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 831c6a43d28SMatthew G. Knepley @*/ 832d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 833d71ae5a4SJacob Faibussowitsch { 834c6a43d28SMatthew G. Knepley PetscFunctionBegin; 835c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8369566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 837c6a43d28SMatthew G. Knepley if (pStart) { 8384f572ea9SToby Isaac PetscAssertPointer(pStart, 2); 839c6a43d28SMatthew G. Knepley *pStart = label->pStart; 840c6a43d28SMatthew G. Knepley } 841c6a43d28SMatthew G. Knepley if (pEnd) { 8424f572ea9SToby Isaac PetscAssertPointer(pEnd, 3); 843c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 844c6a43d28SMatthew G. Knepley } 8453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 846c6a43d28SMatthew G. Knepley } 847c6a43d28SMatthew G. Knepley 848c6a43d28SMatthew G. Knepley /*@ 849c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 850c58f1c22SToby Isaac 85120f4b53cSBarry Smith Not Collective 8525b5e7992SMatthew G. Knepley 853c58f1c22SToby Isaac Input Parameters: 85420f4b53cSBarry Smith + label - the `DMLabel` 855c58f1c22SToby Isaac - value - the value 856c58f1c22SToby Isaac 857c58f1c22SToby Isaac Output Parameter: 858c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 859c58f1c22SToby Isaac 860c58f1c22SToby Isaac Level: developer 861c58f1c22SToby Isaac 86220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 863c58f1c22SToby Isaac @*/ 864d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 865d71ae5a4SJacob Faibussowitsch { 866c58f1c22SToby Isaac PetscInt v; 867c58f1c22SToby Isaac 868c58f1c22SToby Isaac PetscFunctionBegin; 869d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8704f572ea9SToby Isaac PetscAssertPointer(contains, 3); 8719566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8720c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 8733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 874c58f1c22SToby Isaac } 875c58f1c22SToby Isaac 876c58f1c22SToby Isaac /*@ 877c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 878c58f1c22SToby Isaac 87920f4b53cSBarry Smith Not Collective 8805b5e7992SMatthew G. Knepley 881c58f1c22SToby Isaac Input Parameters: 88220f4b53cSBarry Smith + label - the `DMLabel` 883c58f1c22SToby Isaac - point - the point 884c58f1c22SToby Isaac 885c58f1c22SToby Isaac Output Parameter: 886c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 887c58f1c22SToby Isaac 888c58f1c22SToby Isaac Level: developer 889c58f1c22SToby Isaac 89020f4b53cSBarry Smith Note: 89120f4b53cSBarry Smith The user must call `DMLabelCreateIndex()` before this function. 89220f4b53cSBarry Smith 89320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 894c58f1c22SToby Isaac @*/ 895d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 896d71ae5a4SJacob Faibussowitsch { 897c58f1c22SToby Isaac PetscFunctionBeginHot; 898d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8994f572ea9SToby Isaac PetscAssertPointer(contains, 3); 9009566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 90176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 90228b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 90363a3b9bcSJacob 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); 90476bd3646SJed Brown } 905c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 9063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 907c58f1c22SToby Isaac } 908c58f1c22SToby Isaac 909c58f1c22SToby Isaac /*@ 910c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 911c58f1c22SToby Isaac 91220f4b53cSBarry Smith Not Collective 9135b5e7992SMatthew G. Knepley 914c58f1c22SToby Isaac Input Parameters: 91520f4b53cSBarry Smith + label - the `DMLabel` 916c58f1c22SToby Isaac . value - the stratum value 917c58f1c22SToby Isaac - point - the point 918c58f1c22SToby Isaac 919c58f1c22SToby Isaac Output Parameter: 920c58f1c22SToby Isaac . contains - true if the stratum contains the point 921c58f1c22SToby Isaac 922c58f1c22SToby Isaac Level: intermediate 923c58f1c22SToby Isaac 92420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 925c58f1c22SToby Isaac @*/ 926d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 927d71ae5a4SJacob Faibussowitsch { 9280c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 929d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9304f572ea9SToby Isaac PetscAssertPointer(contains, 4); 931cffad2c9SToby Isaac if (value == label->defaultValue) { 932cffad2c9SToby Isaac PetscInt pointVal; 9330c3c4a36SLisandro Dalcin 934cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 935cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 936cffad2c9SToby Isaac } else { 937cffad2c9SToby Isaac PetscInt v; 938cffad2c9SToby Isaac 939cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 940cffad2c9SToby Isaac if (v >= 0) { 9419f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 9429f6c5813SMatthew G. Knepley IS is; 943c58f1c22SToby Isaac PetscInt i; 944c58f1c22SToby Isaac 9459f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 9469f6c5813SMatthew G. Knepley PetscCall(ISLocate(is, point, &i)); 9479f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 948cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 949c58f1c22SToby Isaac } else { 950cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 951cffad2c9SToby Isaac } 952cffad2c9SToby Isaac } else { // value is not present 953cffad2c9SToby Isaac *contains = PETSC_FALSE; 954cffad2c9SToby Isaac } 955c58f1c22SToby Isaac } 9563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 957c58f1c22SToby Isaac } 958c58f1c22SToby Isaac 95984f0b6dfSMatthew G. Knepley /*@ 96020f4b53cSBarry Smith DMLabelGetDefaultValue - Get the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9615aa44df4SToby Isaac When a label is created, it is initialized to -1. 9625aa44df4SToby Isaac 96320f4b53cSBarry Smith Not Collective 9645b5e7992SMatthew G. Knepley 96560225df5SJacob Faibussowitsch Input Parameter: 96620f4b53cSBarry Smith . label - a `DMLabel` object 9675aa44df4SToby Isaac 96860225df5SJacob Faibussowitsch Output Parameter: 9695aa44df4SToby Isaac . defaultValue - the default value 9705aa44df4SToby Isaac 9715aa44df4SToby Isaac Level: beginner 9725aa44df4SToby Isaac 97320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 97484f0b6dfSMatthew G. Knepley @*/ 975d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 976d71ae5a4SJacob Faibussowitsch { 9775aa44df4SToby Isaac PetscFunctionBegin; 978d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9795aa44df4SToby Isaac *defaultValue = label->defaultValue; 9803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9815aa44df4SToby Isaac } 9825aa44df4SToby Isaac 98384f0b6dfSMatthew G. Knepley /*@ 98420f4b53cSBarry Smith DMLabelSetDefaultValue - Set the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9855aa44df4SToby Isaac When a label is created, it is initialized to -1. 9865aa44df4SToby Isaac 98720f4b53cSBarry Smith Not Collective 9885b5e7992SMatthew G. Knepley 98960225df5SJacob Faibussowitsch Input Parameter: 99020f4b53cSBarry Smith . label - a `DMLabel` object 9915aa44df4SToby Isaac 99260225df5SJacob Faibussowitsch Output Parameter: 9935aa44df4SToby Isaac . defaultValue - the default value 9945aa44df4SToby Isaac 9955aa44df4SToby Isaac Level: beginner 9965aa44df4SToby Isaac 99720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 99884f0b6dfSMatthew G. Knepley @*/ 999d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 1000d71ae5a4SJacob Faibussowitsch { 10015aa44df4SToby Isaac PetscFunctionBegin; 1002d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10035aa44df4SToby Isaac label->defaultValue = defaultValue; 10043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10055aa44df4SToby Isaac } 10065aa44df4SToby Isaac 1007c58f1c22SToby Isaac /*@ 100820f4b53cSBarry 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 100920f4b53cSBarry Smith `DMLabelSetDefaultValue()`) 1010c58f1c22SToby Isaac 101120f4b53cSBarry Smith Not Collective 10125b5e7992SMatthew G. Knepley 1013c58f1c22SToby Isaac Input Parameters: 101420f4b53cSBarry Smith + label - the `DMLabel` 1015c58f1c22SToby Isaac - point - the point 1016c58f1c22SToby Isaac 1017c58f1c22SToby Isaac Output Parameter: 10188e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 1019c58f1c22SToby Isaac 1020c58f1c22SToby Isaac Level: intermediate 1021c58f1c22SToby Isaac 102220f4b53cSBarry Smith Note: 102320f4b53cSBarry Smith A label may assign multiple values to a point. No guarantees are made about which value is returned in that case. 102420f4b53cSBarry Smith Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum. 102520f4b53cSBarry Smith 102620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1027c58f1c22SToby Isaac @*/ 1028d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 1029d71ae5a4SJacob Faibussowitsch { 1030c58f1c22SToby Isaac PetscInt v; 1031c58f1c22SToby Isaac 10320c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 1033d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10344f572ea9SToby Isaac PetscAssertPointer(value, 3); 10355aa44df4SToby Isaac *value = label->defaultValue; 1036c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 10379f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 10389f6c5813SMatthew G. Knepley IS is; 1039c58f1c22SToby Isaac PetscInt i; 1040c58f1c22SToby Isaac 10419f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 10429566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 10439f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1044c58f1c22SToby Isaac if (i >= 0) { 1045c58f1c22SToby Isaac *value = label->stratumValues[v]; 1046c58f1c22SToby Isaac break; 1047c58f1c22SToby Isaac } 1048c58f1c22SToby Isaac } else { 1049c58f1c22SToby Isaac PetscBool has; 1050c58f1c22SToby Isaac 10519566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 1052c58f1c22SToby Isaac if (has) { 1053c58f1c22SToby Isaac *value = label->stratumValues[v]; 1054c58f1c22SToby Isaac break; 1055c58f1c22SToby Isaac } 1056c58f1c22SToby Isaac } 1057c58f1c22SToby Isaac } 10583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1059c58f1c22SToby Isaac } 1060c58f1c22SToby Isaac 1061c58f1c22SToby Isaac /*@ 106220f4b53cSBarry 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 106320f4b53cSBarry Smith be changed with `DMLabelSetDefaultValue()` to something different), then this function will do nothing. 1064c58f1c22SToby Isaac 106520f4b53cSBarry Smith Not Collective 10665b5e7992SMatthew G. Knepley 1067c58f1c22SToby Isaac Input Parameters: 106820f4b53cSBarry Smith + label - the `DMLabel` 1069c58f1c22SToby Isaac . point - the point 1070c58f1c22SToby Isaac - value - The point value 1071c58f1c22SToby Isaac 1072c58f1c22SToby Isaac Level: intermediate 1073c58f1c22SToby Isaac 107420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1075c58f1c22SToby Isaac @*/ 1076d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1077d71ae5a4SJacob Faibussowitsch { 1078c58f1c22SToby Isaac PetscInt v; 1079c58f1c22SToby Isaac 1080c58f1c22SToby Isaac PetscFunctionBegin; 1081d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10820c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10833ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 10849f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 10859566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1086c58f1c22SToby Isaac /* Set key */ 10879566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10889566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 10893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1090c58f1c22SToby Isaac } 1091c58f1c22SToby Isaac 1092c58f1c22SToby Isaac /*@ 1093c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1094c58f1c22SToby Isaac 109520f4b53cSBarry Smith Not Collective 10965b5e7992SMatthew G. Knepley 1097c58f1c22SToby Isaac Input Parameters: 109820f4b53cSBarry Smith + label - the `DMLabel` 1099c58f1c22SToby Isaac . point - the point 1100c58f1c22SToby Isaac - value - The point value 1101c58f1c22SToby Isaac 1102c58f1c22SToby Isaac Level: intermediate 1103c58f1c22SToby Isaac 110420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1105c58f1c22SToby Isaac @*/ 1106d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1107d71ae5a4SJacob Faibussowitsch { 1108ad8374ffSToby Isaac PetscInt v; 1109c58f1c22SToby Isaac 1110c58f1c22SToby Isaac PetscFunctionBegin; 1111d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11129f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 1113c58f1c22SToby Isaac /* Find label value */ 11149566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 11153ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 11160c3c4a36SLisandro Dalcin 1117eeed21e7SToby Isaac if (label->bt) { 111863a3b9bcSJacob 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); 11199566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1120eeed21e7SToby Isaac } 11210c3c4a36SLisandro Dalcin 11220c3c4a36SLisandro Dalcin /* Delete key */ 11239566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11249566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 11253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1126c58f1c22SToby Isaac } 1127c58f1c22SToby Isaac 1128c58f1c22SToby Isaac /*@ 112920f4b53cSBarry Smith DMLabelInsertIS - Set all points in the `IS` to a value 1130c58f1c22SToby Isaac 113120f4b53cSBarry Smith Not Collective 11325b5e7992SMatthew G. Knepley 1133c58f1c22SToby Isaac Input Parameters: 113420f4b53cSBarry Smith + label - the `DMLabel` 11352fe279fdSBarry Smith . is - the point `IS` 1136c58f1c22SToby Isaac - value - The point value 1137c58f1c22SToby Isaac 1138c58f1c22SToby Isaac Level: intermediate 1139c58f1c22SToby Isaac 114020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1141c58f1c22SToby Isaac @*/ 1142d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1143d71ae5a4SJacob Faibussowitsch { 11440c3c4a36SLisandro Dalcin PetscInt v, n, p; 1145c58f1c22SToby Isaac const PetscInt *points; 1146c58f1c22SToby Isaac 1147c58f1c22SToby Isaac PetscFunctionBegin; 1148d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1149c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 11500c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11513ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 11529f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 11539566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 11540c3c4a36SLisandro Dalcin /* Set keys */ 11559566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11569566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 11579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 11589566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 11599566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 11603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1161c58f1c22SToby Isaac } 1162c58f1c22SToby Isaac 116384f0b6dfSMatthew G. Knepley /*@ 116420f4b53cSBarry Smith DMLabelGetNumValues - Get the number of values that the `DMLabel` takes 116584f0b6dfSMatthew G. Knepley 116620f4b53cSBarry Smith Not Collective 11675b5e7992SMatthew G. Knepley 116884f0b6dfSMatthew G. Knepley Input Parameter: 116920f4b53cSBarry Smith . label - the `DMLabel` 117084f0b6dfSMatthew G. Knepley 117101d2d390SJose E. Roman Output Parameter: 117284f0b6dfSMatthew G. Knepley . numValues - the number of values 117384f0b6dfSMatthew G. Knepley 117484f0b6dfSMatthew G. Knepley Level: intermediate 117584f0b6dfSMatthew G. Knepley 117620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 117784f0b6dfSMatthew G. Knepley @*/ 1178d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1179d71ae5a4SJacob Faibussowitsch { 1180c58f1c22SToby Isaac PetscFunctionBegin; 1181d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11824f572ea9SToby Isaac PetscAssertPointer(numValues, 2); 1183c58f1c22SToby Isaac *numValues = label->numStrata; 11843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1185c58f1c22SToby Isaac } 1186c58f1c22SToby Isaac 118784f0b6dfSMatthew G. Knepley /*@ 118820f4b53cSBarry Smith DMLabelGetValueIS - Get an `IS` of all values that the `DMlabel` takes 118984f0b6dfSMatthew G. Knepley 119020f4b53cSBarry Smith Not Collective 11915b5e7992SMatthew G. Knepley 119284f0b6dfSMatthew G. Knepley Input Parameter: 119320f4b53cSBarry Smith . label - the `DMLabel` 119484f0b6dfSMatthew G. Knepley 119501d2d390SJose E. Roman Output Parameter: 119660225df5SJacob Faibussowitsch . values - the value `IS` 119784f0b6dfSMatthew G. Knepley 119884f0b6dfSMatthew G. Knepley Level: intermediate 119984f0b6dfSMatthew G. Knepley 12001d04cbbeSVaclav Hapla Notes: 120120f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 120220f4b53cSBarry Smith Strata which are allocated but empty [`DMLabelGetStratumSize()` yields 0] are counted. 120320f4b53cSBarry Smith If you need to count only nonempty strata, use `DMLabelGetNonEmptyStratumValuesIS()`. 12041d04cbbeSVaclav Hapla 120520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 120684f0b6dfSMatthew G. Knepley @*/ 1207d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1208d71ae5a4SJacob Faibussowitsch { 1209c58f1c22SToby Isaac PetscFunctionBegin; 1210d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12114f572ea9SToby Isaac PetscAssertPointer(values, 2); 12129566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1214c58f1c22SToby Isaac } 1215c58f1c22SToby Isaac 121684f0b6dfSMatthew G. Knepley /*@ 121720f4b53cSBarry Smith DMLabelGetNonEmptyStratumValuesIS - Get an `IS` of all values that the `DMlabel` takes 12181d04cbbeSVaclav Hapla 121920f4b53cSBarry Smith Not Collective 12201d04cbbeSVaclav Hapla 12211d04cbbeSVaclav Hapla Input Parameter: 122220f4b53cSBarry Smith . label - the `DMLabel` 12231d04cbbeSVaclav Hapla 1224d5b43468SJose E. Roman Output Parameter: 122560225df5SJacob Faibussowitsch . values - the value `IS` 12261d04cbbeSVaclav Hapla 12271d04cbbeSVaclav Hapla Level: intermediate 12281d04cbbeSVaclav Hapla 12291d04cbbeSVaclav Hapla Notes: 123020f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 123120f4b53cSBarry Smith This is similar to `DMLabelGetValueIS()` but counts only nonempty strata. 12321d04cbbeSVaclav Hapla 123320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 12341d04cbbeSVaclav Hapla @*/ 1235d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 1236d71ae5a4SJacob Faibussowitsch { 12371d04cbbeSVaclav Hapla PetscInt i, j; 12381d04cbbeSVaclav Hapla PetscInt *valuesArr; 12391d04cbbeSVaclav Hapla 12401d04cbbeSVaclav Hapla PetscFunctionBegin; 12411d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12424f572ea9SToby Isaac PetscAssertPointer(values, 2); 12439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 12441d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 12451d04cbbeSVaclav Hapla PetscInt n; 12461d04cbbeSVaclav Hapla 12479566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 12481d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 12491d04cbbeSVaclav Hapla } 12501d04cbbeSVaclav Hapla if (j == label->numStrata) { 12519566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12521d04cbbeSVaclav Hapla } else { 12539566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 12541d04cbbeSVaclav Hapla } 12559566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 12563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12571d04cbbeSVaclav Hapla } 12581d04cbbeSVaclav Hapla 12591d04cbbeSVaclav Hapla /*@ 126020f4b53cSBarry Smith DMLabelGetValueIndex - Get the index of a given value in the list of values for the `DMlabel`, or -1 if it is not present 1261d123abd9SMatthew G. Knepley 126220f4b53cSBarry Smith Not Collective 1263d123abd9SMatthew G. Knepley 1264d123abd9SMatthew G. Knepley Input Parameters: 126520f4b53cSBarry Smith + label - the `DMLabel` 126697bb3fdcSJose E. Roman - value - the value 1267d123abd9SMatthew G. Knepley 126801d2d390SJose E. Roman Output Parameter: 1269d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1270d123abd9SMatthew G. Knepley 1271d123abd9SMatthew G. Knepley Level: intermediate 1272d123abd9SMatthew G. Knepley 127320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1274d123abd9SMatthew G. Knepley @*/ 1275d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1276d71ae5a4SJacob Faibussowitsch { 1277d123abd9SMatthew G. Knepley PetscInt v; 1278d123abd9SMatthew G. Knepley 1279d123abd9SMatthew G. Knepley PetscFunctionBegin; 1280d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12814f572ea9SToby Isaac PetscAssertPointer(index, 3); 1282d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 12839371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 12849371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1285d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1286d123abd9SMatthew G. Knepley else *index = v; 12873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1288d123abd9SMatthew G. Knepley } 1289d123abd9SMatthew G. Knepley 1290d123abd9SMatthew G. Knepley /*@ 129184f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 129284f0b6dfSMatthew G. Knepley 129320f4b53cSBarry Smith Not Collective 12945b5e7992SMatthew G. Knepley 129584f0b6dfSMatthew G. Knepley Input Parameters: 129620f4b53cSBarry Smith + label - the `DMLabel` 129784f0b6dfSMatthew G. Knepley - value - the stratum value 129884f0b6dfSMatthew G. Knepley 129901d2d390SJose E. Roman Output Parameter: 130084f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 130184f0b6dfSMatthew G. Knepley 130284f0b6dfSMatthew G. Knepley Level: intermediate 130384f0b6dfSMatthew G. Knepley 130420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 130584f0b6dfSMatthew G. Knepley @*/ 1306d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1307d71ae5a4SJacob Faibussowitsch { 1308fada774cSMatthew G. Knepley PetscInt v; 1309fada774cSMatthew G. Knepley 1310fada774cSMatthew G. Knepley PetscFunctionBegin; 1311d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13124f572ea9SToby Isaac PetscAssertPointer(exists, 3); 13139566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13140c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 13153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1316fada774cSMatthew G. Knepley } 1317fada774cSMatthew G. Knepley 131884f0b6dfSMatthew G. Knepley /*@ 131984f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 132084f0b6dfSMatthew G. Knepley 132120f4b53cSBarry Smith Not Collective 13225b5e7992SMatthew G. Knepley 132384f0b6dfSMatthew G. Knepley Input Parameters: 132420f4b53cSBarry Smith + label - the `DMLabel` 132584f0b6dfSMatthew G. Knepley - value - the stratum value 132684f0b6dfSMatthew G. Knepley 132701d2d390SJose E. Roman Output Parameter: 132884f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 132984f0b6dfSMatthew G. Knepley 133084f0b6dfSMatthew G. Knepley Level: intermediate 133184f0b6dfSMatthew G. Knepley 133220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 133384f0b6dfSMatthew G. Knepley @*/ 1334d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1335d71ae5a4SJacob Faibussowitsch { 1336c58f1c22SToby Isaac PetscInt v; 1337c58f1c22SToby Isaac 1338c58f1c22SToby Isaac PetscFunctionBegin; 1339d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13404f572ea9SToby Isaac PetscAssertPointer(size, 3); 13419566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13429566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 13433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1344c58f1c22SToby Isaac } 1345c58f1c22SToby Isaac 134684f0b6dfSMatthew G. Knepley /*@ 134784f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 134884f0b6dfSMatthew G. Knepley 134920f4b53cSBarry Smith Not Collective 13505b5e7992SMatthew G. Knepley 135184f0b6dfSMatthew G. Knepley Input Parameters: 135220f4b53cSBarry Smith + label - the `DMLabel` 135384f0b6dfSMatthew G. Knepley - value - the stratum value 135484f0b6dfSMatthew G. Knepley 135501d2d390SJose E. Roman Output Parameters: 135684f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 135784f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 135884f0b6dfSMatthew G. Knepley 135984f0b6dfSMatthew G. Knepley Level: intermediate 136084f0b6dfSMatthew G. Knepley 136120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 136284f0b6dfSMatthew G. Knepley @*/ 1363d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1364d71ae5a4SJacob Faibussowitsch { 13659f6c5813SMatthew G. Knepley IS is; 13660c3c4a36SLisandro Dalcin PetscInt v, min, max; 1367c58f1c22SToby Isaac 1368c58f1c22SToby Isaac PetscFunctionBegin; 1369d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13709371c9d4SSatish Balay if (start) { 13714f572ea9SToby Isaac PetscAssertPointer(start, 3); 13729371c9d4SSatish Balay *start = -1; 13739371c9d4SSatish Balay } 13749371c9d4SSatish Balay if (end) { 13754f572ea9SToby Isaac PetscAssertPointer(end, 4); 13769371c9d4SSatish Balay *end = -1; 13779371c9d4SSatish Balay } 13789566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13793ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 13809566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13813ba16761SJacob Faibussowitsch if (label->stratumSizes[v] <= 0) PetscFunctionReturn(PETSC_SUCCESS); 13829f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 13839f6c5813SMatthew G. Knepley PetscCall(ISGetMinMax(is, &min, &max)); 13849f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1385d6cb179aSToby Isaac if (start) *start = min; 1386d6cb179aSToby Isaac if (end) *end = max + 1; 13873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1388c58f1c22SToby Isaac } 1389c58f1c22SToby Isaac 139066976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelGetStratumIS_Concrete(DMLabel label, PetscInt v, IS *pointIS) 13919f6c5813SMatthew G. Knepley { 13929f6c5813SMatthew G. Knepley PetscFunctionBegin; 13939f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)label->points[v])); 13949f6c5813SMatthew G. Knepley *pointIS = label->points[v]; 13953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13969f6c5813SMatthew G. Knepley } 13979f6c5813SMatthew G. Knepley 139884f0b6dfSMatthew G. Knepley /*@ 139920f4b53cSBarry Smith DMLabelGetStratumIS - Get an `IS` with the stratum points 140084f0b6dfSMatthew G. Knepley 140120f4b53cSBarry Smith Not Collective 14025b5e7992SMatthew G. Knepley 140384f0b6dfSMatthew G. Knepley Input Parameters: 140420f4b53cSBarry Smith + label - the `DMLabel` 140584f0b6dfSMatthew G. Knepley - value - the stratum value 140684f0b6dfSMatthew G. Knepley 140701d2d390SJose E. Roman Output Parameter: 140884f0b6dfSMatthew G. Knepley . points - The stratum points 140984f0b6dfSMatthew G. Knepley 141084f0b6dfSMatthew G. Knepley Level: intermediate 141184f0b6dfSMatthew G. Knepley 1412593ce467SVaclav Hapla Notes: 141320f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 141420f4b53cSBarry Smith Returns `NULL` if the stratum is empty. 1415593ce467SVaclav Hapla 141620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 141784f0b6dfSMatthew G. Knepley @*/ 1418d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1419d71ae5a4SJacob Faibussowitsch { 1420c58f1c22SToby Isaac PetscInt v; 1421c58f1c22SToby Isaac 1422c58f1c22SToby Isaac PetscFunctionBegin; 1423d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14244f572ea9SToby Isaac PetscAssertPointer(points, 3); 1425c58f1c22SToby Isaac *points = NULL; 14269566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14273ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14289566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14299f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, points); 14303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1431c58f1c22SToby Isaac } 1432c58f1c22SToby Isaac 143384f0b6dfSMatthew G. Knepley /*@ 143420f4b53cSBarry Smith DMLabelSetStratumIS - Set the stratum points using an `IS` 143584f0b6dfSMatthew G. Knepley 143620f4b53cSBarry Smith Not Collective 14375b5e7992SMatthew G. Knepley 143884f0b6dfSMatthew G. Knepley Input Parameters: 143920f4b53cSBarry Smith + label - the `DMLabel` 144084f0b6dfSMatthew G. Knepley . value - the stratum value 144160225df5SJacob Faibussowitsch - is - The stratum points 144284f0b6dfSMatthew G. Knepley 144384f0b6dfSMatthew G. Knepley Level: intermediate 144484f0b6dfSMatthew G. Knepley 144520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 144684f0b6dfSMatthew G. Knepley @*/ 1447d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 1448d71ae5a4SJacob Faibussowitsch { 14490c3c4a36SLisandro Dalcin PetscInt v; 14504de306b1SToby Isaac 14514de306b1SToby Isaac PetscFunctionBegin; 1452d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1453d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 14549f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 14559566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 14563ba16761SJacob Faibussowitsch if (is == label->points[v]) PetscFunctionReturn(PETSC_SUCCESS); 14579566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 1458*f4f49eeaSPierre Jolivet PetscCall(ISGetLocalSize(is, &label->stratumSizes[v])); 14599566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 1460*f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 14610c3c4a36SLisandro Dalcin label->points[v] = is; 14620c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 14639566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 14644de306b1SToby Isaac if (label->bt) { 14654de306b1SToby Isaac const PetscInt *points; 14664de306b1SToby Isaac PetscInt p; 14674de306b1SToby Isaac 14689566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 14694de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 14704de306b1SToby Isaac const PetscInt point = points[p]; 14714de306b1SToby Isaac 147263a3b9bcSJacob 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); 14739566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 14744de306b1SToby Isaac } 14754de306b1SToby Isaac } 14763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14774de306b1SToby Isaac } 14784de306b1SToby Isaac 147984f0b6dfSMatthew G. Knepley /*@ 148084f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 14814de306b1SToby Isaac 148220f4b53cSBarry Smith Not Collective 14835b5e7992SMatthew G. Knepley 148484f0b6dfSMatthew G. Knepley Input Parameters: 148520f4b53cSBarry Smith + label - the `DMLabel` 148684f0b6dfSMatthew G. Knepley - value - the stratum value 148784f0b6dfSMatthew G. Knepley 148884f0b6dfSMatthew G. Knepley Level: intermediate 148984f0b6dfSMatthew G. Knepley 149020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 149184f0b6dfSMatthew G. Knepley @*/ 1492d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1493d71ae5a4SJacob Faibussowitsch { 1494c58f1c22SToby Isaac PetscInt v; 1495c58f1c22SToby Isaac 1496c58f1c22SToby Isaac PetscFunctionBegin; 1497d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14989f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 14999566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15003ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15014de306b1SToby Isaac if (label->validIS[v]) { 15024de306b1SToby Isaac if (label->bt) { 1503c58f1c22SToby Isaac PetscInt i; 1504ad8374ffSToby Isaac const PetscInt *points; 1505c58f1c22SToby Isaac 15069566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1507c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1508ad8374ffSToby Isaac const PetscInt point = points[i]; 1509c58f1c22SToby Isaac 151063a3b9bcSJacob 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); 15119566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1512c58f1c22SToby Isaac } 15139566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1514c58f1c22SToby Isaac } 1515c58f1c22SToby Isaac label->stratumSizes[v] = 0; 15169566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 15179566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 15189566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 15199566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1520c58f1c22SToby Isaac } else { 15219566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1522c58f1c22SToby Isaac } 15233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1524c58f1c22SToby Isaac } 1525c58f1c22SToby Isaac 152684f0b6dfSMatthew G. Knepley /*@ 1527412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1528412e9a14SMatthew G. Knepley 152920f4b53cSBarry Smith Not Collective 1530412e9a14SMatthew G. Knepley 1531412e9a14SMatthew G. Knepley Input Parameters: 153220f4b53cSBarry Smith + label - The `DMLabel` 1533412e9a14SMatthew G. Knepley . value - The label value for all points 1534412e9a14SMatthew G. Knepley . pStart - The first point 1535412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1536412e9a14SMatthew G. Knepley 1537412e9a14SMatthew G. Knepley Level: intermediate 1538412e9a14SMatthew G. Knepley 153920f4b53cSBarry Smith Note: 154020f4b53cSBarry Smith The marks points are [`pStart`, `pEnd`), and only the bounds are stored. 154120f4b53cSBarry Smith 154220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1543412e9a14SMatthew G. Knepley @*/ 1544d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1545d71ae5a4SJacob Faibussowitsch { 1546412e9a14SMatthew G. Knepley IS pIS; 1547412e9a14SMatthew G. Knepley 1548412e9a14SMatthew G. Knepley PetscFunctionBegin; 15499566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 15509566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 15519566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 15523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1553412e9a14SMatthew G. Knepley } 1554412e9a14SMatthew G. Knepley 1555412e9a14SMatthew G. Knepley /*@ 1556d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1557d123abd9SMatthew G. Knepley 155820f4b53cSBarry Smith Not Collective 1559d123abd9SMatthew G. Knepley 1560d123abd9SMatthew G. Knepley Input Parameters: 156120f4b53cSBarry Smith + label - The `DMLabel` 1562d123abd9SMatthew G. Knepley . value - The label value 1563d123abd9SMatthew G. Knepley - p - A point with this value 1564d123abd9SMatthew G. Knepley 1565d123abd9SMatthew G. Knepley Output Parameter: 1566d123abd9SMatthew 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 1567d123abd9SMatthew G. Knepley 1568d123abd9SMatthew G. Knepley Level: intermediate 1569d123abd9SMatthew G. Knepley 157020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1571d123abd9SMatthew G. Knepley @*/ 1572d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1573d71ae5a4SJacob Faibussowitsch { 15749f6c5813SMatthew G. Knepley IS pointIS; 1575d123abd9SMatthew G. Knepley const PetscInt *indices; 1576d123abd9SMatthew G. Knepley PetscInt v; 1577d123abd9SMatthew G. Knepley 1578d123abd9SMatthew G. Knepley PetscFunctionBegin; 1579d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15804f572ea9SToby Isaac PetscAssertPointer(index, 4); 1581d123abd9SMatthew G. Knepley *index = -1; 15829566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15833ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15849566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 15859f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 15869f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &indices)); 15879566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 15889f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(pointIS, &indices)); 15899f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 15903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1591d123abd9SMatthew G. Knepley } 1592d123abd9SMatthew G. Knepley 1593d123abd9SMatthew G. Knepley /*@ 159420f4b53cSBarry Smith DMLabelFilter - Remove all points outside of [`start`, `end`) 159584f0b6dfSMatthew G. Knepley 159620f4b53cSBarry Smith Not Collective 15975b5e7992SMatthew G. Knepley 159884f0b6dfSMatthew G. Knepley Input Parameters: 159920f4b53cSBarry Smith + label - the `DMLabel` 160022cd2cdaSVaclav Hapla . start - the first point kept 160122cd2cdaSVaclav Hapla - end - one more than the last point kept 160284f0b6dfSMatthew G. Knepley 160384f0b6dfSMatthew G. Knepley Level: intermediate 160484f0b6dfSMatthew G. Knepley 160520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 160684f0b6dfSMatthew G. Knepley @*/ 1607d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1608d71ae5a4SJacob Faibussowitsch { 1609c58f1c22SToby Isaac PetscInt v; 1610c58f1c22SToby Isaac 1611c58f1c22SToby Isaac PetscFunctionBegin; 1612d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16139f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16149566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 16159566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16169f6c5813SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 16179f6c5813SMatthew G. Knepley PetscCall(ISGeneralFilter(label->points[v], start, end)); 16189f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(label->points[v], &label->stratumSizes[v])); 16199f6c5813SMatthew G. Knepley } 16209566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 16213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1622c58f1c22SToby Isaac } 1623c58f1c22SToby Isaac 162484f0b6dfSMatthew G. Knepley /*@ 162584f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 162684f0b6dfSMatthew G. Knepley 162720f4b53cSBarry Smith Not Collective 16285b5e7992SMatthew G. Knepley 162984f0b6dfSMatthew G. Knepley Input Parameters: 163020f4b53cSBarry Smith + label - the `DMLabel` 163184f0b6dfSMatthew G. Knepley - permutation - the point permutation 163284f0b6dfSMatthew G. Knepley 163384f0b6dfSMatthew G. Knepley Output Parameter: 163460225df5SJacob Faibussowitsch . labelNew - the new label containing the permuted points 163584f0b6dfSMatthew G. Knepley 163684f0b6dfSMatthew G. Knepley Level: intermediate 163784f0b6dfSMatthew G. Knepley 163820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 163984f0b6dfSMatthew G. Knepley @*/ 1640d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1641d71ae5a4SJacob Faibussowitsch { 1642c58f1c22SToby Isaac const PetscInt *perm; 1643c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1644c58f1c22SToby Isaac 1645c58f1c22SToby Isaac PetscFunctionBegin; 1646d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1647d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 16489f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16499566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16509566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 16519566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 16529566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 16539566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1654c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1655c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1656ad8374ffSToby Isaac const PetscInt *points; 1657ad8374ffSToby Isaac PetscInt *pointsNew; 1658c58f1c22SToby Isaac 16599566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 16609f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(size, &pointsNew)); 1661c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1662ad8374ffSToby Isaac const PetscInt point = points[q]; 1663c58f1c22SToby Isaac 166463a3b9bcSJacob 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); 1665ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1666c58f1c22SToby Isaac } 16679566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 16689566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 16699566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1670fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 16719566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 16729566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1673fa8e8ae5SToby Isaac } else { 16749566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1675fa8e8ae5SToby Isaac } 16769566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1677c58f1c22SToby Isaac } 16789566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1679c58f1c22SToby Isaac if (label->bt) { 16809566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 16819566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1682c58f1c22SToby Isaac } 16833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1684c58f1c22SToby Isaac } 1685c58f1c22SToby Isaac 168666976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 1687d71ae5a4SJacob Faibussowitsch { 168826c55118SMichael Lange MPI_Comm comm; 1689eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 169026c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 169126c55118SMichael Lange PetscSection rootSection; 169226c55118SMichael Lange PetscSF labelSF; 169326c55118SMichael Lange 169426c55118SMichael Lange PetscFunctionBegin; 16959566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 16969566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 169726c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 169826c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 16999566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 17009566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 17019566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 170226c55118SMichael Lange if (label) { 170326c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1704ad8374ffSToby Isaac const PetscInt *points; 1705ad8374ffSToby Isaac 17069566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 170748a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 17089566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 170926c55118SMichael Lange } 171026c55118SMichael Lange } 17119566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 171226c55118SMichael Lange /* Create a point-wise array of stratum values */ 17139566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 17149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 17159566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 171626c55118SMichael Lange if (label) { 171726c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1718ad8374ffSToby Isaac const PetscInt *points; 1719ad8374ffSToby Isaac 17209566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 172126c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1722ad8374ffSToby Isaac const PetscInt p = points[l]; 17239566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 172426c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 172526c55118SMichael Lange } 17269566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 172726c55118SMichael Lange } 172826c55118SMichael Lange } 172926c55118SMichael Lange /* Build SF that maps label points to remote processes */ 17309566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 17319566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 17329566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 17339566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 173426c55118SMichael Lange /* Send the strata for each point over the derived SF */ 17359566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 17369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 17379566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 17389566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 173926c55118SMichael Lange /* Clean up */ 17409566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 17419566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 17429566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 17439566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 17443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 174526c55118SMichael Lange } 174626c55118SMichael Lange 174784f0b6dfSMatthew G. Knepley /*@ 174820f4b53cSBarry Smith DMLabelDistribute - Create a new label pushed forward over the `PetscSF` 174984f0b6dfSMatthew G. Knepley 175020f4b53cSBarry Smith Collective 17515b5e7992SMatthew G. Knepley 175284f0b6dfSMatthew G. Knepley Input Parameters: 175320f4b53cSBarry Smith + label - the `DMLabel` 175484f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 175584f0b6dfSMatthew G. Knepley 175684f0b6dfSMatthew G. Knepley Output Parameter: 175760225df5SJacob Faibussowitsch . labelNew - the new redistributed label 175884f0b6dfSMatthew G. Knepley 175984f0b6dfSMatthew G. Knepley Level: intermediate 176084f0b6dfSMatthew G. Knepley 176120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 176284f0b6dfSMatthew G. Knepley @*/ 1763d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1764d71ae5a4SJacob Faibussowitsch { 1765c58f1c22SToby Isaac MPI_Comm comm; 176626c55118SMichael Lange PetscSection leafSection; 176726c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 176826c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1769ad8374ffSToby Isaac PetscInt **points; 1770d67d17b1SMatthew G. Knepley const char *lname = NULL; 1771c58f1c22SToby Isaac char *name; 1772c58f1c22SToby Isaac PetscInt nameSize; 1773e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1774c58f1c22SToby Isaac size_t len = 0; 177526c55118SMichael Lange PetscMPIInt rank; 1776c58f1c22SToby Isaac 1777c58f1c22SToby Isaac PetscFunctionBegin; 1778d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1779f018e600SMatthew G. Knepley if (label) { 1780f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 17819f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 17829566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1783f018e600SMatthew G. Knepley } 17849566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 17859566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1786c58f1c22SToby Isaac /* Bcast name */ 1787dd400576SPatrick Sanan if (rank == 0) { 17889566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 17899566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1790d67d17b1SMatthew G. Knepley } 1791c58f1c22SToby Isaac nameSize = len; 17929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 17939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 17949566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 17959566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 17969566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 17979566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 179877d236dfSMichael Lange /* Bcast defaultValue */ 1799dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 18009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 180126c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 18029566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 18035cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 18049566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 18059566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 18069566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 18079566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 18089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1809ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 18109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 18115cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 18125cbdf6fcSMichael Lange offset = 0; 18139566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 18149566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 181548a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 18165cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1817231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 18189371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 18199371c9d4SSatish Balay leafStrata[p] = s; 18209371c9d4SSatish Balay break; 18219371c9d4SSatish Balay } 18225cbdf6fcSMichael Lange } 18235cbdf6fcSMichael Lange } 1824c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 18259566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 18269566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1827c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18289566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18299566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1830ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1831c58f1c22SToby Isaac } 18329566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 18339f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 18349f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &points)); 1835c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 18369566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 1837*f4f49eeaSPierre Jolivet PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &points[s])); 1838c58f1c22SToby Isaac } 1839c58f1c22SToby Isaac /* Insert points into new strata */ 18409566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 18419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1842c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1845c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1846c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1847ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1848c58f1c22SToby Isaac } 1849c58f1c22SToby Isaac } 1850ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1851*f4f49eeaSPierre Jolivet PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &points[s][0], PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 18529566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1853ad8374ffSToby Isaac } 18549566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 18559566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 18569566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 18579566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 18589566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 18593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1860c58f1c22SToby Isaac } 1861c58f1c22SToby Isaac 18627937d9ceSMichael Lange /*@ 18637937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 18647937d9ceSMichael Lange 186520f4b53cSBarry Smith Collective 18665b5e7992SMatthew G. Knepley 18677937d9ceSMichael Lange Input Parameters: 186820f4b53cSBarry Smith + label - the `DMLabel` 186920f4b53cSBarry Smith - sf - the `PetscSF` communication map 18707937d9ceSMichael Lange 18712fe279fdSBarry Smith Output Parameter: 187220f4b53cSBarry Smith . labelNew - the new `DMLabel` with localised leaf values 18737937d9ceSMichael Lange 18747937d9ceSMichael Lange Level: developer 18757937d9ceSMichael Lange 187620f4b53cSBarry Smith Note: 187720f4b53cSBarry Smith This is the inverse operation to `DMLabelDistribute()`. 18787937d9ceSMichael Lange 187920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 18807937d9ceSMichael Lange @*/ 1881d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 1882d71ae5a4SJacob Faibussowitsch { 18837937d9ceSMichael Lange MPI_Comm comm; 18847937d9ceSMichael Lange PetscSection rootSection; 18857937d9ceSMichael Lange PetscSF sfLabel; 18867937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 18877937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 18887937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 18897937d9ceSMichael Lange PetscInt *rootStrata; 1890d67d17b1SMatthew G. Knepley const char *lname; 18917937d9ceSMichael Lange char *name; 18927937d9ceSMichael Lange PetscInt nameSize; 18937937d9ceSMichael Lange size_t len = 0; 18949852e123SBarry Smith PetscMPIInt rank, size; 18957937d9ceSMichael Lange 18967937d9ceSMichael Lange PetscFunctionBegin; 1897d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1898d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 18999f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 19009566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 19019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 19029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 19037937d9ceSMichael Lange /* Bcast name */ 1904dd400576SPatrick Sanan if (rank == 0) { 19059566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 19069566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1907d67d17b1SMatthew G. Knepley } 19087937d9ceSMichael Lange nameSize = len; 19099566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 19109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 19119566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 19129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 19139566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 19149566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 19157937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 19167937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 19177937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 19189566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 19199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1920dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 19217937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 19228212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 19238212dd46SStefano Zampini 19248212dd46SStefano Zampini leafPoints[ilp].index = ilp; 19258212dd46SStefano Zampini leafPoints[ilp].rank = rank; 19267937d9ceSMichael Lange } 19279566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 19289566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 19297937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 19309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 19319566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 19329566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 19339566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 19349566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 19357937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 19369566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 19377937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 19387937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 19397937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 19409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 19419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 19429566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 19437937d9ceSMichael Lange } 19447937d9ceSMichael Lange idx += rootDegree[p]; 19457937d9ceSMichael Lange } 19469566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 19479566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 19489566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 19499566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 19503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19517937d9ceSMichael Lange } 19527937d9ceSMichael Lange 1953d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1954d71ae5a4SJacob Faibussowitsch { 1955d42890abSMatthew G. Knepley const PetscInt *degree; 1956d42890abSMatthew G. Knepley const PetscInt *points; 1957d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1958d42890abSMatthew G. Knepley 1959d42890abSMatthew G. Knepley PetscFunctionBegin; 1960d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1961d42890abSMatthew G. Knepley /* Add in leaves */ 1962d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1963d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1964d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 1965d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 1966d42890abSMatthew G. Knepley } 1967d42890abSMatthew G. Knepley /* Add in shared roots */ 1968d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1969d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1970d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1971d42890abSMatthew G. Knepley if (degree[r]) { 1972d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1973d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 1974d42890abSMatthew G. Knepley } 1975d42890abSMatthew G. Knepley } 19763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1977d42890abSMatthew G. Knepley } 1978d42890abSMatthew G. Knepley 1979d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 1980d71ae5a4SJacob Faibussowitsch { 1981d42890abSMatthew G. Knepley const PetscInt *degree; 1982d42890abSMatthew G. Knepley const PetscInt *points; 1983d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1984d42890abSMatthew G. Knepley 1985d42890abSMatthew G. Knepley PetscFunctionBegin; 1986d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1987d42890abSMatthew G. Knepley /* Read out leaves */ 1988d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1989d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1990d42890abSMatthew G. Knepley const PetscInt p = points[l]; 1991d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 1992d42890abSMatthew G. Knepley 1993d42890abSMatthew G. Knepley if (cval != defVal) { 1994d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 1995d42890abSMatthew G. Knepley if (val == defVal) { 1996d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 199748a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 1998d42890abSMatthew G. Knepley } 1999d42890abSMatthew G. Knepley } 2000d42890abSMatthew G. Knepley } 2001d42890abSMatthew G. Knepley /* Read out shared roots */ 2002d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2003d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2004d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2005d42890abSMatthew G. Knepley if (degree[r]) { 2006d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 2007d42890abSMatthew G. Knepley 2008d42890abSMatthew G. Knepley if (cval != defVal) { 2009d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2010d42890abSMatthew G. Knepley if (val == defVal) { 2011d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 201248a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 2013d42890abSMatthew G. Knepley } 2014d42890abSMatthew G. Knepley } 2015d42890abSMatthew G. Knepley } 2016d42890abSMatthew G. Knepley } 20173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2018d42890abSMatthew G. Knepley } 2019d42890abSMatthew G. Knepley 2020d42890abSMatthew G. Knepley /*@ 2021d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 2022d42890abSMatthew G. Knepley 202320f4b53cSBarry Smith Collective 2024d42890abSMatthew G. Knepley 2025d42890abSMatthew G. Knepley Input Parameters: 202620f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 202720f4b53cSBarry Smith - sf - The `PetscSF` describing parallel layout of the label points 2028d42890abSMatthew G. Knepley 2029d42890abSMatthew G. Knepley Level: intermediate 2030d42890abSMatthew G. Knepley 203120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 2032d42890abSMatthew G. Knepley @*/ 2033d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 2034d71ae5a4SJacob Faibussowitsch { 2035d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 2036d42890abSMatthew G. Knepley PetscMPIInt size; 2037d42890abSMatthew G. Knepley 2038d42890abSMatthew G. Knepley PetscFunctionBegin; 20399f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2040d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 2041d42890abSMatthew G. Knepley if (size > 1) { 2042d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2043d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 2044d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 2045d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 2046d42890abSMatthew G. Knepley } 20473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2048d42890abSMatthew G. Knepley } 2049d42890abSMatthew G. Knepley 2050d42890abSMatthew G. Knepley /*@ 2051d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 2052d42890abSMatthew G. Knepley 205320f4b53cSBarry Smith Collective 2054d42890abSMatthew G. Knepley 2055d42890abSMatthew G. Knepley Input Parameters: 205620f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 205760225df5SJacob Faibussowitsch - pointSF - The `PetscSF` describing parallel layout of the label points 2058d42890abSMatthew G. Knepley 2059d42890abSMatthew G. Knepley Level: intermediate 2060d42890abSMatthew G. Knepley 206120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 2062d42890abSMatthew G. Knepley @*/ 2063d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 2064d71ae5a4SJacob Faibussowitsch { 2065d42890abSMatthew G. Knepley PetscFunctionBegin; 20669f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2067d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 2068d42890abSMatthew G. Knepley label->propArray = NULL; 20693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2070d42890abSMatthew G. Knepley } 2071d42890abSMatthew G. Knepley 2072d42890abSMatthew G. Knepley /*@C 2073d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 2074d42890abSMatthew G. Knepley 207520f4b53cSBarry Smith Collective 2076d42890abSMatthew G. Knepley 2077d42890abSMatthew G. Knepley Input Parameters: 207820f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 2079a4e35b19SJacob Faibussowitsch . pointSF - The `PetscSF` describing parallel layout of the label points 208020f4b53cSBarry Smith . markPoint - An optional callback that is called when a point is marked, or `NULL` 208120f4b53cSBarry Smith - ctx - An optional user context for the callback, or `NULL` 2082d42890abSMatthew G. Knepley 208320f4b53cSBarry Smith Calling sequence of `markPoint`: 208420f4b53cSBarry Smith + label - The `DMLabel` 2085d42890abSMatthew G. Knepley . p - The point being marked 2086a4e35b19SJacob Faibussowitsch . val - The label value for `p` 2087d42890abSMatthew G. Knepley - ctx - An optional user context 2088d42890abSMatthew G. Knepley 2089d42890abSMatthew G. Knepley Level: intermediate 2090d42890abSMatthew G. Knepley 209120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2092d42890abSMatthew G. Knepley @*/ 2093a4e35b19SJacob Faibussowitsch PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel label, PetscInt p, PetscInt val, void *ctx), void *ctx) 2094d71ae5a4SJacob Faibussowitsch { 2095c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2096d42890abSMatthew G. Knepley PetscMPIInt size; 2097d42890abSMatthew G. Knepley 2098d42890abSMatthew G. Knepley PetscFunctionBegin; 20999f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2100d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 2101c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2102c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2103d42890abSMatthew G. Knepley /* Communicate marked edges 2104d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2105d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2106d42890abSMatthew G. Knepley 2107d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2108d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2109d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2110d42890abSMatthew G. Knepley 2111d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2112d42890abSMatthew 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 2113d42890abSMatthew G. Knepley edge to the queue. 2114d42890abSMatthew G. Knepley */ 2115d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2116d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2117d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2118d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2119d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2120d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2121d42890abSMatthew G. Knepley } 21223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2123d42890abSMatthew G. Knepley } 2124d42890abSMatthew G. Knepley 212584f0b6dfSMatthew G. Knepley /*@ 212620f4b53cSBarry Smith DMLabelConvertToSection - Make a `PetscSection`/`IS` pair that encodes the label 212784f0b6dfSMatthew G. Knepley 212820f4b53cSBarry Smith Not Collective 21295b5e7992SMatthew G. Knepley 213084f0b6dfSMatthew G. Knepley Input Parameter: 213120f4b53cSBarry Smith . label - the `DMLabel` 213284f0b6dfSMatthew G. Knepley 213384f0b6dfSMatthew G. Knepley Output Parameters: 213484f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 213520f4b53cSBarry Smith - is - An `IS` containing all the label points 213684f0b6dfSMatthew G. Knepley 213784f0b6dfSMatthew G. Knepley Level: developer 213884f0b6dfSMatthew G. Knepley 213920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 214084f0b6dfSMatthew G. Knepley @*/ 2141d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2142d71ae5a4SJacob Faibussowitsch { 2143c58f1c22SToby Isaac IS vIS; 2144c58f1c22SToby Isaac const PetscInt *values; 2145c58f1c22SToby Isaac PetscInt *points; 2146c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2147c58f1c22SToby Isaac 2148c58f1c22SToby Isaac PetscFunctionBegin; 2149d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 21509566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 21519566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 21529566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 21539371c9d4SSatish Balay if (nV) { 21549371c9d4SSatish Balay vS = values[0]; 21559371c9d4SSatish Balay vE = values[0] + 1; 21569371c9d4SSatish Balay } 2157c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2158c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2159c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2160c58f1c22SToby Isaac } 21619566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 21629566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2163c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2164c58f1c22SToby Isaac PetscInt n; 2165c58f1c22SToby Isaac 21669566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 21679566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2168c58f1c22SToby Isaac } 21699566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 21709566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 21719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2172c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2173c58f1c22SToby Isaac IS is; 2174c58f1c22SToby Isaac const PetscInt *spoints; 2175c58f1c22SToby Isaac PetscInt dof, off, p; 2176c58f1c22SToby Isaac 21779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 21789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 21799566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 21809566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2181c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 21829566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 21839566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2184c58f1c22SToby Isaac } 21859566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 21869566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 21879566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 21883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2189c58f1c22SToby Isaac } 2190c58f1c22SToby Isaac 21919f6c5813SMatthew G. Knepley /*@C 21929f6c5813SMatthew G. Knepley DMLabelRegister - Adds a new label component implementation 21939f6c5813SMatthew G. Knepley 21949f6c5813SMatthew G. Knepley Not Collective 21959f6c5813SMatthew G. Knepley 21969f6c5813SMatthew G. Knepley Input Parameters: 21979f6c5813SMatthew G. Knepley + name - The name of a new user-defined creation routine 21989f6c5813SMatthew G. Knepley - create_func - The creation routine itself 21999f6c5813SMatthew G. Knepley 22009f6c5813SMatthew G. Knepley Notes: 22019f6c5813SMatthew G. Knepley `DMLabelRegister()` may be called multiple times to add several user-defined labels 22029f6c5813SMatthew G. Knepley 220360225df5SJacob Faibussowitsch Example Usage: 22049f6c5813SMatthew G. Knepley .vb 22059f6c5813SMatthew G. Knepley DMLabelRegister("my_label", MyLabelCreate); 22069f6c5813SMatthew G. Knepley .ve 22079f6c5813SMatthew G. Knepley 22089f6c5813SMatthew G. Knepley Then, your label type can be chosen with the procedural interface via 22099f6c5813SMatthew G. Knepley .vb 22109f6c5813SMatthew G. Knepley DMLabelCreate(MPI_Comm, DMLabel *); 22119f6c5813SMatthew G. Knepley DMLabelSetType(DMLabel, "my_label"); 22129f6c5813SMatthew G. Knepley .ve 22139f6c5813SMatthew G. Knepley or at runtime via the option 22149f6c5813SMatthew G. Knepley .vb 22159f6c5813SMatthew G. Knepley -dm_label_type my_label 22169f6c5813SMatthew G. Knepley .ve 22179f6c5813SMatthew G. Knepley 22189f6c5813SMatthew G. Knepley Level: advanced 22199f6c5813SMatthew G. Knepley 222060225df5SJacob Faibussowitsch .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelRegisterAll()`, `DMLabelRegisterDestroy()` 22219f6c5813SMatthew G. Knepley @*/ 22229f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegister(const char name[], PetscErrorCode (*create_func)(DMLabel)) 22239f6c5813SMatthew G. Knepley { 22249f6c5813SMatthew G. Knepley PetscFunctionBegin; 22259f6c5813SMatthew G. Knepley PetscCall(DMInitializePackage()); 22269f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListAdd(&DMLabelList, name, create_func)); 22273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22289f6c5813SMatthew G. Knepley } 22299f6c5813SMatthew G. Knepley 22309f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel); 22319f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel); 22329f6c5813SMatthew G. Knepley 22339f6c5813SMatthew G. Knepley /*@C 22349f6c5813SMatthew G. Knepley DMLabelRegisterAll - Registers all of the `DMLabel` implementations in the `DM` package. 22359f6c5813SMatthew G. Knepley 22369f6c5813SMatthew G. Knepley Not Collective 22379f6c5813SMatthew G. Knepley 22389f6c5813SMatthew G. Knepley Level: advanced 22399f6c5813SMatthew G. Knepley 224020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMRegisterAll()`, `DMLabelRegisterDestroy()` 22419f6c5813SMatthew G. Knepley @*/ 22429f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterAll(void) 22439f6c5813SMatthew G. Knepley { 22449f6c5813SMatthew G. Knepley PetscFunctionBegin; 22453ba16761SJacob Faibussowitsch if (DMLabelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 22469f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_TRUE; 22479f6c5813SMatthew G. Knepley 22489f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELCONCRETE, DMLabelCreate_Concrete)); 22499f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELEPHEMERAL, DMLabelCreate_Ephemeral)); 22503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22519f6c5813SMatthew G. Knepley } 22529f6c5813SMatthew G. Knepley 22539f6c5813SMatthew G. Knepley /*@C 22549f6c5813SMatthew G. Knepley DMLabelRegisterDestroy - This function destroys the `DMLabel` registry. It is called from `PetscFinalize()`. 22559f6c5813SMatthew G. Knepley 22569f6c5813SMatthew G. Knepley Level: developer 22579f6c5813SMatthew G. Knepley 225820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscInitialize()` 22599f6c5813SMatthew G. Knepley @*/ 22609f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterDestroy(void) 22619f6c5813SMatthew G. Knepley { 22629f6c5813SMatthew G. Knepley PetscFunctionBegin; 22639f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMLabelList)); 22649f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_FALSE; 22653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22669f6c5813SMatthew G. Knepley } 22679f6c5813SMatthew G. Knepley 22689f6c5813SMatthew G. Knepley /*@C 22699f6c5813SMatthew G. Knepley DMLabelSetType - Sets the particular implementation for a label. 22709f6c5813SMatthew G. Knepley 227120f4b53cSBarry Smith Collective 22729f6c5813SMatthew G. Knepley 22739f6c5813SMatthew G. Knepley Input Parameters: 22749f6c5813SMatthew G. Knepley + label - The label 22759f6c5813SMatthew G. Knepley - method - The name of the label type 22769f6c5813SMatthew G. Knepley 22779f6c5813SMatthew G. Knepley Options Database Key: 227820f4b53cSBarry Smith . -dm_label_type <type> - Sets the label type; use -help for a list of available types or see `DMLabelType` 22799f6c5813SMatthew G. Knepley 22809f6c5813SMatthew G. Knepley Level: intermediate 22819f6c5813SMatthew G. Knepley 228220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetType()`, `DMLabelCreate()` 22839f6c5813SMatthew G. Knepley @*/ 22849f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetType(DMLabel label, DMLabelType method) 22859f6c5813SMatthew G. Knepley { 22869f6c5813SMatthew G. Knepley PetscErrorCode (*r)(DMLabel); 22879f6c5813SMatthew G. Knepley PetscBool match; 22889f6c5813SMatthew G. Knepley 22899f6c5813SMatthew G. Knepley PetscFunctionBegin; 22909f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 22919f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)label, method, &match)); 22923ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 22939f6c5813SMatthew G. Knepley 22949f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 22959f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListFind(DMLabelList, method, &r)); 22969f6c5813SMatthew G. Knepley PetscCheck(r, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMLabel type: %s", method); 22979f6c5813SMatthew G. Knepley 22989f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, destroy); 22999f6c5813SMatthew G. Knepley PetscCall(PetscMemzero(label->ops, sizeof(*label->ops))); 23009f6c5813SMatthew G. Knepley PetscCall(PetscObjectChangeTypeName((PetscObject)label, method)); 23019f6c5813SMatthew G. Knepley PetscCall((*r)(label)); 23023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23039f6c5813SMatthew G. Knepley } 23049f6c5813SMatthew G. Knepley 23059f6c5813SMatthew G. Knepley /*@C 23069f6c5813SMatthew G. Knepley DMLabelGetType - Gets the type name (as a string) from the label. 23079f6c5813SMatthew G. Knepley 23089f6c5813SMatthew G. Knepley Not Collective 23099f6c5813SMatthew G. Knepley 23109f6c5813SMatthew G. Knepley Input Parameter: 231120f4b53cSBarry Smith . label - The `DMLabel` 23129f6c5813SMatthew G. Knepley 23139f6c5813SMatthew G. Knepley Output Parameter: 231420f4b53cSBarry Smith . type - The `DMLabel` type name 23159f6c5813SMatthew G. Knepley 23169f6c5813SMatthew G. Knepley Level: intermediate 23179f6c5813SMatthew G. Knepley 231820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetType()`, `DMLabelCreate()` 23199f6c5813SMatthew G. Knepley @*/ 23209f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetType(DMLabel label, DMLabelType *type) 23219f6c5813SMatthew G. Knepley { 23229f6c5813SMatthew G. Knepley PetscFunctionBegin; 23239f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23244f572ea9SToby Isaac PetscAssertPointer(type, 2); 23259f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23269f6c5813SMatthew G. Knepley *type = ((PetscObject)label)->type_name; 23273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23289f6c5813SMatthew G. Knepley } 23299f6c5813SMatthew G. Knepley 23309f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Concrete(DMLabel label) 23319f6c5813SMatthew G. Knepley { 23329f6c5813SMatthew G. Knepley PetscFunctionBegin; 23339f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Concrete; 23349f6c5813SMatthew G. Knepley label->ops->setup = NULL; 23359f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Concrete; 23369f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Concrete; 23373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23389f6c5813SMatthew G. Knepley } 23399f6c5813SMatthew G. Knepley 23409f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel label) 23419f6c5813SMatthew G. Knepley { 23429f6c5813SMatthew G. Knepley PetscFunctionBegin; 23439f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23449f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Concrete(label)); 23453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23469f6c5813SMatthew G. Knepley } 23479f6c5813SMatthew G. Knepley 234884f0b6dfSMatthew G. Knepley /*@ 2349c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 235020f4b53cSBarry Smith the local section and an `PetscSF` describing the section point overlap. 2351c58f1c22SToby Isaac 235220f4b53cSBarry Smith Collective 23535b5e7992SMatthew G. Knepley 2354c58f1c22SToby Isaac Input Parameters: 235520f4b53cSBarry Smith + s - The `PetscSection` for the local field layout 235620f4b53cSBarry Smith . sf - The `PetscSF` describing parallel layout of the section points 235720f4b53cSBarry Smith . includeConstraints - By default this is `PETSC_FALSE`, meaning that the global field vector will not possess constrained dofs 2358c58f1c22SToby Isaac . label - The label specifying the points 2359c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2360c58f1c22SToby Isaac 2361c58f1c22SToby Isaac Output Parameter: 236220f4b53cSBarry Smith . gsection - The `PetscSection` for the global field layout 2363c58f1c22SToby Isaac 2364c58f1c22SToby Isaac Level: developer 2365c58f1c22SToby Isaac 236620f4b53cSBarry Smith Note: 236720f4b53cSBarry Smith This gives negative sizes and offsets to points not owned by this process 236820f4b53cSBarry Smith 236920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionCreate()` 2370c58f1c22SToby Isaac @*/ 2371d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2372d71ae5a4SJacob Faibussowitsch { 2373c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2374c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2375c58f1c22SToby Isaac 2376c58f1c22SToby Isaac PetscFunctionBegin; 2377d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2378d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2379d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 23809566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 23819566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 23829566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 23839566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2384c58f1c22SToby Isaac if (nroots >= 0) { 238563a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 23869566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2387c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 23889566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2389c58f1c22SToby Isaac } else { 2390c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2391c58f1c22SToby Isaac } 2392c58f1c22SToby Isaac } 2393c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2394c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2395c58f1c22SToby Isaac PetscInt value; 2396c58f1c22SToby Isaac 23979566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2398c58f1c22SToby Isaac if (value != labelValue) continue; 23999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 24009566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 24019566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 24029566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2403c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2404c58f1c22SToby Isaac } 24059566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2406c58f1c22SToby Isaac if (nroots >= 0) { 24079566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24089566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2409c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24109371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24119371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 24129371c9d4SSatish Balay } 2413c58f1c22SToby Isaac } 2414c58f1c22SToby Isaac } 241535cb6cd3SPierre Jolivet /* Calculate new sizes, get process offset, and calculate point offsets */ 2416c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2417c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2418c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2419c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2420c58f1c22SToby Isaac } 24219566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2422c58f1c22SToby Isaac globalOff -= off; 2423c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2424c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2425c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2426c58f1c22SToby Isaac } 2427c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2428c58f1c22SToby Isaac if (nroots >= 0) { 24299566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24309566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2431c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24329371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24339371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 24349371c9d4SSatish Balay } 2435c58f1c22SToby Isaac } 2436c58f1c22SToby Isaac } 24379566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 24389566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 24393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2440c58f1c22SToby Isaac } 2441c58f1c22SToby Isaac 24429371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 24435fdea053SToby Isaac DMLabel label; 24445fdea053SToby Isaac PetscCopyMode *modes; 24455fdea053SToby Isaac PetscInt *sizes; 24465fdea053SToby Isaac const PetscInt ***perms; 24475fdea053SToby Isaac const PetscScalar ***rots; 24485fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 24495fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 24505fdea053SToby Isaac } PetscSectionSym_Label; 24515fdea053SToby Isaac 2452d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 2453d71ae5a4SJacob Faibussowitsch { 24545fdea053SToby Isaac PetscInt i, j; 24555fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24565fdea053SToby Isaac 24575fdea053SToby Isaac PetscFunctionBegin; 24585fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24595fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 24605fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 24619566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 24629566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 24635fdea053SToby Isaac } 24645fdea053SToby Isaac if (sl->perms[i]) { 24655fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 24665fdea053SToby Isaac 24679566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 24685fdea053SToby Isaac } 24695fdea053SToby Isaac if (sl->rots[i]) { 24705fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 24715fdea053SToby Isaac 24729566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 24735fdea053SToby Isaac } 24745fdea053SToby Isaac } 24755fdea053SToby Isaac } 24769566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 24779566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 24785fdea053SToby Isaac sl->numStrata = 0; 24793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24805fdea053SToby Isaac } 24815fdea053SToby Isaac 2482d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 2483d71ae5a4SJacob Faibussowitsch { 24845fdea053SToby Isaac PetscFunctionBegin; 24859566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 24869566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 24873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24885fdea053SToby Isaac } 24895fdea053SToby Isaac 2490d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 2491d71ae5a4SJacob Faibussowitsch { 24925fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24935fdea053SToby Isaac PetscBool isAscii; 24945fdea053SToby Isaac DMLabel label = sl->label; 2495d67d17b1SMatthew G. Knepley const char *name; 24965fdea053SToby Isaac 24975fdea053SToby Isaac PetscFunctionBegin; 24989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 24995fdea053SToby Isaac if (isAscii) { 25005fdea053SToby Isaac PetscInt i, j, k; 25015fdea053SToby Isaac PetscViewerFormat format; 25025fdea053SToby Isaac 25039566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25045fdea053SToby Isaac if (label) { 25059566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25065fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25089566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 25099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25105fdea053SToby Isaac } else { 25119566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 25129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 25135fdea053SToby Isaac } 25145fdea053SToby Isaac } else { 25159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 25165fdea053SToby Isaac } 25179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25185fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 25195fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 25205fdea053SToby Isaac 25215fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 252263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 25235fdea053SToby Isaac } else { 252463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 25259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 252663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 25275fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25295fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 25305fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 253163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 25325fdea053SToby Isaac } else { 25335fdea053SToby Isaac PetscInt tab; 25345fdea053SToby Isaac 253563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 25369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 25385fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 25399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 25409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 254163a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 25429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25445fdea053SToby Isaac } 25455fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 25469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 25479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 25485fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 254963a3b9bcSJacob 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]))); 25505fdea053SToby Isaac #else 255163a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 25525fdea053SToby Isaac #endif 25539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25555fdea053SToby Isaac } 25569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25575fdea053SToby Isaac } 25585fdea053SToby Isaac } 25599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25605fdea053SToby Isaac } 25619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25625fdea053SToby Isaac } 25635fdea053SToby Isaac } 25649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25655fdea053SToby Isaac } 25663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25675fdea053SToby Isaac } 25685fdea053SToby Isaac 25695fdea053SToby Isaac /*@ 25705fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 25715fdea053SToby Isaac 257220f4b53cSBarry Smith Logically 25735fdea053SToby Isaac 257460225df5SJacob Faibussowitsch Input Parameters: 25755fdea053SToby Isaac + sym - the section symmetries 257620f4b53cSBarry Smith - label - the `DMLabel` describing the types of points 25775fdea053SToby Isaac 25785fdea053SToby Isaac Level: developer: 25795fdea053SToby Isaac 258020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 25815fdea053SToby Isaac @*/ 2582d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 2583d71ae5a4SJacob Faibussowitsch { 25845fdea053SToby Isaac PetscSectionSym_Label *sl; 25855fdea053SToby Isaac 25865fdea053SToby Isaac PetscFunctionBegin; 25875fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 25885fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 25899566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 25905fdea053SToby Isaac if (label) { 25915fdea053SToby Isaac sl->label = label; 25929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 25939566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 25949566063dSJacob 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)); 25959566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 25969566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 25979566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 25989566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 25999566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 26005fdea053SToby Isaac } 26013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26025fdea053SToby Isaac } 26035fdea053SToby Isaac 26045fdea053SToby Isaac /*@C 2605b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2606b004864fSMatthew G. Knepley 260720f4b53cSBarry Smith Logically Collective 2608b004864fSMatthew G. Knepley 2609b004864fSMatthew G. Knepley Input Parameters: 2610b004864fSMatthew G. Knepley + sym - the section symmetries 2611b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2612b004864fSMatthew G. Knepley 2613b004864fSMatthew G. Knepley Output Parameters: 261420f4b53cSBarry Smith + size - the number of dofs for points in the `stratum` of the label 261520f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 261620f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a ppoint in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 261720f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 261820f4b53cSBarry 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 2619b004864fSMatthew G. Knepley 2620b004864fSMatthew G. Knepley Level: developer 2621b004864fSMatthew G. Knepley 262220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2623b004864fSMatthew G. Knepley @*/ 2624d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2625d71ae5a4SJacob Faibussowitsch { 2626b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2627b004864fSMatthew G. Knepley const char *name; 2628b004864fSMatthew G. Knepley PetscInt i; 2629b004864fSMatthew G. Knepley 2630b004864fSMatthew G. Knepley PetscFunctionBegin; 2631b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2632b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2633b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2634b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2635b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2636b004864fSMatthew G. Knepley 2637b004864fSMatthew G. Knepley if (stratum == value) break; 2638b004864fSMatthew G. Knepley } 26399566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2640b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 26419371c9d4SSatish Balay if (size) { 26424f572ea9SToby Isaac PetscAssertPointer(size, 3); 26439371c9d4SSatish Balay *size = sl->sizes[i]; 26449371c9d4SSatish Balay } 26459371c9d4SSatish Balay if (minOrient) { 26464f572ea9SToby Isaac PetscAssertPointer(minOrient, 4); 26479371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 26489371c9d4SSatish Balay } 26499371c9d4SSatish Balay if (maxOrient) { 26504f572ea9SToby Isaac PetscAssertPointer(maxOrient, 5); 26519371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 26529371c9d4SSatish Balay } 26539371c9d4SSatish Balay if (perms) { 26544f572ea9SToby Isaac PetscAssertPointer(perms, 6); 26558e3a54c0SPierre Jolivet *perms = PetscSafePointerPlusOffset(sl->perms[i], sl->minMaxOrients[i][0]); 26569371c9d4SSatish Balay } 26579371c9d4SSatish Balay if (rots) { 26584f572ea9SToby Isaac PetscAssertPointer(rots, 7); 26598e3a54c0SPierre Jolivet *rots = PetscSafePointerPlusOffset(sl->rots[i], sl->minMaxOrients[i][0]); 26609371c9d4SSatish Balay } 26613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2662b004864fSMatthew G. Knepley } 2663b004864fSMatthew G. Knepley 2664b004864fSMatthew G. Knepley /*@C 26655fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 26665fdea053SToby Isaac 266720f4b53cSBarry Smith Logically 26685fdea053SToby Isaac 26695fdea053SToby Isaac Input Parameters: 26705b5e7992SMatthew G. Knepley + sym - the section symmetries 26715fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 267220f4b53cSBarry Smith . size - the number of dofs for points in the `stratum` of the label 267320f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 267420f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a point in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 267520f4b53cSBarry Smith . mode - how `sym` should copy the `perms` and `rots` arrays 267620f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 267720f4b53cSBarry 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 26785fdea053SToby Isaac 26795fdea053SToby Isaac Level: developer 26805fdea053SToby Isaac 268120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 26825fdea053SToby Isaac @*/ 2683d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 2684d71ae5a4SJacob Faibussowitsch { 26855fdea053SToby Isaac PetscSectionSym_Label *sl; 2686d67d17b1SMatthew G. Knepley const char *name; 2687d67d17b1SMatthew G. Knepley PetscInt i, j, k; 26885fdea053SToby Isaac 26895fdea053SToby Isaac PetscFunctionBegin; 26905fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 26915fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2692b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 26935fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 26945fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 26955fdea053SToby Isaac 26965fdea053SToby Isaac if (stratum == value) break; 26975fdea053SToby Isaac } 26989566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 269963a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 27005fdea053SToby Isaac sl->sizes[i] = size; 27015fdea053SToby Isaac sl->modes[i] = mode; 27025fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 27035fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 27045fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 27055fdea053SToby Isaac if (perms) { 27065fdea053SToby Isaac PetscInt **ownPerms; 27075fdea053SToby Isaac 27089566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 27095fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27105fdea053SToby Isaac if (perms[j]) { 27119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2712ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 27135fdea053SToby Isaac } 27145fdea053SToby Isaac } 27155fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 27165fdea053SToby Isaac } 27175fdea053SToby Isaac if (rots) { 27185fdea053SToby Isaac PetscScalar **ownRots; 27195fdea053SToby Isaac 27209566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 27215fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27225fdea053SToby Isaac if (rots[j]) { 27239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2724ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 27255fdea053SToby Isaac } 27265fdea053SToby Isaac } 27275fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 27285fdea053SToby Isaac } 27295fdea053SToby Isaac } else { 27308e3a54c0SPierre Jolivet sl->perms[i] = PetscSafePointerPlusOffset(perms, -minOrient); 27318e3a54c0SPierre Jolivet sl->rots[i] = PetscSafePointerPlusOffset(rots, -minOrient); 27325fdea053SToby Isaac } 27333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27345fdea053SToby Isaac } 27355fdea053SToby Isaac 2736d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 2737d71ae5a4SJacob Faibussowitsch { 27385fdea053SToby Isaac PetscInt i, j, numStrata; 27395fdea053SToby Isaac PetscSectionSym_Label *sl; 27405fdea053SToby Isaac DMLabel label; 27415fdea053SToby Isaac 27425fdea053SToby Isaac PetscFunctionBegin; 27435fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 27445fdea053SToby Isaac numStrata = sl->numStrata; 27455fdea053SToby Isaac label = sl->label; 27465fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 27475fdea053SToby Isaac PetscInt point = points[2 * i]; 27485fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 27495fdea053SToby Isaac 27505fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 27515fdea053SToby Isaac if (label->validIS[j]) { 27525fdea053SToby Isaac PetscInt k; 27535fdea053SToby Isaac 27549566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j], point, &k)); 27555fdea053SToby Isaac if (k >= 0) break; 27565fdea053SToby Isaac } else { 27575fdea053SToby Isaac PetscBool has; 27585fdea053SToby Isaac 27599566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 27605fdea053SToby Isaac if (has) break; 27615fdea053SToby Isaac } 27625fdea053SToby Isaac } 27639371c9d4SSatish 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], 27649371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2765ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2766ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 27675fdea053SToby Isaac } 27683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27695fdea053SToby Isaac } 27705fdea053SToby Isaac 2771d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2772d71ae5a4SJacob Faibussowitsch { 2773b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2774b004864fSMatthew G. Knepley IS valIS; 2775b004864fSMatthew G. Knepley const PetscInt *values; 2776b004864fSMatthew G. Knepley PetscInt Nv, v; 2777b004864fSMatthew G. Knepley 2778b004864fSMatthew G. Knepley PetscFunctionBegin; 27799566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 27809566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 27819566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2782b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2783b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2784b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2785b004864fSMatthew G. Knepley const PetscInt **perms; 2786b004864fSMatthew G. Knepley const PetscScalar **rots; 2787b004864fSMatthew G. Knepley 27889566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 27899566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2790b004864fSMatthew G. Knepley } 27919566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 27923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2793b004864fSMatthew G. Knepley } 2794b004864fSMatthew G. Knepley 2795d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2796d71ae5a4SJacob Faibussowitsch { 2797b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2798b004864fSMatthew G. Knepley DMLabel dlabel; 2799b004864fSMatthew G. Knepley 2800b004864fSMatthew G. Knepley PetscFunctionBegin; 28019566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 28029566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 28039566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 28049566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 28053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2806b004864fSMatthew G. Knepley } 2807b004864fSMatthew G. Knepley 2808d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 2809d71ae5a4SJacob Faibussowitsch { 28105fdea053SToby Isaac PetscSectionSym_Label *sl; 28115fdea053SToby Isaac 28125fdea053SToby Isaac PetscFunctionBegin; 28134dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 28145fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2815b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2816b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 28175fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 28185fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 28195fdea053SToby Isaac sym->data = (void *)sl; 28203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28215fdea053SToby Isaac } 28225fdea053SToby Isaac 28235fdea053SToby Isaac /*@ 28245fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 28255fdea053SToby Isaac 28265fdea053SToby Isaac Collective 28275fdea053SToby Isaac 28285fdea053SToby Isaac Input Parameters: 28295fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 28305fdea053SToby Isaac - label - the label defining the strata 28315fdea053SToby Isaac 28322fe279fdSBarry Smith Output Parameter: 28335fdea053SToby Isaac . sym - the section symmetries 28345fdea053SToby Isaac 28355fdea053SToby Isaac Level: developer 28365fdea053SToby Isaac 283720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 28385fdea053SToby Isaac @*/ 2839d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 2840d71ae5a4SJacob Faibussowitsch { 28415fdea053SToby Isaac PetscFunctionBegin; 28429566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 28439566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 28449566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 28459566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 28463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28475fdea053SToby Isaac } 2848