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)); 175f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 176ad8374ffSToby Isaac } 177ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 179c58f1c22SToby Isaac } 180c58f1c22SToby Isaac 181d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelMakeAllInvalid_Internal(DMLabel label) 182d71ae5a4SJacob Faibussowitsch { 183695799ffSMatthew G. Knepley PetscInt v; 184695799ffSMatthew G. Knepley 185695799ffSMatthew G. Knepley PetscFunctionBegin; 18648a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeInvalid_Private(label, v)); 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 188695799ffSMatthew G. Knepley } 189695799ffSMatthew G. Knepley 190b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 191b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 192b9907514SLisandro Dalcin #endif 193b9907514SLisandro Dalcin 1949f6c5813SMatthew G. Knepley PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 195d71ae5a4SJacob Faibussowitsch { 1960c3c4a36SLisandro Dalcin PetscInt v; 1970e79e033SBarry Smith 1980c3c4a36SLisandro Dalcin PetscFunctionBegin; 1990e79e033SBarry Smith *index = -1; 2009f6c5813SMatthew G. Knepley if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD || label->readonly) { 201b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2029371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2039371c9d4SSatish Balay *index = v; 2049371c9d4SSatish Balay break; 2059371c9d4SSatish Balay } 206b9907514SLisandro Dalcin } else { 2079566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index)); 2080e79e033SBarry Smith } 2099f6c5813SMatthew G. Knepley if (PetscDefined(USE_DEBUG) && !label->readonly) { /* Check strata hash map consistency */ 21090e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 2119566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len)); 21208401ef6SPierre Jolivet PetscCheck(len == label->numStrata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 21390e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 2149566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc)); 21590e9b2aeSLisandro Dalcin } else { 21690e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 2179371c9d4SSatish Balay if (label->stratumValues[v] == value) { 2189371c9d4SSatish Balay loc = v; 2199371c9d4SSatish Balay break; 2209371c9d4SSatish Balay } 22190e9b2aeSLisandro Dalcin } 22208401ef6SPierre Jolivet PetscCheck(loc == *index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 22390e9b2aeSLisandro Dalcin } 2243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2250c3c4a36SLisandro Dalcin } 2260c3c4a36SLisandro Dalcin 227d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 228d71ae5a4SJacob Faibussowitsch { 229b9907514SLisandro Dalcin PetscInt v; 230b9907514SLisandro Dalcin PetscInt *tmpV; 231b9907514SLisandro Dalcin PetscInt *tmpS; 232b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 233b9907514SLisandro Dalcin IS *tmpP, is; 234c58f1c22SToby Isaac PetscBool *tmpB; 235b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 236c58f1c22SToby Isaac 237c58f1c22SToby Isaac PetscFunctionBegin; 238b9907514SLisandro Dalcin v = label->numStrata; 239b9907514SLisandro Dalcin tmpV = label->stratumValues; 240b9907514SLisandro Dalcin tmpS = label->stratumSizes; 241b9907514SLisandro Dalcin tmpH = label->ht; 242b9907514SLisandro Dalcin tmpP = label->points; 243b9907514SLisandro Dalcin tmpB = label->validIS; 2448e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2458e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2468e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2478e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2488e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2498e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2509566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpV), &tmpV)); 2519566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpS), &tmpS)); 2529f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpH), &tmpH)); 2539f6c5813SMatthew G. Knepley PetscCall(PetscCalloc((v + 1) * sizeof(*tmpP), &tmpP)); 2549566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpB), &tmpB)); 2559566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v)); 2569566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v)); 2579566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v)); 2589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v)); 2599566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v)); 2609566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV)); 2619566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS)); 2629566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH)); 2639566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP)); 2649566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB)); 2658e1f8cf0SLisandro Dalcin } 266b9907514SLisandro Dalcin label->numStrata = v + 1; 267c58f1c22SToby Isaac label->stratumValues = tmpV; 268c58f1c22SToby Isaac label->stratumSizes = tmpS; 269c58f1c22SToby Isaac label->ht = tmpH; 270c58f1c22SToby Isaac label->points = tmpP; 271ad8374ffSToby Isaac label->validIS = tmpB; 2729566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 2739566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 2749566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v)); 275b9907514SLisandro Dalcin tmpV[v] = value; 276b9907514SLisandro Dalcin tmpS[v] = 0; 277b9907514SLisandro Dalcin tmpH[v] = ht; 278b9907514SLisandro Dalcin tmpP[v] = is; 279b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 2809566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 2810c3c4a36SLisandro Dalcin *index = v; 2823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2830c3c4a36SLisandro Dalcin } 2840c3c4a36SLisandro Dalcin 285d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 286d71ae5a4SJacob Faibussowitsch { 287b9907514SLisandro Dalcin PetscFunctionBegin; 2889566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index)); 2899566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index)); 2903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 291b9907514SLisandro Dalcin } 292b9907514SLisandro Dalcin 2939f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) 294d71ae5a4SJacob Faibussowitsch { 2959e63cc69SVaclav Hapla PetscFunctionBegin; 2969e63cc69SVaclav Hapla *size = 0; 2973ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 2989f6c5813SMatthew G. Knepley if (label->readonly || label->validIS[v]) { 2999e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 3009e63cc69SVaclav Hapla } else { 3019566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size)); 3029e63cc69SVaclav Hapla } 3033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3049e63cc69SVaclav Hapla } 3059e63cc69SVaclav Hapla 306b9907514SLisandro Dalcin /*@ 30720f4b53cSBarry Smith DMLabelAddStratum - Adds a new stratum value in a `DMLabel` 308b9907514SLisandro Dalcin 309d8d19677SJose E. Roman Input Parameters: 31020f4b53cSBarry Smith + label - The `DMLabel` 311b9907514SLisandro Dalcin - value - The stratum value 312b9907514SLisandro Dalcin 313b9907514SLisandro Dalcin Level: beginner 314b9907514SLisandro Dalcin 31520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 316b9907514SLisandro Dalcin @*/ 317d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 318d71ae5a4SJacob Faibussowitsch { 3190c3c4a36SLisandro Dalcin PetscInt v; 3200c3c4a36SLisandro Dalcin 3210c3c4a36SLisandro Dalcin PetscFunctionBegin; 322d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3239f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3249566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 3253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 326b9907514SLisandro Dalcin } 327b9907514SLisandro Dalcin 328b9907514SLisandro Dalcin /*@ 32920f4b53cSBarry Smith DMLabelAddStrata - Adds new stratum values in a `DMLabel` 330b9907514SLisandro Dalcin 33120f4b53cSBarry Smith Not Collective 3325b5e7992SMatthew G. Knepley 333d8d19677SJose E. Roman Input Parameters: 33420f4b53cSBarry Smith + label - The `DMLabel` 335b9907514SLisandro Dalcin . numStrata - The number of stratum values 336b9907514SLisandro Dalcin - stratumValues - The stratum values 337b9907514SLisandro Dalcin 338b9907514SLisandro Dalcin Level: beginner 339b9907514SLisandro Dalcin 34020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 341b9907514SLisandro Dalcin @*/ 342d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 343d71ae5a4SJacob Faibussowitsch { 344b9907514SLisandro Dalcin PetscInt *values, v; 345b9907514SLisandro Dalcin 346b9907514SLisandro Dalcin PetscFunctionBegin; 347b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 3484f572ea9SToby Isaac if (numStrata) PetscAssertPointer(stratumValues, 3); 3499f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 3509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &values)); 3519566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(values, stratumValues, numStrata)); 3529566063dSJacob Faibussowitsch PetscCall(PetscSortRemoveDupsInt(&numStrata, values)); 353b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 354b9907514SLisandro Dalcin PetscInt *tmpV; 355b9907514SLisandro Dalcin PetscInt *tmpS; 356b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 357b9907514SLisandro Dalcin IS *tmpP, is; 358b9907514SLisandro Dalcin PetscBool *tmpB; 359b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 360b9907514SLisandro Dalcin 3619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpV)); 3629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpS)); 3639f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpH)); 3649f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(numStrata, &tmpP)); 3659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpB)); 366b9907514SLisandro Dalcin label->numStrata = numStrata; 367b9907514SLisandro Dalcin label->stratumValues = tmpV; 368b9907514SLisandro Dalcin label->stratumSizes = tmpS; 369b9907514SLisandro Dalcin label->ht = tmpH; 370b9907514SLisandro Dalcin label->points = tmpP; 371b9907514SLisandro Dalcin label->validIS = tmpB; 372b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 3739566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 3749566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 3759566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, values[v], v)); 376b9907514SLisandro Dalcin tmpV[v] = values[v]; 377b9907514SLisandro Dalcin tmpS[v] = 0; 378b9907514SLisandro Dalcin tmpH[v] = ht; 379b9907514SLisandro Dalcin tmpP[v] = is; 380b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 381b9907514SLisandro Dalcin } 3829566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 383b9907514SLisandro Dalcin } else { 38448a46eb9SPierre Jolivet for (v = 0; v < numStrata; ++v) PetscCall(DMLabelAddStratum(label, values[v])); 385b9907514SLisandro Dalcin } 3869566063dSJacob Faibussowitsch PetscCall(PetscFree(values)); 3873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 388b9907514SLisandro Dalcin } 389b9907514SLisandro Dalcin 390b9907514SLisandro Dalcin /*@ 39120f4b53cSBarry Smith DMLabelAddStrataIS - Adds new stratum values in a `DMLabel` 392b9907514SLisandro Dalcin 39320f4b53cSBarry Smith Not Collective 3945b5e7992SMatthew G. Knepley 395d8d19677SJose E. Roman Input Parameters: 39620f4b53cSBarry Smith + label - The `DMLabel` 397b9907514SLisandro Dalcin - valueIS - Index set with stratum values 398b9907514SLisandro Dalcin 399b9907514SLisandro Dalcin Level: beginner 400b9907514SLisandro Dalcin 40120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelDestroy()` 402b9907514SLisandro Dalcin @*/ 403d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 404d71ae5a4SJacob Faibussowitsch { 405b9907514SLisandro Dalcin PetscInt numStrata; 406b9907514SLisandro Dalcin const PetscInt *stratumValues; 407b9907514SLisandro Dalcin 408b9907514SLisandro Dalcin PetscFunctionBegin; 409b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 410b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 4119f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 4129566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata)); 4139566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues)); 4149566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues)); 4153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 416c58f1c22SToby Isaac } 417c58f1c22SToby Isaac 4189f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelView_Concrete_Ascii(DMLabel label, PetscViewer viewer) 419d71ae5a4SJacob Faibussowitsch { 420c58f1c22SToby Isaac PetscInt v; 421c58f1c22SToby Isaac PetscMPIInt rank; 422c58f1c22SToby Isaac 423c58f1c22SToby Isaac PetscFunctionBegin; 4249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 4259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 426c58f1c22SToby Isaac if (label) { 427d67d17b1SMatthew G. Knepley const char *name; 428d67d17b1SMatthew G. Knepley 4299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 4309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name)); 43163a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd)); 432c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 433c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 434ad8374ffSToby Isaac const PetscInt *points; 435c58f1c22SToby Isaac PetscInt p; 436c58f1c22SToby Isaac 4379566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 43848a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 4399566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 440c58f1c22SToby Isaac } 441c58f1c22SToby Isaac } 4429566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 4443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 445c58f1c22SToby Isaac } 446c58f1c22SToby Isaac 44766976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelView_Concrete(DMLabel label, PetscViewer viewer) 4489f6c5813SMatthew G. Knepley { 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); 532f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*label, DMLABEL_CLASSID, 1); 533f4f49eeaSPierre 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])); 548f4f49eeaSPierre 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 631*a3b724e8SBarry Smith Developer Note: 632*a3b724e8SBarry Smith Fortran stub cannot be generated automatically because `message` must be freed with `PetscFree()` 633*a3b724e8SBarry Smith 63420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 635609dae6eSVaclav Hapla @*/ 636d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 637d71ae5a4SJacob Faibussowitsch { 638609dae6eSVaclav Hapla const char *name0, *name1; 639609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 6405efe38ccSVaclav Hapla PetscBool eq; 6415efe38ccSVaclav Hapla PetscMPIInt rank; 642609dae6eSVaclav Hapla 643609dae6eSVaclav Hapla PetscFunctionBegin; 6445efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 6455efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6464f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 4); 6474f572ea9SToby Isaac if (message) PetscAssertPointer(message, 5); 6489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6499566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6509566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 651609dae6eSVaclav Hapla { 652609dae6eSVaclav Hapla PetscInt v0, v1; 653609dae6eSVaclav Hapla 6549566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6559566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6565efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 65748a46eb9SPierre 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)); 658712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6595efe38ccSVaclav Hapla if (!eq) goto finish; 660609dae6eSVaclav Hapla } 661609dae6eSVaclav Hapla { 662609dae6eSVaclav Hapla IS is0, is1; 663609dae6eSVaclav Hapla 6649566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6659566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6669566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6679566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6689566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 66948a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 670712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6715efe38ccSVaclav Hapla if (!eq) goto finish; 672609dae6eSVaclav Hapla } 673609dae6eSVaclav Hapla { 674609dae6eSVaclav Hapla PetscInt i, nValues; 675609dae6eSVaclav Hapla 6769566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 677609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 678609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 679609dae6eSVaclav Hapla PetscInt n; 680609dae6eSVaclav Hapla IS is0, is1; 681609dae6eSVaclav Hapla 6829566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 683609dae6eSVaclav Hapla if (!n) continue; 6849566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6859566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6869566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6879566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6889566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6895efe38ccSVaclav Hapla if (!eq) { 69063a3b9bcSJacob 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)); 6915efe38ccSVaclav Hapla break; 692609dae6eSVaclav Hapla } 693609dae6eSVaclav Hapla } 694712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 695609dae6eSVaclav Hapla } 696609dae6eSVaclav Hapla finish: 6975efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 698609dae6eSVaclav Hapla if (message) { 699609dae6eSVaclav Hapla *message = NULL; 70048a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 7015efe38ccSVaclav Hapla } else { 70248a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 7039566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 7045efe38ccSVaclav Hapla } 7055efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 7065efe38ccSVaclav Hapla if (equal) *equal = eq; 70763a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 7083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 709609dae6eSVaclav Hapla } 710609dae6eSVaclav Hapla 711c6a43d28SMatthew G. Knepley /*@ 712c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 713c6a43d28SMatthew G. Knepley 71420f4b53cSBarry Smith Not Collective 7155b5e7992SMatthew G. Knepley 716c6a43d28SMatthew G. Knepley Input Parameter: 71720f4b53cSBarry Smith . label - The `DMLabel` 718c6a43d28SMatthew G. Knepley 719c6a43d28SMatthew G. Knepley Level: intermediate 720c6a43d28SMatthew G. Knepley 72120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 722c6a43d28SMatthew G. Knepley @*/ 723d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label) 724d71ae5a4SJacob Faibussowitsch { 725c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 726c6a43d28SMatthew G. Knepley 727c6a43d28SMatthew G. Knepley PetscFunctionBegin; 728c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7299566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 730c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 731c6a43d28SMatthew G. Knepley const PetscInt *points; 732c6a43d28SMatthew G. Knepley PetscInt i; 733c6a43d28SMatthew G. Knepley 7349566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 735c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 736c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 737c6a43d28SMatthew G. Knepley 738c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 739c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 740c6a43d28SMatthew G. Knepley } 7419566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 742c6a43d28SMatthew G. Knepley } 743c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 744c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7459566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 7463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 747c6a43d28SMatthew G. Knepley } 748c6a43d28SMatthew G. Knepley 749c6a43d28SMatthew G. Knepley /*@ 750c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 751c6a43d28SMatthew G. Knepley 75220f4b53cSBarry Smith Not Collective 7535b5e7992SMatthew G. Knepley 754c6a43d28SMatthew G. Knepley Input Parameters: 75520f4b53cSBarry Smith + label - The `DMLabel` 756c6a43d28SMatthew G. Knepley . pStart - The smallest point 757c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 758c6a43d28SMatthew G. Knepley 759c6a43d28SMatthew G. Knepley Level: intermediate 760c6a43d28SMatthew G. Knepley 76120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 762c6a43d28SMatthew G. Knepley @*/ 763d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 764d71ae5a4SJacob Faibussowitsch { 765c58f1c22SToby Isaac PetscInt v; 766c58f1c22SToby Isaac 767c58f1c22SToby Isaac PetscFunctionBegin; 768d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7699566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7709566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 771c58f1c22SToby Isaac label->pStart = pStart; 772c58f1c22SToby Isaac label->pEnd = pEnd; 773c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7749566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 775c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 7769f6c5813SMatthew G. Knepley IS pointIS; 777ad8374ffSToby Isaac const PetscInt *points; 778c58f1c22SToby Isaac PetscInt i; 779c58f1c22SToby Isaac 7809f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 7819f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points)); 782c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 783ad8374ffSToby Isaac const PetscInt point = points[i]; 784c58f1c22SToby Isaac 7859f6c5813SMatthew 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); 7869566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 787c58f1c22SToby Isaac } 7889566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 7899f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 790c58f1c22SToby Isaac } 7913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 792c58f1c22SToby Isaac } 793c58f1c22SToby Isaac 794c6a43d28SMatthew G. Knepley /*@ 795c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 796c6a43d28SMatthew G. Knepley 79720f4b53cSBarry Smith Not Collective 7985b5e7992SMatthew G. Knepley 799c6a43d28SMatthew G. Knepley Input Parameter: 80020f4b53cSBarry Smith . label - the `DMLabel` 801c6a43d28SMatthew G. Knepley 802c6a43d28SMatthew G. Knepley Level: intermediate 803c6a43d28SMatthew G. Knepley 80420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 805c6a43d28SMatthew G. Knepley @*/ 806d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label) 807d71ae5a4SJacob Faibussowitsch { 808c58f1c22SToby Isaac PetscFunctionBegin; 809d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 810c58f1c22SToby Isaac label->pStart = -1; 811c58f1c22SToby Isaac label->pEnd = -1; 8129566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 8133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 814c58f1c22SToby Isaac } 815c58f1c22SToby Isaac 816c58f1c22SToby Isaac /*@ 817c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 818c6a43d28SMatthew G. Knepley 81920f4b53cSBarry Smith Not Collective 8205b5e7992SMatthew G. Knepley 821c6a43d28SMatthew G. Knepley Input Parameter: 82220f4b53cSBarry Smith . label - the `DMLabel` 823c6a43d28SMatthew G. Knepley 824c6a43d28SMatthew G. Knepley Output Parameters: 825c6a43d28SMatthew G. Knepley + pStart - The smallest point 826c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 827c6a43d28SMatthew G. Knepley 828c6a43d28SMatthew G. Knepley Level: intermediate 829c6a43d28SMatthew G. Knepley 83020f4b53cSBarry Smith Note: 83120f4b53cSBarry Smith This will compute an index for the label if one does not exist. 83220f4b53cSBarry Smith 83320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 834c6a43d28SMatthew G. Knepley @*/ 835d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 836d71ae5a4SJacob Faibussowitsch { 837c6a43d28SMatthew G. Knepley PetscFunctionBegin; 838c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8399566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 840c6a43d28SMatthew G. Knepley if (pStart) { 8414f572ea9SToby Isaac PetscAssertPointer(pStart, 2); 842c6a43d28SMatthew G. Knepley *pStart = label->pStart; 843c6a43d28SMatthew G. Knepley } 844c6a43d28SMatthew G. Knepley if (pEnd) { 8454f572ea9SToby Isaac PetscAssertPointer(pEnd, 3); 846c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 847c6a43d28SMatthew G. Knepley } 8483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 849c6a43d28SMatthew G. Knepley } 850c6a43d28SMatthew G. Knepley 851c6a43d28SMatthew G. Knepley /*@ 852c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 853c58f1c22SToby Isaac 85420f4b53cSBarry Smith Not Collective 8555b5e7992SMatthew G. Knepley 856c58f1c22SToby Isaac Input Parameters: 85720f4b53cSBarry Smith + label - the `DMLabel` 858c58f1c22SToby Isaac - value - the value 859c58f1c22SToby Isaac 860c58f1c22SToby Isaac Output Parameter: 861c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 862c58f1c22SToby Isaac 863c58f1c22SToby Isaac Level: developer 864c58f1c22SToby Isaac 86520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 866c58f1c22SToby Isaac @*/ 867d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 868d71ae5a4SJacob Faibussowitsch { 869c58f1c22SToby Isaac PetscInt v; 870c58f1c22SToby Isaac 871c58f1c22SToby Isaac PetscFunctionBegin; 872d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8734f572ea9SToby Isaac PetscAssertPointer(contains, 3); 8749566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8750c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 8763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 877c58f1c22SToby Isaac } 878c58f1c22SToby Isaac 879c58f1c22SToby Isaac /*@ 880c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 881c58f1c22SToby Isaac 88220f4b53cSBarry Smith Not Collective 8835b5e7992SMatthew G. Knepley 884c58f1c22SToby Isaac Input Parameters: 88520f4b53cSBarry Smith + label - the `DMLabel` 886c58f1c22SToby Isaac - point - the point 887c58f1c22SToby Isaac 888c58f1c22SToby Isaac Output Parameter: 889c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 890c58f1c22SToby Isaac 891c58f1c22SToby Isaac Level: developer 892c58f1c22SToby Isaac 89320f4b53cSBarry Smith Note: 89420f4b53cSBarry Smith The user must call `DMLabelCreateIndex()` before this function. 89520f4b53cSBarry Smith 89620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 897c58f1c22SToby Isaac @*/ 898d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 899d71ae5a4SJacob Faibussowitsch { 900c58f1c22SToby Isaac PetscFunctionBeginHot; 901d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9024f572ea9SToby Isaac PetscAssertPointer(contains, 3); 9039566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 90476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 90528b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 90663a3b9bcSJacob 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); 90776bd3646SJed Brown } 908c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 9093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 910c58f1c22SToby Isaac } 911c58f1c22SToby Isaac 912c58f1c22SToby Isaac /*@ 913c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 914c58f1c22SToby Isaac 91520f4b53cSBarry Smith Not Collective 9165b5e7992SMatthew G. Knepley 917c58f1c22SToby Isaac Input Parameters: 91820f4b53cSBarry Smith + label - the `DMLabel` 919c58f1c22SToby Isaac . value - the stratum value 920c58f1c22SToby Isaac - point - the point 921c58f1c22SToby Isaac 922c58f1c22SToby Isaac Output Parameter: 923c58f1c22SToby Isaac . contains - true if the stratum contains the point 924c58f1c22SToby Isaac 925c58f1c22SToby Isaac Level: intermediate 926c58f1c22SToby Isaac 92720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 928c58f1c22SToby Isaac @*/ 929d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 930d71ae5a4SJacob Faibussowitsch { 9310c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 932d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9334f572ea9SToby Isaac PetscAssertPointer(contains, 4); 934cffad2c9SToby Isaac if (value == label->defaultValue) { 935cffad2c9SToby Isaac PetscInt pointVal; 9360c3c4a36SLisandro Dalcin 937cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 938cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 939cffad2c9SToby Isaac } else { 940cffad2c9SToby Isaac PetscInt v; 941cffad2c9SToby Isaac 942cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 943cffad2c9SToby Isaac if (v >= 0) { 9449f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 9459f6c5813SMatthew G. Knepley IS is; 946c58f1c22SToby Isaac PetscInt i; 947c58f1c22SToby Isaac 9489f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 9499f6c5813SMatthew G. Knepley PetscCall(ISLocate(is, point, &i)); 9509f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 951cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 952c58f1c22SToby Isaac } else { 953cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 954cffad2c9SToby Isaac } 955cffad2c9SToby Isaac } else { // value is not present 956cffad2c9SToby Isaac *contains = PETSC_FALSE; 957cffad2c9SToby Isaac } 958c58f1c22SToby Isaac } 9593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 960c58f1c22SToby Isaac } 961c58f1c22SToby Isaac 96284f0b6dfSMatthew G. Knepley /*@ 96320f4b53cSBarry Smith DMLabelGetDefaultValue - Get the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9645aa44df4SToby Isaac When a label is created, it is initialized to -1. 9655aa44df4SToby Isaac 96620f4b53cSBarry Smith Not Collective 9675b5e7992SMatthew G. Knepley 96860225df5SJacob Faibussowitsch Input Parameter: 96920f4b53cSBarry Smith . label - a `DMLabel` object 9705aa44df4SToby Isaac 97160225df5SJacob Faibussowitsch Output Parameter: 9725aa44df4SToby Isaac . defaultValue - the default value 9735aa44df4SToby Isaac 9745aa44df4SToby Isaac Level: beginner 9755aa44df4SToby Isaac 97620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 97784f0b6dfSMatthew G. Knepley @*/ 978d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 979d71ae5a4SJacob Faibussowitsch { 9805aa44df4SToby Isaac PetscFunctionBegin; 981d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9825aa44df4SToby Isaac *defaultValue = label->defaultValue; 9833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9845aa44df4SToby Isaac } 9855aa44df4SToby Isaac 98684f0b6dfSMatthew G. Knepley /*@ 98720f4b53cSBarry Smith DMLabelSetDefaultValue - Set the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9885aa44df4SToby Isaac When a label is created, it is initialized to -1. 9895aa44df4SToby Isaac 99020f4b53cSBarry Smith Not Collective 9915b5e7992SMatthew G. Knepley 99260225df5SJacob Faibussowitsch Input Parameter: 99320f4b53cSBarry Smith . label - a `DMLabel` object 9945aa44df4SToby Isaac 99560225df5SJacob Faibussowitsch Output Parameter: 9965aa44df4SToby Isaac . defaultValue - the default value 9975aa44df4SToby Isaac 9985aa44df4SToby Isaac Level: beginner 9995aa44df4SToby Isaac 100020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 100184f0b6dfSMatthew G. Knepley @*/ 1002d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 1003d71ae5a4SJacob Faibussowitsch { 10045aa44df4SToby Isaac PetscFunctionBegin; 1005d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10065aa44df4SToby Isaac label->defaultValue = defaultValue; 10073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10085aa44df4SToby Isaac } 10095aa44df4SToby Isaac 1010c58f1c22SToby Isaac /*@ 101120f4b53cSBarry 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 101220f4b53cSBarry Smith `DMLabelSetDefaultValue()`) 1013c58f1c22SToby Isaac 101420f4b53cSBarry Smith Not Collective 10155b5e7992SMatthew G. Knepley 1016c58f1c22SToby Isaac Input Parameters: 101720f4b53cSBarry Smith + label - the `DMLabel` 1018c58f1c22SToby Isaac - point - the point 1019c58f1c22SToby Isaac 1020c58f1c22SToby Isaac Output Parameter: 10218e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 1022c58f1c22SToby Isaac 1023c58f1c22SToby Isaac Level: intermediate 1024c58f1c22SToby Isaac 102520f4b53cSBarry Smith Note: 102620f4b53cSBarry Smith A label may assign multiple values to a point. No guarantees are made about which value is returned in that case. 102720f4b53cSBarry Smith Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum. 102820f4b53cSBarry Smith 102920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1030c58f1c22SToby Isaac @*/ 1031d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 1032d71ae5a4SJacob Faibussowitsch { 1033c58f1c22SToby Isaac PetscInt v; 1034c58f1c22SToby Isaac 10350c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 1036d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10374f572ea9SToby Isaac PetscAssertPointer(value, 3); 10385aa44df4SToby Isaac *value = label->defaultValue; 1039c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 10409f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 10419f6c5813SMatthew G. Knepley IS is; 1042c58f1c22SToby Isaac PetscInt i; 1043c58f1c22SToby Isaac 10449f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 10459566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 10469f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1047c58f1c22SToby Isaac if (i >= 0) { 1048c58f1c22SToby Isaac *value = label->stratumValues[v]; 1049c58f1c22SToby Isaac break; 1050c58f1c22SToby Isaac } 1051c58f1c22SToby Isaac } else { 1052c58f1c22SToby Isaac PetscBool has; 1053c58f1c22SToby Isaac 10549566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 1055c58f1c22SToby Isaac if (has) { 1056c58f1c22SToby Isaac *value = label->stratumValues[v]; 1057c58f1c22SToby Isaac break; 1058c58f1c22SToby Isaac } 1059c58f1c22SToby Isaac } 1060c58f1c22SToby Isaac } 10613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1062c58f1c22SToby Isaac } 1063c58f1c22SToby Isaac 1064c58f1c22SToby Isaac /*@ 106520f4b53cSBarry 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 106620f4b53cSBarry Smith be changed with `DMLabelSetDefaultValue()` to something different), then this function will do nothing. 1067c58f1c22SToby Isaac 106820f4b53cSBarry Smith Not Collective 10695b5e7992SMatthew G. Knepley 1070c58f1c22SToby Isaac Input Parameters: 107120f4b53cSBarry Smith + label - the `DMLabel` 1072c58f1c22SToby Isaac . point - the point 1073c58f1c22SToby Isaac - value - The point value 1074c58f1c22SToby Isaac 1075c58f1c22SToby Isaac Level: intermediate 1076c58f1c22SToby Isaac 107720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1078c58f1c22SToby Isaac @*/ 1079d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1080d71ae5a4SJacob Faibussowitsch { 1081c58f1c22SToby Isaac PetscInt v; 1082c58f1c22SToby Isaac 1083c58f1c22SToby Isaac PetscFunctionBegin; 1084d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10850c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10863ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 10879f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 10889566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1089c58f1c22SToby Isaac /* Set key */ 10909566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10919566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 10923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1093c58f1c22SToby Isaac } 1094c58f1c22SToby Isaac 1095c58f1c22SToby Isaac /*@ 1096c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1097c58f1c22SToby Isaac 109820f4b53cSBarry Smith Not Collective 10995b5e7992SMatthew G. Knepley 1100c58f1c22SToby Isaac Input Parameters: 110120f4b53cSBarry Smith + label - the `DMLabel` 1102c58f1c22SToby Isaac . point - the point 1103c58f1c22SToby Isaac - value - The point value 1104c58f1c22SToby Isaac 1105c58f1c22SToby Isaac Level: intermediate 1106c58f1c22SToby Isaac 110720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1108c58f1c22SToby Isaac @*/ 1109d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1110d71ae5a4SJacob Faibussowitsch { 1111ad8374ffSToby Isaac PetscInt v; 1112c58f1c22SToby Isaac 1113c58f1c22SToby Isaac PetscFunctionBegin; 1114d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11159f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 1116c58f1c22SToby Isaac /* Find label value */ 11179566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 11183ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 11190c3c4a36SLisandro Dalcin 1120eeed21e7SToby Isaac if (label->bt) { 112163a3b9bcSJacob 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); 11229566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1123eeed21e7SToby Isaac } 11240c3c4a36SLisandro Dalcin 11250c3c4a36SLisandro Dalcin /* Delete key */ 11269566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11279566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 11283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1129c58f1c22SToby Isaac } 1130c58f1c22SToby Isaac 1131c58f1c22SToby Isaac /*@ 113220f4b53cSBarry Smith DMLabelInsertIS - Set all points in the `IS` to a value 1133c58f1c22SToby Isaac 113420f4b53cSBarry Smith Not Collective 11355b5e7992SMatthew G. Knepley 1136c58f1c22SToby Isaac Input Parameters: 113720f4b53cSBarry Smith + label - the `DMLabel` 11382fe279fdSBarry Smith . is - the point `IS` 1139c58f1c22SToby Isaac - value - The point value 1140c58f1c22SToby Isaac 1141c58f1c22SToby Isaac Level: intermediate 1142c58f1c22SToby Isaac 114320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1144c58f1c22SToby Isaac @*/ 1145d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1146d71ae5a4SJacob Faibussowitsch { 11470c3c4a36SLisandro Dalcin PetscInt v, n, p; 1148c58f1c22SToby Isaac const PetscInt *points; 1149c58f1c22SToby Isaac 1150c58f1c22SToby Isaac PetscFunctionBegin; 1151d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1152c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 11530c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11543ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 11559f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 11569566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 11570c3c4a36SLisandro Dalcin /* Set keys */ 11589566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11599566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 11609566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 11619566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 11629566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 11633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1164c58f1c22SToby Isaac } 1165c58f1c22SToby Isaac 116684f0b6dfSMatthew G. Knepley /*@ 116720f4b53cSBarry Smith DMLabelGetNumValues - Get the number of values that the `DMLabel` takes 116884f0b6dfSMatthew G. Knepley 116920f4b53cSBarry Smith Not Collective 11705b5e7992SMatthew G. Knepley 117184f0b6dfSMatthew G. Knepley Input Parameter: 117220f4b53cSBarry Smith . label - the `DMLabel` 117384f0b6dfSMatthew G. Knepley 117401d2d390SJose E. Roman Output Parameter: 117584f0b6dfSMatthew G. Knepley . numValues - the number of values 117684f0b6dfSMatthew G. Knepley 117784f0b6dfSMatthew G. Knepley Level: intermediate 117884f0b6dfSMatthew G. Knepley 117920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 118084f0b6dfSMatthew G. Knepley @*/ 1181d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1182d71ae5a4SJacob Faibussowitsch { 1183c58f1c22SToby Isaac PetscFunctionBegin; 1184d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11854f572ea9SToby Isaac PetscAssertPointer(numValues, 2); 1186c58f1c22SToby Isaac *numValues = label->numStrata; 11873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1188c58f1c22SToby Isaac } 1189c58f1c22SToby Isaac 119084f0b6dfSMatthew G. Knepley /*@ 119120f4b53cSBarry Smith DMLabelGetValueIS - Get an `IS` of all values that the `DMlabel` takes 119284f0b6dfSMatthew G. Knepley 119320f4b53cSBarry Smith Not Collective 11945b5e7992SMatthew G. Knepley 119584f0b6dfSMatthew G. Knepley Input Parameter: 119620f4b53cSBarry Smith . label - the `DMLabel` 119784f0b6dfSMatthew G. Knepley 119801d2d390SJose E. Roman Output Parameter: 119960225df5SJacob Faibussowitsch . values - the value `IS` 120084f0b6dfSMatthew G. Knepley 120184f0b6dfSMatthew G. Knepley Level: intermediate 120284f0b6dfSMatthew G. Knepley 12031d04cbbeSVaclav Hapla Notes: 120420f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 120520f4b53cSBarry Smith Strata which are allocated but empty [`DMLabelGetStratumSize()` yields 0] are counted. 120620f4b53cSBarry Smith If you need to count only nonempty strata, use `DMLabelGetNonEmptyStratumValuesIS()`. 12071d04cbbeSVaclav Hapla 120820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 120984f0b6dfSMatthew G. Knepley @*/ 1210d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1211d71ae5a4SJacob Faibussowitsch { 1212c58f1c22SToby Isaac PetscFunctionBegin; 1213d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12144f572ea9SToby Isaac PetscAssertPointer(values, 2); 12159566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1217c58f1c22SToby Isaac } 1218c58f1c22SToby Isaac 121984f0b6dfSMatthew G. Knepley /*@ 122020f4b53cSBarry Smith DMLabelGetNonEmptyStratumValuesIS - Get an `IS` of all values that the `DMlabel` takes 12211d04cbbeSVaclav Hapla 122220f4b53cSBarry Smith Not Collective 12231d04cbbeSVaclav Hapla 12241d04cbbeSVaclav Hapla Input Parameter: 122520f4b53cSBarry Smith . label - the `DMLabel` 12261d04cbbeSVaclav Hapla 1227d5b43468SJose E. Roman Output Parameter: 122860225df5SJacob Faibussowitsch . values - the value `IS` 12291d04cbbeSVaclav Hapla 12301d04cbbeSVaclav Hapla Level: intermediate 12311d04cbbeSVaclav Hapla 12321d04cbbeSVaclav Hapla Notes: 123320f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 123420f4b53cSBarry Smith This is similar to `DMLabelGetValueIS()` but counts only nonempty strata. 12351d04cbbeSVaclav Hapla 123620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 12371d04cbbeSVaclav Hapla @*/ 1238d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 1239d71ae5a4SJacob Faibussowitsch { 12401d04cbbeSVaclav Hapla PetscInt i, j; 12411d04cbbeSVaclav Hapla PetscInt *valuesArr; 12421d04cbbeSVaclav Hapla 12431d04cbbeSVaclav Hapla PetscFunctionBegin; 12441d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12454f572ea9SToby Isaac PetscAssertPointer(values, 2); 12469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 12471d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 12481d04cbbeSVaclav Hapla PetscInt n; 12491d04cbbeSVaclav Hapla 12509566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 12511d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 12521d04cbbeSVaclav Hapla } 12531d04cbbeSVaclav Hapla if (j == label->numStrata) { 12549566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12551d04cbbeSVaclav Hapla } else { 12569566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 12571d04cbbeSVaclav Hapla } 12589566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 12593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12601d04cbbeSVaclav Hapla } 12611d04cbbeSVaclav Hapla 12621d04cbbeSVaclav Hapla /*@ 126320f4b53cSBarry Smith DMLabelGetValueIndex - Get the index of a given value in the list of values for the `DMlabel`, or -1 if it is not present 1264d123abd9SMatthew G. Knepley 126520f4b53cSBarry Smith Not Collective 1266d123abd9SMatthew G. Knepley 1267d123abd9SMatthew G. Knepley Input Parameters: 126820f4b53cSBarry Smith + label - the `DMLabel` 126997bb3fdcSJose E. Roman - value - the value 1270d123abd9SMatthew G. Knepley 127101d2d390SJose E. Roman Output Parameter: 1272d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1273d123abd9SMatthew G. Knepley 1274d123abd9SMatthew G. Knepley Level: intermediate 1275d123abd9SMatthew G. Knepley 127620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1277d123abd9SMatthew G. Knepley @*/ 1278d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1279d71ae5a4SJacob Faibussowitsch { 1280d123abd9SMatthew G. Knepley PetscInt v; 1281d123abd9SMatthew G. Knepley 1282d123abd9SMatthew G. Knepley PetscFunctionBegin; 1283d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12844f572ea9SToby Isaac PetscAssertPointer(index, 3); 1285d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 12869371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 12879371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1288d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1289d123abd9SMatthew G. Knepley else *index = v; 12903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1291d123abd9SMatthew G. Knepley } 1292d123abd9SMatthew G. Knepley 1293d123abd9SMatthew G. Knepley /*@ 129484f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 129584f0b6dfSMatthew G. Knepley 129620f4b53cSBarry Smith Not Collective 12975b5e7992SMatthew G. Knepley 129884f0b6dfSMatthew G. Knepley Input Parameters: 129920f4b53cSBarry Smith + label - the `DMLabel` 130084f0b6dfSMatthew G. Knepley - value - the stratum value 130184f0b6dfSMatthew G. Knepley 130201d2d390SJose E. Roman Output Parameter: 130384f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 130484f0b6dfSMatthew G. Knepley 130584f0b6dfSMatthew G. Knepley Level: intermediate 130684f0b6dfSMatthew G. Knepley 130720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 130884f0b6dfSMatthew G. Knepley @*/ 1309d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1310d71ae5a4SJacob Faibussowitsch { 1311fada774cSMatthew G. Knepley PetscInt v; 1312fada774cSMatthew G. Knepley 1313fada774cSMatthew G. Knepley PetscFunctionBegin; 1314d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13154f572ea9SToby Isaac PetscAssertPointer(exists, 3); 13169566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13170c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 13183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1319fada774cSMatthew G. Knepley } 1320fada774cSMatthew G. Knepley 132184f0b6dfSMatthew G. Knepley /*@ 132284f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 132384f0b6dfSMatthew G. Knepley 132420f4b53cSBarry Smith Not Collective 13255b5e7992SMatthew G. Knepley 132684f0b6dfSMatthew G. Knepley Input Parameters: 132720f4b53cSBarry Smith + label - the `DMLabel` 132884f0b6dfSMatthew G. Knepley - value - the stratum value 132984f0b6dfSMatthew G. Knepley 133001d2d390SJose E. Roman Output Parameter: 133184f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 133284f0b6dfSMatthew G. Knepley 133384f0b6dfSMatthew G. Knepley Level: intermediate 133484f0b6dfSMatthew G. Knepley 133520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 133684f0b6dfSMatthew G. Knepley @*/ 1337d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1338d71ae5a4SJacob Faibussowitsch { 1339c58f1c22SToby Isaac PetscInt v; 1340c58f1c22SToby Isaac 1341c58f1c22SToby Isaac PetscFunctionBegin; 1342d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13434f572ea9SToby Isaac PetscAssertPointer(size, 3); 13449566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13459566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 13463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1347c58f1c22SToby Isaac } 1348c58f1c22SToby Isaac 134984f0b6dfSMatthew G. Knepley /*@ 135084f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 135184f0b6dfSMatthew G. Knepley 135220f4b53cSBarry Smith Not Collective 13535b5e7992SMatthew G. Knepley 135484f0b6dfSMatthew G. Knepley Input Parameters: 135520f4b53cSBarry Smith + label - the `DMLabel` 135684f0b6dfSMatthew G. Knepley - value - the stratum value 135784f0b6dfSMatthew G. Knepley 135801d2d390SJose E. Roman Output Parameters: 135984f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 136084f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 136184f0b6dfSMatthew G. Knepley 136284f0b6dfSMatthew G. Knepley Level: intermediate 136384f0b6dfSMatthew G. Knepley 136420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 136584f0b6dfSMatthew G. Knepley @*/ 1366d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1367d71ae5a4SJacob Faibussowitsch { 13689f6c5813SMatthew G. Knepley IS is; 13690c3c4a36SLisandro Dalcin PetscInt v, min, max; 1370c58f1c22SToby Isaac 1371c58f1c22SToby Isaac PetscFunctionBegin; 1372d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13739371c9d4SSatish Balay if (start) { 13744f572ea9SToby Isaac PetscAssertPointer(start, 3); 13759371c9d4SSatish Balay *start = -1; 13769371c9d4SSatish Balay } 13779371c9d4SSatish Balay if (end) { 13784f572ea9SToby Isaac PetscAssertPointer(end, 4); 13799371c9d4SSatish Balay *end = -1; 13809371c9d4SSatish Balay } 13819566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13823ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 13839566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13843ba16761SJacob Faibussowitsch if (label->stratumSizes[v] <= 0) PetscFunctionReturn(PETSC_SUCCESS); 13859f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 13869f6c5813SMatthew G. Knepley PetscCall(ISGetMinMax(is, &min, &max)); 13879f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1388d6cb179aSToby Isaac if (start) *start = min; 1389d6cb179aSToby Isaac if (end) *end = max + 1; 13903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1391c58f1c22SToby Isaac } 1392c58f1c22SToby Isaac 139366976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelGetStratumIS_Concrete(DMLabel label, PetscInt v, IS *pointIS) 13949f6c5813SMatthew G. Knepley { 13959f6c5813SMatthew G. Knepley PetscFunctionBegin; 13969f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)label->points[v])); 13979f6c5813SMatthew G. Knepley *pointIS = label->points[v]; 13983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13999f6c5813SMatthew G. Knepley } 14009f6c5813SMatthew G. Knepley 140184f0b6dfSMatthew G. Knepley /*@ 140220f4b53cSBarry Smith DMLabelGetStratumIS - Get an `IS` with the stratum points 140384f0b6dfSMatthew G. Knepley 140420f4b53cSBarry Smith Not Collective 14055b5e7992SMatthew G. Knepley 140684f0b6dfSMatthew G. Knepley Input Parameters: 140720f4b53cSBarry Smith + label - the `DMLabel` 140884f0b6dfSMatthew G. Knepley - value - the stratum value 140984f0b6dfSMatthew G. Knepley 141001d2d390SJose E. Roman Output Parameter: 141184f0b6dfSMatthew G. Knepley . points - The stratum points 141284f0b6dfSMatthew G. Knepley 141384f0b6dfSMatthew G. Knepley Level: intermediate 141484f0b6dfSMatthew G. Knepley 1415593ce467SVaclav Hapla Notes: 141620f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 141720f4b53cSBarry Smith Returns `NULL` if the stratum is empty. 1418593ce467SVaclav Hapla 141920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 142084f0b6dfSMatthew G. Knepley @*/ 1421d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1422d71ae5a4SJacob Faibussowitsch { 1423c58f1c22SToby Isaac PetscInt v; 1424c58f1c22SToby Isaac 1425c58f1c22SToby Isaac PetscFunctionBegin; 1426d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14274f572ea9SToby Isaac PetscAssertPointer(points, 3); 1428c58f1c22SToby Isaac *points = NULL; 14299566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14303ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14319566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14329f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, points); 14333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1434c58f1c22SToby Isaac } 1435c58f1c22SToby Isaac 143684f0b6dfSMatthew G. Knepley /*@ 143720f4b53cSBarry Smith DMLabelSetStratumIS - Set the stratum points using an `IS` 143884f0b6dfSMatthew G. Knepley 143920f4b53cSBarry Smith Not Collective 14405b5e7992SMatthew G. Knepley 144184f0b6dfSMatthew G. Knepley Input Parameters: 144220f4b53cSBarry Smith + label - the `DMLabel` 144384f0b6dfSMatthew G. Knepley . value - the stratum value 144460225df5SJacob Faibussowitsch - is - The stratum points 144584f0b6dfSMatthew G. Knepley 144684f0b6dfSMatthew G. Knepley Level: intermediate 144784f0b6dfSMatthew G. Knepley 144820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 144984f0b6dfSMatthew G. Knepley @*/ 1450d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 1451d71ae5a4SJacob Faibussowitsch { 14520c3c4a36SLisandro Dalcin PetscInt v; 14534de306b1SToby Isaac 14544de306b1SToby Isaac PetscFunctionBegin; 1455d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1456d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 14579f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 14589566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 14593ba16761SJacob Faibussowitsch if (is == label->points[v]) PetscFunctionReturn(PETSC_SUCCESS); 14609566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 1461f4f49eeaSPierre Jolivet PetscCall(ISGetLocalSize(is, &label->stratumSizes[v])); 14629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 1463f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 14640c3c4a36SLisandro Dalcin label->points[v] = is; 14650c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 14669566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 14674de306b1SToby Isaac if (label->bt) { 14684de306b1SToby Isaac const PetscInt *points; 14694de306b1SToby Isaac PetscInt p; 14704de306b1SToby Isaac 14719566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 14724de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 14734de306b1SToby Isaac const PetscInt point = points[p]; 14744de306b1SToby Isaac 147563a3b9bcSJacob 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); 14769566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 14774de306b1SToby Isaac } 14784de306b1SToby Isaac } 14793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14804de306b1SToby Isaac } 14814de306b1SToby Isaac 148284f0b6dfSMatthew G. Knepley /*@ 148384f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 14844de306b1SToby Isaac 148520f4b53cSBarry Smith Not Collective 14865b5e7992SMatthew G. Knepley 148784f0b6dfSMatthew G. Knepley Input Parameters: 148820f4b53cSBarry Smith + label - the `DMLabel` 148984f0b6dfSMatthew G. Knepley - value - the stratum value 149084f0b6dfSMatthew G. Knepley 149184f0b6dfSMatthew G. Knepley Level: intermediate 149284f0b6dfSMatthew G. Knepley 149320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 149484f0b6dfSMatthew G. Knepley @*/ 1495d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1496d71ae5a4SJacob Faibussowitsch { 1497c58f1c22SToby Isaac PetscInt v; 1498c58f1c22SToby Isaac 1499c58f1c22SToby Isaac PetscFunctionBegin; 1500d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15019f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 15029566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15033ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15044de306b1SToby Isaac if (label->validIS[v]) { 15054de306b1SToby Isaac if (label->bt) { 1506c58f1c22SToby Isaac PetscInt i; 1507ad8374ffSToby Isaac const PetscInt *points; 1508c58f1c22SToby Isaac 15099566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1510c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1511ad8374ffSToby Isaac const PetscInt point = points[i]; 1512c58f1c22SToby Isaac 151363a3b9bcSJacob 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); 15149566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1515c58f1c22SToby Isaac } 15169566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1517c58f1c22SToby Isaac } 1518c58f1c22SToby Isaac label->stratumSizes[v] = 0; 15199566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 15209566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 15219566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 15229566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1523c58f1c22SToby Isaac } else { 15249566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1525c58f1c22SToby Isaac } 15263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1527c58f1c22SToby Isaac } 1528c58f1c22SToby Isaac 152984f0b6dfSMatthew G. Knepley /*@ 1530412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1531412e9a14SMatthew G. Knepley 153220f4b53cSBarry Smith Not Collective 1533412e9a14SMatthew G. Knepley 1534412e9a14SMatthew G. Knepley Input Parameters: 153520f4b53cSBarry Smith + label - The `DMLabel` 1536412e9a14SMatthew G. Knepley . value - The label value for all points 1537412e9a14SMatthew G. Knepley . pStart - The first point 1538412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1539412e9a14SMatthew G. Knepley 1540412e9a14SMatthew G. Knepley Level: intermediate 1541412e9a14SMatthew G. Knepley 154220f4b53cSBarry Smith Note: 154320f4b53cSBarry Smith The marks points are [`pStart`, `pEnd`), and only the bounds are stored. 154420f4b53cSBarry Smith 154520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1546412e9a14SMatthew G. Knepley @*/ 1547d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1548d71ae5a4SJacob Faibussowitsch { 1549412e9a14SMatthew G. Knepley IS pIS; 1550412e9a14SMatthew G. Knepley 1551412e9a14SMatthew G. Knepley PetscFunctionBegin; 15529566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 15539566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 15549566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 15553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1556412e9a14SMatthew G. Knepley } 1557412e9a14SMatthew G. Knepley 1558412e9a14SMatthew G. Knepley /*@ 1559d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1560d123abd9SMatthew G. Knepley 156120f4b53cSBarry Smith Not Collective 1562d123abd9SMatthew G. Knepley 1563d123abd9SMatthew G. Knepley Input Parameters: 156420f4b53cSBarry Smith + label - The `DMLabel` 1565d123abd9SMatthew G. Knepley . value - The label value 1566d123abd9SMatthew G. Knepley - p - A point with this value 1567d123abd9SMatthew G. Knepley 1568d123abd9SMatthew G. Knepley Output Parameter: 1569d123abd9SMatthew 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 1570d123abd9SMatthew G. Knepley 1571d123abd9SMatthew G. Knepley Level: intermediate 1572d123abd9SMatthew G. Knepley 157320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1574d123abd9SMatthew G. Knepley @*/ 1575d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1576d71ae5a4SJacob Faibussowitsch { 15779f6c5813SMatthew G. Knepley IS pointIS; 1578d123abd9SMatthew G. Knepley const PetscInt *indices; 1579d123abd9SMatthew G. Knepley PetscInt v; 1580d123abd9SMatthew G. Knepley 1581d123abd9SMatthew G. Knepley PetscFunctionBegin; 1582d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15834f572ea9SToby Isaac PetscAssertPointer(index, 4); 1584d123abd9SMatthew G. Knepley *index = -1; 15859566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15863ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15879566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 15889f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 15899f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &indices)); 15909566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 15919f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(pointIS, &indices)); 15929f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 15933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1594d123abd9SMatthew G. Knepley } 1595d123abd9SMatthew G. Knepley 1596d123abd9SMatthew G. Knepley /*@ 159720f4b53cSBarry Smith DMLabelFilter - Remove all points outside of [`start`, `end`) 159884f0b6dfSMatthew G. Knepley 159920f4b53cSBarry Smith Not Collective 16005b5e7992SMatthew G. Knepley 160184f0b6dfSMatthew G. Knepley Input Parameters: 160220f4b53cSBarry Smith + label - the `DMLabel` 160322cd2cdaSVaclav Hapla . start - the first point kept 160422cd2cdaSVaclav Hapla - end - one more than the last point kept 160584f0b6dfSMatthew G. Knepley 160684f0b6dfSMatthew G. Knepley Level: intermediate 160784f0b6dfSMatthew G. Knepley 160820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 160984f0b6dfSMatthew G. Knepley @*/ 1610d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1611d71ae5a4SJacob Faibussowitsch { 1612c58f1c22SToby Isaac PetscInt v; 1613c58f1c22SToby Isaac 1614c58f1c22SToby Isaac PetscFunctionBegin; 1615d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16169f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16179566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 16189566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16199f6c5813SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 16209f6c5813SMatthew G. Knepley PetscCall(ISGeneralFilter(label->points[v], start, end)); 16219f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(label->points[v], &label->stratumSizes[v])); 16229f6c5813SMatthew G. Knepley } 16239566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 16243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1625c58f1c22SToby Isaac } 1626c58f1c22SToby Isaac 162784f0b6dfSMatthew G. Knepley /*@ 162884f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 162984f0b6dfSMatthew G. Knepley 163020f4b53cSBarry Smith Not Collective 16315b5e7992SMatthew G. Knepley 163284f0b6dfSMatthew G. Knepley Input Parameters: 163320f4b53cSBarry Smith + label - the `DMLabel` 163484f0b6dfSMatthew G. Knepley - permutation - the point permutation 163584f0b6dfSMatthew G. Knepley 163684f0b6dfSMatthew G. Knepley Output Parameter: 163760225df5SJacob Faibussowitsch . labelNew - the new label containing the permuted points 163884f0b6dfSMatthew G. Knepley 163984f0b6dfSMatthew G. Knepley Level: intermediate 164084f0b6dfSMatthew G. Knepley 164120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 164284f0b6dfSMatthew G. Knepley @*/ 1643d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1644d71ae5a4SJacob Faibussowitsch { 1645c58f1c22SToby Isaac const PetscInt *perm; 1646c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1647c58f1c22SToby Isaac 1648c58f1c22SToby Isaac PetscFunctionBegin; 1649d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1650d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 16519f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16529566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16539566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 16549566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 16559566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 16569566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1657c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1658c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1659ad8374ffSToby Isaac const PetscInt *points; 1660ad8374ffSToby Isaac PetscInt *pointsNew; 1661c58f1c22SToby Isaac 16629566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 16639f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(size, &pointsNew)); 1664c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1665ad8374ffSToby Isaac const PetscInt point = points[q]; 1666c58f1c22SToby Isaac 166763a3b9bcSJacob 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); 1668ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1669c58f1c22SToby Isaac } 16709566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 16719566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 16729566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1673fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 16749566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 16759566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1676fa8e8ae5SToby Isaac } else { 16779566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1678fa8e8ae5SToby Isaac } 16799566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1680c58f1c22SToby Isaac } 16819566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1682c58f1c22SToby Isaac if (label->bt) { 16839566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 16849566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1685c58f1c22SToby Isaac } 16863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1687c58f1c22SToby Isaac } 1688c58f1c22SToby Isaac 168966976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 1690d71ae5a4SJacob Faibussowitsch { 169126c55118SMichael Lange MPI_Comm comm; 1692eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 169326c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 169426c55118SMichael Lange PetscSection rootSection; 169526c55118SMichael Lange PetscSF labelSF; 169626c55118SMichael Lange 169726c55118SMichael Lange PetscFunctionBegin; 16989566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 16999566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 170026c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 170126c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 17029566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 17039566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 17049566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 170526c55118SMichael Lange if (label) { 170626c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1707ad8374ffSToby Isaac const PetscInt *points; 1708ad8374ffSToby Isaac 17099566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 171048a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 17119566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 171226c55118SMichael Lange } 171326c55118SMichael Lange } 17149566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 171526c55118SMichael Lange /* Create a point-wise array of stratum values */ 17169566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 17179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 17189566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 171926c55118SMichael Lange if (label) { 172026c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1721ad8374ffSToby Isaac const PetscInt *points; 1722ad8374ffSToby Isaac 17239566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 172426c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1725ad8374ffSToby Isaac const PetscInt p = points[l]; 17269566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 172726c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 172826c55118SMichael Lange } 17299566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 173026c55118SMichael Lange } 173126c55118SMichael Lange } 173226c55118SMichael Lange /* Build SF that maps label points to remote processes */ 17339566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 17349566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 17359566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 17369566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 173726c55118SMichael Lange /* Send the strata for each point over the derived SF */ 17389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 17399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 17409566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 17419566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 174226c55118SMichael Lange /* Clean up */ 17439566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 17449566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 17459566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 17469566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 17473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 174826c55118SMichael Lange } 174926c55118SMichael Lange 175084f0b6dfSMatthew G. Knepley /*@ 175120f4b53cSBarry Smith DMLabelDistribute - Create a new label pushed forward over the `PetscSF` 175284f0b6dfSMatthew G. Knepley 175320f4b53cSBarry Smith Collective 17545b5e7992SMatthew G. Knepley 175584f0b6dfSMatthew G. Knepley Input Parameters: 175620f4b53cSBarry Smith + label - the `DMLabel` 175784f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 175884f0b6dfSMatthew G. Knepley 175984f0b6dfSMatthew G. Knepley Output Parameter: 176060225df5SJacob Faibussowitsch . labelNew - the new redistributed label 176184f0b6dfSMatthew G. Knepley 176284f0b6dfSMatthew G. Knepley Level: intermediate 176384f0b6dfSMatthew G. Knepley 176420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 176584f0b6dfSMatthew G. Knepley @*/ 1766d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1767d71ae5a4SJacob Faibussowitsch { 1768c58f1c22SToby Isaac MPI_Comm comm; 176926c55118SMichael Lange PetscSection leafSection; 177026c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 177126c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1772ad8374ffSToby Isaac PetscInt **points; 1773d67d17b1SMatthew G. Knepley const char *lname = NULL; 1774c58f1c22SToby Isaac char *name; 1775c58f1c22SToby Isaac PetscInt nameSize; 1776e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1777c58f1c22SToby Isaac size_t len = 0; 177826c55118SMichael Lange PetscMPIInt rank; 1779c58f1c22SToby Isaac 1780c58f1c22SToby Isaac PetscFunctionBegin; 1781d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1782f018e600SMatthew G. Knepley if (label) { 1783f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 17849f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 17859566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1786f018e600SMatthew G. Knepley } 17879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 17889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1789c58f1c22SToby Isaac /* Bcast name */ 1790dd400576SPatrick Sanan if (rank == 0) { 17919566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 17929566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1793d67d17b1SMatthew G. Knepley } 1794c58f1c22SToby Isaac nameSize = len; 17959566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 17969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 17979566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 17989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 17999566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 18009566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 180177d236dfSMichael Lange /* Bcast defaultValue */ 1802dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 18039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 180426c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 18059566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 18065cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 18079566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 18089566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 18099566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 18109566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 18119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1812ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 18139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 18145cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 18155cbdf6fcSMichael Lange offset = 0; 18169566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 18179566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 181848a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 18195cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1820231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 18219371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 18229371c9d4SSatish Balay leafStrata[p] = s; 18239371c9d4SSatish Balay break; 18249371c9d4SSatish Balay } 18255cbdf6fcSMichael Lange } 18265cbdf6fcSMichael Lange } 1827c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 18289566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 18299566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1830c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18329566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1833ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1834c58f1c22SToby Isaac } 18359566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 18369f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 18379f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &points)); 1838c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 18399566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 1840f4f49eeaSPierre Jolivet PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &points[s])); 1841c58f1c22SToby Isaac } 1842c58f1c22SToby Isaac /* Insert points into new strata */ 18439566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 18449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1845c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18469566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18479566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1848c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1849c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1850ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1851c58f1c22SToby Isaac } 1852c58f1c22SToby Isaac } 1853ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1854f4f49eeaSPierre Jolivet PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &points[s][0], PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 18559566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1856ad8374ffSToby Isaac } 18579566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 18589566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 18599566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 18609566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 18619566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 18623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1863c58f1c22SToby Isaac } 1864c58f1c22SToby Isaac 18657937d9ceSMichael Lange /*@ 18667937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 18677937d9ceSMichael Lange 186820f4b53cSBarry Smith Collective 18695b5e7992SMatthew G. Knepley 18707937d9ceSMichael Lange Input Parameters: 187120f4b53cSBarry Smith + label - the `DMLabel` 187220f4b53cSBarry Smith - sf - the `PetscSF` communication map 18737937d9ceSMichael Lange 18742fe279fdSBarry Smith Output Parameter: 187520f4b53cSBarry Smith . labelNew - the new `DMLabel` with localised leaf values 18767937d9ceSMichael Lange 18777937d9ceSMichael Lange Level: developer 18787937d9ceSMichael Lange 187920f4b53cSBarry Smith Note: 188020f4b53cSBarry Smith This is the inverse operation to `DMLabelDistribute()`. 18817937d9ceSMichael Lange 188220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 18837937d9ceSMichael Lange @*/ 1884d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 1885d71ae5a4SJacob Faibussowitsch { 18867937d9ceSMichael Lange MPI_Comm comm; 18877937d9ceSMichael Lange PetscSection rootSection; 18887937d9ceSMichael Lange PetscSF sfLabel; 18897937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 18907937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 18917937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 18927937d9ceSMichael Lange PetscInt *rootStrata; 1893d67d17b1SMatthew G. Knepley const char *lname; 18947937d9ceSMichael Lange char *name; 18957937d9ceSMichael Lange PetscInt nameSize; 18967937d9ceSMichael Lange size_t len = 0; 18979852e123SBarry Smith PetscMPIInt rank, size; 18987937d9ceSMichael Lange 18997937d9ceSMichael Lange PetscFunctionBegin; 1900d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1901d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 19029f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 19039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 19049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 19059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 19067937d9ceSMichael Lange /* Bcast name */ 1907dd400576SPatrick Sanan if (rank == 0) { 19089566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 19099566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1910d67d17b1SMatthew G. Knepley } 19117937d9ceSMichael Lange nameSize = len; 19129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 19139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 19149566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 19159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 19169566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 19179566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 19187937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 19197937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 19207937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 19219566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 19229566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1923dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 19247937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 19258212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 19268212dd46SStefano Zampini 19278212dd46SStefano Zampini leafPoints[ilp].index = ilp; 19288212dd46SStefano Zampini leafPoints[ilp].rank = rank; 19297937d9ceSMichael Lange } 19309566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 19319566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 19327937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 19339566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 19349566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 19359566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 19369566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 19379566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 19387937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 19399566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 19407937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 19417937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 19427937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 19439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 19449566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 19459566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 19467937d9ceSMichael Lange } 19477937d9ceSMichael Lange idx += rootDegree[p]; 19487937d9ceSMichael Lange } 19499566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 19509566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 19519566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 19529566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 19533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19547937d9ceSMichael Lange } 19557937d9ceSMichael Lange 1956d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1957d71ae5a4SJacob Faibussowitsch { 1958d42890abSMatthew G. Knepley const PetscInt *degree; 1959d42890abSMatthew G. Knepley const PetscInt *points; 1960d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1961d42890abSMatthew G. Knepley 1962d42890abSMatthew G. Knepley PetscFunctionBegin; 1963d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1964d42890abSMatthew G. Knepley /* Add in leaves */ 1965d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1966d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1967d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 1968d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 1969d42890abSMatthew G. Knepley } 1970d42890abSMatthew G. Knepley /* Add in shared roots */ 1971d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1972d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1973d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1974d42890abSMatthew G. Knepley if (degree[r]) { 1975d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1976d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 1977d42890abSMatthew G. Knepley } 1978d42890abSMatthew G. Knepley } 19793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1980d42890abSMatthew G. Knepley } 1981d42890abSMatthew G. Knepley 1982d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 1983d71ae5a4SJacob Faibussowitsch { 1984d42890abSMatthew G. Knepley const PetscInt *degree; 1985d42890abSMatthew G. Knepley const PetscInt *points; 1986d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1987d42890abSMatthew G. Knepley 1988d42890abSMatthew G. Knepley PetscFunctionBegin; 1989d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1990d42890abSMatthew G. Knepley /* Read out leaves */ 1991d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1992d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1993d42890abSMatthew G. Knepley const PetscInt p = points[l]; 1994d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 1995d42890abSMatthew G. Knepley 1996d42890abSMatthew G. Knepley if (cval != defVal) { 1997d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 1998d42890abSMatthew G. Knepley if (val == defVal) { 1999d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 200048a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 2001d42890abSMatthew G. Knepley } 2002d42890abSMatthew G. Knepley } 2003d42890abSMatthew G. Knepley } 2004d42890abSMatthew G. Knepley /* Read out shared roots */ 2005d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2006d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2007d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2008d42890abSMatthew G. Knepley if (degree[r]) { 2009d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 2010d42890abSMatthew G. Knepley 2011d42890abSMatthew G. Knepley if (cval != defVal) { 2012d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2013d42890abSMatthew G. Knepley if (val == defVal) { 2014d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 201548a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 2016d42890abSMatthew G. Knepley } 2017d42890abSMatthew G. Knepley } 2018d42890abSMatthew G. Knepley } 2019d42890abSMatthew G. Knepley } 20203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2021d42890abSMatthew G. Knepley } 2022d42890abSMatthew G. Knepley 2023d42890abSMatthew G. Knepley /*@ 2024d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 2025d42890abSMatthew G. Knepley 202620f4b53cSBarry Smith Collective 2027d42890abSMatthew G. Knepley 2028d42890abSMatthew G. Knepley Input Parameters: 202920f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 203020f4b53cSBarry Smith - sf - The `PetscSF` describing parallel layout of the label points 2031d42890abSMatthew G. Knepley 2032d42890abSMatthew G. Knepley Level: intermediate 2033d42890abSMatthew G. Knepley 203420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 2035d42890abSMatthew G. Knepley @*/ 2036d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 2037d71ae5a4SJacob Faibussowitsch { 2038d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 2039d42890abSMatthew G. Knepley PetscMPIInt size; 2040d42890abSMatthew G. Knepley 2041d42890abSMatthew G. Knepley PetscFunctionBegin; 20429f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2043d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 2044d42890abSMatthew G. Knepley if (size > 1) { 2045d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2046d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 2047d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 2048d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 2049d42890abSMatthew G. Knepley } 20503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2051d42890abSMatthew G. Knepley } 2052d42890abSMatthew G. Knepley 2053d42890abSMatthew G. Knepley /*@ 2054d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 2055d42890abSMatthew G. Knepley 205620f4b53cSBarry Smith Collective 2057d42890abSMatthew G. Knepley 2058d42890abSMatthew G. Knepley Input Parameters: 205920f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 206060225df5SJacob Faibussowitsch - pointSF - The `PetscSF` describing parallel layout of the label points 2061d42890abSMatthew G. Knepley 2062d42890abSMatthew G. Knepley Level: intermediate 2063d42890abSMatthew G. Knepley 206420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 2065d42890abSMatthew G. Knepley @*/ 2066d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 2067d71ae5a4SJacob Faibussowitsch { 2068d42890abSMatthew G. Knepley PetscFunctionBegin; 20699f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2070d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 2071d42890abSMatthew G. Knepley label->propArray = NULL; 20723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2073d42890abSMatthew G. Knepley } 2074d42890abSMatthew G. Knepley 2075d42890abSMatthew G. Knepley /*@C 2076d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 2077d42890abSMatthew G. Knepley 207820f4b53cSBarry Smith Collective 2079d42890abSMatthew G. Knepley 2080d42890abSMatthew G. Knepley Input Parameters: 208120f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 2082a4e35b19SJacob Faibussowitsch . pointSF - The `PetscSF` describing parallel layout of the label points 208320f4b53cSBarry Smith . markPoint - An optional callback that is called when a point is marked, or `NULL` 208420f4b53cSBarry Smith - ctx - An optional user context for the callback, or `NULL` 2085d42890abSMatthew G. Knepley 208620f4b53cSBarry Smith Calling sequence of `markPoint`: 208720f4b53cSBarry Smith + label - The `DMLabel` 2088d42890abSMatthew G. Knepley . p - The point being marked 2089a4e35b19SJacob Faibussowitsch . val - The label value for `p` 2090d42890abSMatthew G. Knepley - ctx - An optional user context 2091d42890abSMatthew G. Knepley 2092d42890abSMatthew G. Knepley Level: intermediate 2093d42890abSMatthew G. Knepley 209420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2095d42890abSMatthew G. Knepley @*/ 2096a4e35b19SJacob Faibussowitsch PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel label, PetscInt p, PetscInt val, void *ctx), void *ctx) 2097d71ae5a4SJacob Faibussowitsch { 2098c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2099d42890abSMatthew G. Knepley PetscMPIInt size; 2100d42890abSMatthew G. Knepley 2101d42890abSMatthew G. Knepley PetscFunctionBegin; 21029f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2103d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 2104c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2105c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2106d42890abSMatthew G. Knepley /* Communicate marked edges 2107d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2108d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2109d42890abSMatthew G. Knepley 2110d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2111d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2112d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2113d42890abSMatthew G. Knepley 2114d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2115d42890abSMatthew 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 2116d42890abSMatthew G. Knepley edge to the queue. 2117d42890abSMatthew G. Knepley */ 2118d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2119d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2120d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2121d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2122d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2123d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2124d42890abSMatthew G. Knepley } 21253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2126d42890abSMatthew G. Knepley } 2127d42890abSMatthew G. Knepley 212884f0b6dfSMatthew G. Knepley /*@ 212920f4b53cSBarry Smith DMLabelConvertToSection - Make a `PetscSection`/`IS` pair that encodes the label 213084f0b6dfSMatthew G. Knepley 213120f4b53cSBarry Smith Not Collective 21325b5e7992SMatthew G. Knepley 213384f0b6dfSMatthew G. Knepley Input Parameter: 213420f4b53cSBarry Smith . label - the `DMLabel` 213584f0b6dfSMatthew G. Knepley 213684f0b6dfSMatthew G. Knepley Output Parameters: 213784f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 213820f4b53cSBarry Smith - is - An `IS` containing all the label points 213984f0b6dfSMatthew G. Knepley 214084f0b6dfSMatthew G. Knepley Level: developer 214184f0b6dfSMatthew G. Knepley 214220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 214384f0b6dfSMatthew G. Knepley @*/ 2144d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2145d71ae5a4SJacob Faibussowitsch { 2146c58f1c22SToby Isaac IS vIS; 2147c58f1c22SToby Isaac const PetscInt *values; 2148c58f1c22SToby Isaac PetscInt *points; 2149c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2150c58f1c22SToby Isaac 2151c58f1c22SToby Isaac PetscFunctionBegin; 2152d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 21539566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 21549566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 21559566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 21569371c9d4SSatish Balay if (nV) { 21579371c9d4SSatish Balay vS = values[0]; 21589371c9d4SSatish Balay vE = values[0] + 1; 21599371c9d4SSatish Balay } 2160c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2161c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2162c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2163c58f1c22SToby Isaac } 21649566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 21659566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2166c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2167c58f1c22SToby Isaac PetscInt n; 2168c58f1c22SToby Isaac 21699566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 21709566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2171c58f1c22SToby Isaac } 21729566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 21739566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 21749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2175c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2176c58f1c22SToby Isaac IS is; 2177c58f1c22SToby Isaac const PetscInt *spoints; 2178c58f1c22SToby Isaac PetscInt dof, off, p; 2179c58f1c22SToby Isaac 21809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 21819566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 21829566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 21839566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2184c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 21859566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 21869566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2187c58f1c22SToby Isaac } 21889566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 21899566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 21909566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 21913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2192c58f1c22SToby Isaac } 2193c58f1c22SToby Isaac 21949f6c5813SMatthew G. Knepley /*@C 21959f6c5813SMatthew G. Knepley DMLabelRegister - Adds a new label component implementation 21969f6c5813SMatthew G. Knepley 21979f6c5813SMatthew G. Knepley Not Collective 21989f6c5813SMatthew G. Knepley 21999f6c5813SMatthew G. Knepley Input Parameters: 22009f6c5813SMatthew G. Knepley + name - The name of a new user-defined creation routine 22019f6c5813SMatthew G. Knepley - create_func - The creation routine itself 22029f6c5813SMatthew G. Knepley 22039f6c5813SMatthew G. Knepley Notes: 22049f6c5813SMatthew G. Knepley `DMLabelRegister()` may be called multiple times to add several user-defined labels 22059f6c5813SMatthew G. Knepley 220660225df5SJacob Faibussowitsch Example Usage: 22079f6c5813SMatthew G. Knepley .vb 22089f6c5813SMatthew G. Knepley DMLabelRegister("my_label", MyLabelCreate); 22099f6c5813SMatthew G. Knepley .ve 22109f6c5813SMatthew G. Knepley 22119f6c5813SMatthew G. Knepley Then, your label type can be chosen with the procedural interface via 22129f6c5813SMatthew G. Knepley .vb 22139f6c5813SMatthew G. Knepley DMLabelCreate(MPI_Comm, DMLabel *); 22149f6c5813SMatthew G. Knepley DMLabelSetType(DMLabel, "my_label"); 22159f6c5813SMatthew G. Knepley .ve 22169f6c5813SMatthew G. Knepley or at runtime via the option 22179f6c5813SMatthew G. Knepley .vb 22189f6c5813SMatthew G. Knepley -dm_label_type my_label 22199f6c5813SMatthew G. Knepley .ve 22209f6c5813SMatthew G. Knepley 22219f6c5813SMatthew G. Knepley Level: advanced 22229f6c5813SMatthew G. Knepley 222360225df5SJacob Faibussowitsch .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelRegisterAll()`, `DMLabelRegisterDestroy()` 22249f6c5813SMatthew G. Knepley @*/ 22259f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegister(const char name[], PetscErrorCode (*create_func)(DMLabel)) 22269f6c5813SMatthew G. Knepley { 22279f6c5813SMatthew G. Knepley PetscFunctionBegin; 22289f6c5813SMatthew G. Knepley PetscCall(DMInitializePackage()); 22299f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListAdd(&DMLabelList, name, create_func)); 22303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22319f6c5813SMatthew G. Knepley } 22329f6c5813SMatthew G. Knepley 22339f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel); 22349f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel); 22359f6c5813SMatthew G. Knepley 22369f6c5813SMatthew G. Knepley /*@C 22379f6c5813SMatthew G. Knepley DMLabelRegisterAll - Registers all of the `DMLabel` implementations in the `DM` package. 22389f6c5813SMatthew G. Knepley 22399f6c5813SMatthew G. Knepley Not Collective 22409f6c5813SMatthew G. Knepley 22419f6c5813SMatthew G. Knepley Level: advanced 22429f6c5813SMatthew G. Knepley 224320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMRegisterAll()`, `DMLabelRegisterDestroy()` 22449f6c5813SMatthew G. Knepley @*/ 22459f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterAll(void) 22469f6c5813SMatthew G. Knepley { 22479f6c5813SMatthew G. Knepley PetscFunctionBegin; 22483ba16761SJacob Faibussowitsch if (DMLabelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 22499f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_TRUE; 22509f6c5813SMatthew G. Knepley 22519f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELCONCRETE, DMLabelCreate_Concrete)); 22529f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELEPHEMERAL, DMLabelCreate_Ephemeral)); 22533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22549f6c5813SMatthew G. Knepley } 22559f6c5813SMatthew G. Knepley 22569f6c5813SMatthew G. Knepley /*@C 22579f6c5813SMatthew G. Knepley DMLabelRegisterDestroy - This function destroys the `DMLabel` registry. It is called from `PetscFinalize()`. 22589f6c5813SMatthew G. Knepley 22599f6c5813SMatthew G. Knepley Level: developer 22609f6c5813SMatthew G. Knepley 226120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscInitialize()` 22629f6c5813SMatthew G. Knepley @*/ 22639f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterDestroy(void) 22649f6c5813SMatthew G. Knepley { 22659f6c5813SMatthew G. Knepley PetscFunctionBegin; 22669f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMLabelList)); 22679f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_FALSE; 22683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22699f6c5813SMatthew G. Knepley } 22709f6c5813SMatthew G. Knepley 22719f6c5813SMatthew G. Knepley /*@C 22729f6c5813SMatthew G. Knepley DMLabelSetType - Sets the particular implementation for a label. 22739f6c5813SMatthew G. Knepley 227420f4b53cSBarry Smith Collective 22759f6c5813SMatthew G. Knepley 22769f6c5813SMatthew G. Knepley Input Parameters: 22779f6c5813SMatthew G. Knepley + label - The label 22789f6c5813SMatthew G. Knepley - method - The name of the label type 22799f6c5813SMatthew G. Knepley 22809f6c5813SMatthew G. Knepley Options Database Key: 228120f4b53cSBarry Smith . -dm_label_type <type> - Sets the label type; use -help for a list of available types or see `DMLabelType` 22829f6c5813SMatthew G. Knepley 22839f6c5813SMatthew G. Knepley Level: intermediate 22849f6c5813SMatthew G. Knepley 228520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetType()`, `DMLabelCreate()` 22869f6c5813SMatthew G. Knepley @*/ 22879f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetType(DMLabel label, DMLabelType method) 22889f6c5813SMatthew G. Knepley { 22899f6c5813SMatthew G. Knepley PetscErrorCode (*r)(DMLabel); 22909f6c5813SMatthew G. Knepley PetscBool match; 22919f6c5813SMatthew G. Knepley 22929f6c5813SMatthew G. Knepley PetscFunctionBegin; 22939f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 22949f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)label, method, &match)); 22953ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 22969f6c5813SMatthew G. Knepley 22979f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 22989f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListFind(DMLabelList, method, &r)); 22999f6c5813SMatthew G. Knepley PetscCheck(r, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMLabel type: %s", method); 23009f6c5813SMatthew G. Knepley 23019f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, destroy); 23029f6c5813SMatthew G. Knepley PetscCall(PetscMemzero(label->ops, sizeof(*label->ops))); 23039f6c5813SMatthew G. Knepley PetscCall(PetscObjectChangeTypeName((PetscObject)label, method)); 23049f6c5813SMatthew G. Knepley PetscCall((*r)(label)); 23053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23069f6c5813SMatthew G. Knepley } 23079f6c5813SMatthew G. Knepley 23089f6c5813SMatthew G. Knepley /*@C 23099f6c5813SMatthew G. Knepley DMLabelGetType - Gets the type name (as a string) from the label. 23109f6c5813SMatthew G. Knepley 23119f6c5813SMatthew G. Knepley Not Collective 23129f6c5813SMatthew G. Knepley 23139f6c5813SMatthew G. Knepley Input Parameter: 231420f4b53cSBarry Smith . label - The `DMLabel` 23159f6c5813SMatthew G. Knepley 23169f6c5813SMatthew G. Knepley Output Parameter: 231720f4b53cSBarry Smith . type - The `DMLabel` type name 23189f6c5813SMatthew G. Knepley 23199f6c5813SMatthew G. Knepley Level: intermediate 23209f6c5813SMatthew G. Knepley 232120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetType()`, `DMLabelCreate()` 23229f6c5813SMatthew G. Knepley @*/ 23239f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetType(DMLabel label, DMLabelType *type) 23249f6c5813SMatthew G. Knepley { 23259f6c5813SMatthew G. Knepley PetscFunctionBegin; 23269f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23274f572ea9SToby Isaac PetscAssertPointer(type, 2); 23289f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23299f6c5813SMatthew G. Knepley *type = ((PetscObject)label)->type_name; 23303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23319f6c5813SMatthew G. Knepley } 23329f6c5813SMatthew G. Knepley 23339f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Concrete(DMLabel label) 23349f6c5813SMatthew G. Knepley { 23359f6c5813SMatthew G. Knepley PetscFunctionBegin; 23369f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Concrete; 23379f6c5813SMatthew G. Knepley label->ops->setup = NULL; 23389f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Concrete; 23399f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Concrete; 23403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23419f6c5813SMatthew G. Knepley } 23429f6c5813SMatthew G. Knepley 23439f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel label) 23449f6c5813SMatthew G. Knepley { 23459f6c5813SMatthew G. Knepley PetscFunctionBegin; 23469f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23479f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Concrete(label)); 23483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23499f6c5813SMatthew G. Knepley } 23509f6c5813SMatthew G. Knepley 235184f0b6dfSMatthew G. Knepley /*@ 2352c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 235320f4b53cSBarry Smith the local section and an `PetscSF` describing the section point overlap. 2354c58f1c22SToby Isaac 235520f4b53cSBarry Smith Collective 23565b5e7992SMatthew G. Knepley 2357c58f1c22SToby Isaac Input Parameters: 235820f4b53cSBarry Smith + s - The `PetscSection` for the local field layout 235920f4b53cSBarry Smith . sf - The `PetscSF` describing parallel layout of the section points 236020f4b53cSBarry Smith . includeConstraints - By default this is `PETSC_FALSE`, meaning that the global field vector will not possess constrained dofs 2361c58f1c22SToby Isaac . label - The label specifying the points 2362c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2363c58f1c22SToby Isaac 2364c58f1c22SToby Isaac Output Parameter: 236520f4b53cSBarry Smith . gsection - The `PetscSection` for the global field layout 2366c58f1c22SToby Isaac 2367c58f1c22SToby Isaac Level: developer 2368c58f1c22SToby Isaac 236920f4b53cSBarry Smith Note: 237020f4b53cSBarry Smith This gives negative sizes and offsets to points not owned by this process 237120f4b53cSBarry Smith 237220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionCreate()` 2373c58f1c22SToby Isaac @*/ 2374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2375d71ae5a4SJacob Faibussowitsch { 2376c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2377c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2378c58f1c22SToby Isaac 2379c58f1c22SToby Isaac PetscFunctionBegin; 2380d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2381d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2382d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 23839566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 23849566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 23859566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 23869566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2387c58f1c22SToby Isaac if (nroots >= 0) { 238863a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 23899566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2390c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 23919566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2392c58f1c22SToby Isaac } else { 2393c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2394c58f1c22SToby Isaac } 2395c58f1c22SToby Isaac } 2396c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2397c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2398c58f1c22SToby Isaac PetscInt value; 2399c58f1c22SToby Isaac 24009566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2401c58f1c22SToby Isaac if (value != labelValue) continue; 24029566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 24039566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 24049566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 24059566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2406c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2407c58f1c22SToby Isaac } 24089566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2409c58f1c22SToby Isaac if (nroots >= 0) { 24109566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24119566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2412c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24139371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24149371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 24159371c9d4SSatish Balay } 2416c58f1c22SToby Isaac } 2417c58f1c22SToby Isaac } 241835cb6cd3SPierre Jolivet /* Calculate new sizes, get process offset, and calculate point offsets */ 2419c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2420c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2421c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2422c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2423c58f1c22SToby Isaac } 24249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2425c58f1c22SToby Isaac globalOff -= off; 2426c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2427c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2428c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2429c58f1c22SToby Isaac } 2430c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2431c58f1c22SToby Isaac if (nroots >= 0) { 24329566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24339566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2434c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24359371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24369371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 24379371c9d4SSatish Balay } 2438c58f1c22SToby Isaac } 2439c58f1c22SToby Isaac } 24409566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 24419566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 24423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2443c58f1c22SToby Isaac } 2444c58f1c22SToby Isaac 24459371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 24465fdea053SToby Isaac DMLabel label; 24475fdea053SToby Isaac PetscCopyMode *modes; 24485fdea053SToby Isaac PetscInt *sizes; 24495fdea053SToby Isaac const PetscInt ***perms; 24505fdea053SToby Isaac const PetscScalar ***rots; 24515fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 24525fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 24535fdea053SToby Isaac } PetscSectionSym_Label; 24545fdea053SToby Isaac 2455d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 2456d71ae5a4SJacob Faibussowitsch { 24575fdea053SToby Isaac PetscInt i, j; 24585fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24595fdea053SToby Isaac 24605fdea053SToby Isaac PetscFunctionBegin; 24615fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24625fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 24635fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 24649566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 24659566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 24665fdea053SToby Isaac } 24675fdea053SToby Isaac if (sl->perms[i]) { 24685fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 24695fdea053SToby Isaac 24709566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 24715fdea053SToby Isaac } 24725fdea053SToby Isaac if (sl->rots[i]) { 24735fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 24745fdea053SToby Isaac 24759566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 24765fdea053SToby Isaac } 24775fdea053SToby Isaac } 24785fdea053SToby Isaac } 24799566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 24809566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 24815fdea053SToby Isaac sl->numStrata = 0; 24823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24835fdea053SToby Isaac } 24845fdea053SToby Isaac 2485d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 2486d71ae5a4SJacob Faibussowitsch { 24875fdea053SToby Isaac PetscFunctionBegin; 24889566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 24899566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 24903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24915fdea053SToby Isaac } 24925fdea053SToby Isaac 2493d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 2494d71ae5a4SJacob Faibussowitsch { 24955fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24965fdea053SToby Isaac PetscBool isAscii; 24975fdea053SToby Isaac DMLabel label = sl->label; 2498d67d17b1SMatthew G. Knepley const char *name; 24995fdea053SToby Isaac 25005fdea053SToby Isaac PetscFunctionBegin; 25019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 25025fdea053SToby Isaac if (isAscii) { 25035fdea053SToby Isaac PetscInt i, j, k; 25045fdea053SToby Isaac PetscViewerFormat format; 25055fdea053SToby Isaac 25069566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25075fdea053SToby Isaac if (label) { 25089566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25095fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25119566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 25129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25135fdea053SToby Isaac } else { 25149566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 25159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 25165fdea053SToby Isaac } 25175fdea053SToby Isaac } else { 25189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 25195fdea053SToby Isaac } 25209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25215fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 25225fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 25235fdea053SToby Isaac 25245fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 252563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 25265fdea053SToby Isaac } else { 252763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 25289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 252963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 25305fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25325fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 25335fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 253463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 25355fdea053SToby Isaac } else { 25365fdea053SToby Isaac PetscInt tab; 25375fdea053SToby Isaac 253863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 25399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 25415fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 25429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 25439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 254463a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 25459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25475fdea053SToby Isaac } 25485fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 25499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 25509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 25515fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 255263a3b9bcSJacob 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]))); 25535fdea053SToby Isaac #else 255463a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 25555fdea053SToby Isaac #endif 25569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25585fdea053SToby Isaac } 25599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25605fdea053SToby Isaac } 25615fdea053SToby Isaac } 25629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25635fdea053SToby Isaac } 25649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25655fdea053SToby Isaac } 25665fdea053SToby Isaac } 25679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25685fdea053SToby Isaac } 25693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25705fdea053SToby Isaac } 25715fdea053SToby Isaac 25725fdea053SToby Isaac /*@ 25735fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 25745fdea053SToby Isaac 257520f4b53cSBarry Smith Logically 25765fdea053SToby Isaac 257760225df5SJacob Faibussowitsch Input Parameters: 25785fdea053SToby Isaac + sym - the section symmetries 257920f4b53cSBarry Smith - label - the `DMLabel` describing the types of points 25805fdea053SToby Isaac 25815fdea053SToby Isaac Level: developer: 25825fdea053SToby Isaac 258320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 25845fdea053SToby Isaac @*/ 2585d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 2586d71ae5a4SJacob Faibussowitsch { 25875fdea053SToby Isaac PetscSectionSym_Label *sl; 25885fdea053SToby Isaac 25895fdea053SToby Isaac PetscFunctionBegin; 25905fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 25915fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 25929566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 25935fdea053SToby Isaac if (label) { 25945fdea053SToby Isaac sl->label = label; 25959566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 25969566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 25979566063dSJacob 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)); 25989566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 25999566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 26009566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 26019566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 26029566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 26035fdea053SToby Isaac } 26043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26055fdea053SToby Isaac } 26065fdea053SToby Isaac 26075fdea053SToby Isaac /*@C 2608b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2609b004864fSMatthew G. Knepley 261020f4b53cSBarry Smith Logically Collective 2611b004864fSMatthew G. Knepley 2612b004864fSMatthew G. Knepley Input Parameters: 2613b004864fSMatthew G. Knepley + sym - the section symmetries 2614b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2615b004864fSMatthew G. Knepley 2616b004864fSMatthew G. Knepley Output Parameters: 261720f4b53cSBarry Smith + size - the number of dofs for points in the `stratum` of the label 261820f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 261920f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a ppoint in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 262020f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 262120f4b53cSBarry 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 2622b004864fSMatthew G. Knepley 2623b004864fSMatthew G. Knepley Level: developer 2624b004864fSMatthew G. Knepley 262520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2626b004864fSMatthew G. Knepley @*/ 2627d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2628d71ae5a4SJacob Faibussowitsch { 2629b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2630b004864fSMatthew G. Knepley const char *name; 2631b004864fSMatthew G. Knepley PetscInt i; 2632b004864fSMatthew G. Knepley 2633b004864fSMatthew G. Knepley PetscFunctionBegin; 2634b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2635b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2636b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2637b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2638b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2639b004864fSMatthew G. Knepley 2640b004864fSMatthew G. Knepley if (stratum == value) break; 2641b004864fSMatthew G. Knepley } 26429566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2643b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 26449371c9d4SSatish Balay if (size) { 26454f572ea9SToby Isaac PetscAssertPointer(size, 3); 26469371c9d4SSatish Balay *size = sl->sizes[i]; 26479371c9d4SSatish Balay } 26489371c9d4SSatish Balay if (minOrient) { 26494f572ea9SToby Isaac PetscAssertPointer(minOrient, 4); 26509371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 26519371c9d4SSatish Balay } 26529371c9d4SSatish Balay if (maxOrient) { 26534f572ea9SToby Isaac PetscAssertPointer(maxOrient, 5); 26549371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 26559371c9d4SSatish Balay } 26569371c9d4SSatish Balay if (perms) { 26574f572ea9SToby Isaac PetscAssertPointer(perms, 6); 26588e3a54c0SPierre Jolivet *perms = PetscSafePointerPlusOffset(sl->perms[i], sl->minMaxOrients[i][0]); 26599371c9d4SSatish Balay } 26609371c9d4SSatish Balay if (rots) { 26614f572ea9SToby Isaac PetscAssertPointer(rots, 7); 26628e3a54c0SPierre Jolivet *rots = PetscSafePointerPlusOffset(sl->rots[i], sl->minMaxOrients[i][0]); 26639371c9d4SSatish Balay } 26643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2665b004864fSMatthew G. Knepley } 2666b004864fSMatthew G. Knepley 2667b004864fSMatthew G. Knepley /*@C 26685fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 26695fdea053SToby Isaac 267020f4b53cSBarry Smith Logically 26715fdea053SToby Isaac 26725fdea053SToby Isaac Input Parameters: 26735b5e7992SMatthew G. Knepley + sym - the section symmetries 26745fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 267520f4b53cSBarry Smith . size - the number of dofs for points in the `stratum` of the label 267620f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 267720f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a point in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 267820f4b53cSBarry Smith . mode - how `sym` should copy the `perms` and `rots` arrays 267920f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 268020f4b53cSBarry 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 26815fdea053SToby Isaac 26825fdea053SToby Isaac Level: developer 26835fdea053SToby Isaac 268420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 26855fdea053SToby Isaac @*/ 2686d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 2687d71ae5a4SJacob Faibussowitsch { 26885fdea053SToby Isaac PetscSectionSym_Label *sl; 2689d67d17b1SMatthew G. Knepley const char *name; 2690d67d17b1SMatthew G. Knepley PetscInt i, j, k; 26915fdea053SToby Isaac 26925fdea053SToby Isaac PetscFunctionBegin; 26935fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 26945fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2695b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 26965fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 26975fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 26985fdea053SToby Isaac 26995fdea053SToby Isaac if (stratum == value) break; 27005fdea053SToby Isaac } 27019566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 270263a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 27035fdea053SToby Isaac sl->sizes[i] = size; 27045fdea053SToby Isaac sl->modes[i] = mode; 27055fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 27065fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 27075fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 27085fdea053SToby Isaac if (perms) { 27095fdea053SToby Isaac PetscInt **ownPerms; 27105fdea053SToby Isaac 27119566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 27125fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27135fdea053SToby Isaac if (perms[j]) { 27149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2715ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 27165fdea053SToby Isaac } 27175fdea053SToby Isaac } 27185fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 27195fdea053SToby Isaac } 27205fdea053SToby Isaac if (rots) { 27215fdea053SToby Isaac PetscScalar **ownRots; 27225fdea053SToby Isaac 27239566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 27245fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27255fdea053SToby Isaac if (rots[j]) { 27269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2727ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 27285fdea053SToby Isaac } 27295fdea053SToby Isaac } 27305fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 27315fdea053SToby Isaac } 27325fdea053SToby Isaac } else { 27338e3a54c0SPierre Jolivet sl->perms[i] = PetscSafePointerPlusOffset(perms, -minOrient); 27348e3a54c0SPierre Jolivet sl->rots[i] = PetscSafePointerPlusOffset(rots, -minOrient); 27355fdea053SToby Isaac } 27363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27375fdea053SToby Isaac } 27385fdea053SToby Isaac 2739d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 2740d71ae5a4SJacob Faibussowitsch { 27415fdea053SToby Isaac PetscInt i, j, numStrata; 27425fdea053SToby Isaac PetscSectionSym_Label *sl; 27435fdea053SToby Isaac DMLabel label; 27445fdea053SToby Isaac 27455fdea053SToby Isaac PetscFunctionBegin; 27465fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 27475fdea053SToby Isaac numStrata = sl->numStrata; 27485fdea053SToby Isaac label = sl->label; 27495fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 27505fdea053SToby Isaac PetscInt point = points[2 * i]; 27515fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 27525fdea053SToby Isaac 27535fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 27545fdea053SToby Isaac if (label->validIS[j]) { 27555fdea053SToby Isaac PetscInt k; 27565fdea053SToby Isaac 27579566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j], point, &k)); 27585fdea053SToby Isaac if (k >= 0) break; 27595fdea053SToby Isaac } else { 27605fdea053SToby Isaac PetscBool has; 27615fdea053SToby Isaac 27629566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 27635fdea053SToby Isaac if (has) break; 27645fdea053SToby Isaac } 27655fdea053SToby Isaac } 27669371c9d4SSatish 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], 27679371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2768ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2769ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 27705fdea053SToby Isaac } 27713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27725fdea053SToby Isaac } 27735fdea053SToby Isaac 2774d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2775d71ae5a4SJacob Faibussowitsch { 2776b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2777b004864fSMatthew G. Knepley IS valIS; 2778b004864fSMatthew G. Knepley const PetscInt *values; 2779b004864fSMatthew G. Knepley PetscInt Nv, v; 2780b004864fSMatthew G. Knepley 2781b004864fSMatthew G. Knepley PetscFunctionBegin; 27829566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 27839566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 27849566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2785b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2786b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2787b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2788b004864fSMatthew G. Knepley const PetscInt **perms; 2789b004864fSMatthew G. Knepley const PetscScalar **rots; 2790b004864fSMatthew G. Knepley 27919566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 27929566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2793b004864fSMatthew G. Knepley } 27949566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 27953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2796b004864fSMatthew G. Knepley } 2797b004864fSMatthew G. Knepley 2798d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2799d71ae5a4SJacob Faibussowitsch { 2800b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2801b004864fSMatthew G. Knepley DMLabel dlabel; 2802b004864fSMatthew G. Knepley 2803b004864fSMatthew G. Knepley PetscFunctionBegin; 28049566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 28059566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 28069566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 28079566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 28083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2809b004864fSMatthew G. Knepley } 2810b004864fSMatthew G. Knepley 2811d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 2812d71ae5a4SJacob Faibussowitsch { 28135fdea053SToby Isaac PetscSectionSym_Label *sl; 28145fdea053SToby Isaac 28155fdea053SToby Isaac PetscFunctionBegin; 28164dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 28175fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2818b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2819b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 28205fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 28215fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 28225fdea053SToby Isaac sym->data = (void *)sl; 28233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28245fdea053SToby Isaac } 28255fdea053SToby Isaac 28265fdea053SToby Isaac /*@ 28275fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 28285fdea053SToby Isaac 28295fdea053SToby Isaac Collective 28305fdea053SToby Isaac 28315fdea053SToby Isaac Input Parameters: 28325fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 28335fdea053SToby Isaac - label - the label defining the strata 28345fdea053SToby Isaac 28352fe279fdSBarry Smith Output Parameter: 28365fdea053SToby Isaac . sym - the section symmetries 28375fdea053SToby Isaac 28385fdea053SToby Isaac Level: developer 28395fdea053SToby Isaac 284020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 28415fdea053SToby Isaac @*/ 2842d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 2843d71ae5a4SJacob Faibussowitsch { 28445fdea053SToby Isaac PetscFunctionBegin; 28459566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 28469566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 28479566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 28489566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 28493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28505fdea053SToby Isaac } 2851