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 63120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 632609dae6eSVaclav Hapla @*/ 633d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 634d71ae5a4SJacob Faibussowitsch { 635609dae6eSVaclav Hapla const char *name0, *name1; 636609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 6375efe38ccSVaclav Hapla PetscBool eq; 6385efe38ccSVaclav Hapla PetscMPIInt rank; 639609dae6eSVaclav Hapla 640609dae6eSVaclav Hapla PetscFunctionBegin; 6415efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 6425efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6434f572ea9SToby Isaac if (equal) PetscAssertPointer(equal, 4); 6444f572ea9SToby Isaac if (message) PetscAssertPointer(message, 5); 6459566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6469566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 648609dae6eSVaclav Hapla { 649609dae6eSVaclav Hapla PetscInt v0, v1; 650609dae6eSVaclav Hapla 6519566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6529566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6535efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 65448a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Default value of DMLabel l0 \"%s\" = %" PetscInt_FMT " != %" PetscInt_FMT " = Default value of DMLabel l1 \"%s\"", name0, v0, v1, name1)); 655712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6565efe38ccSVaclav Hapla if (!eq) goto finish; 657609dae6eSVaclav Hapla } 658609dae6eSVaclav Hapla { 659609dae6eSVaclav Hapla IS is0, is1; 660609dae6eSVaclav Hapla 6619566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6629566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6639566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6649566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6659566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 66648a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 667712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6685efe38ccSVaclav Hapla if (!eq) goto finish; 669609dae6eSVaclav Hapla } 670609dae6eSVaclav Hapla { 671609dae6eSVaclav Hapla PetscInt i, nValues; 672609dae6eSVaclav Hapla 6739566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 674609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 675609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 676609dae6eSVaclav Hapla PetscInt n; 677609dae6eSVaclav Hapla IS is0, is1; 678609dae6eSVaclav Hapla 6799566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 680609dae6eSVaclav Hapla if (!n) continue; 6819566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6829566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6839566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6849566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6859566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6865efe38ccSVaclav Hapla if (!eq) { 68763a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum #%" PetscInt_FMT " with value %" PetscInt_FMT " contains different points in DMLabel l0 \"%s\" and DMLabel l1 \"%s\"", i, v, name0, name1)); 6885efe38ccSVaclav Hapla break; 689609dae6eSVaclav Hapla } 690609dae6eSVaclav Hapla } 691712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 692609dae6eSVaclav Hapla } 693609dae6eSVaclav Hapla finish: 6945efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 695609dae6eSVaclav Hapla if (message) { 696609dae6eSVaclav Hapla *message = NULL; 69748a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 6985efe38ccSVaclav Hapla } else { 69948a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 7009566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 7015efe38ccSVaclav Hapla } 7025efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 7035efe38ccSVaclav Hapla if (equal) *equal = eq; 70463a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 7053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 706609dae6eSVaclav Hapla } 707609dae6eSVaclav Hapla 708c6a43d28SMatthew G. Knepley /*@ 709c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 710c6a43d28SMatthew G. Knepley 71120f4b53cSBarry Smith Not Collective 7125b5e7992SMatthew G. Knepley 713c6a43d28SMatthew G. Knepley Input Parameter: 71420f4b53cSBarry Smith . label - The `DMLabel` 715c6a43d28SMatthew G. Knepley 716c6a43d28SMatthew G. Knepley Level: intermediate 717c6a43d28SMatthew G. Knepley 71820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 719c6a43d28SMatthew G. Knepley @*/ 720d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label) 721d71ae5a4SJacob Faibussowitsch { 722c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 723c6a43d28SMatthew G. Knepley 724c6a43d28SMatthew G. Knepley PetscFunctionBegin; 725c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7269566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 727c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 728c6a43d28SMatthew G. Knepley const PetscInt *points; 729c6a43d28SMatthew G. Knepley PetscInt i; 730c6a43d28SMatthew G. Knepley 7319566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 732c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 733c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 734c6a43d28SMatthew G. Knepley 735c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 736c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 737c6a43d28SMatthew G. Knepley } 7389566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 739c6a43d28SMatthew G. Knepley } 740c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 741c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7429566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 7433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 744c6a43d28SMatthew G. Knepley } 745c6a43d28SMatthew G. Knepley 746c6a43d28SMatthew G. Knepley /*@ 747c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 748c6a43d28SMatthew G. Knepley 74920f4b53cSBarry Smith Not Collective 7505b5e7992SMatthew G. Knepley 751c6a43d28SMatthew G. Knepley Input Parameters: 75220f4b53cSBarry Smith + label - The `DMLabel` 753c6a43d28SMatthew G. Knepley . pStart - The smallest point 754c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 755c6a43d28SMatthew G. Knepley 756c6a43d28SMatthew G. Knepley Level: intermediate 757c6a43d28SMatthew G. Knepley 75820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 759c6a43d28SMatthew G. Knepley @*/ 760d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 761d71ae5a4SJacob Faibussowitsch { 762c58f1c22SToby Isaac PetscInt v; 763c58f1c22SToby Isaac 764c58f1c22SToby Isaac PetscFunctionBegin; 765d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7669566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7679566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 768c58f1c22SToby Isaac label->pStart = pStart; 769c58f1c22SToby Isaac label->pEnd = pEnd; 770c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7719566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 772c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 7739f6c5813SMatthew G. Knepley IS pointIS; 774ad8374ffSToby Isaac const PetscInt *points; 775c58f1c22SToby Isaac PetscInt i; 776c58f1c22SToby Isaac 7779f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 7789f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &points)); 779c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 780ad8374ffSToby Isaac const PetscInt point = points[i]; 781c58f1c22SToby Isaac 7829f6c5813SMatthew G. Knepley PetscCheck(!(point < pStart) && !(point >= pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " in stratum %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->stratumValues[v], pStart, pEnd); 7839566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 784c58f1c22SToby Isaac } 7859566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 7869f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 787c58f1c22SToby Isaac } 7883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 789c58f1c22SToby Isaac } 790c58f1c22SToby Isaac 791c6a43d28SMatthew G. Knepley /*@ 792c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 793c6a43d28SMatthew G. Knepley 79420f4b53cSBarry Smith Not Collective 7955b5e7992SMatthew G. Knepley 796c6a43d28SMatthew G. Knepley Input Parameter: 79720f4b53cSBarry Smith . label - the `DMLabel` 798c6a43d28SMatthew G. Knepley 799c6a43d28SMatthew G. Knepley Level: intermediate 800c6a43d28SMatthew G. Knepley 80120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 802c6a43d28SMatthew G. Knepley @*/ 803d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label) 804d71ae5a4SJacob Faibussowitsch { 805c58f1c22SToby Isaac PetscFunctionBegin; 806d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 807c58f1c22SToby Isaac label->pStart = -1; 808c58f1c22SToby Isaac label->pEnd = -1; 8099566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 8103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 811c58f1c22SToby Isaac } 812c58f1c22SToby Isaac 813c58f1c22SToby Isaac /*@ 814c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 815c6a43d28SMatthew G. Knepley 81620f4b53cSBarry Smith Not Collective 8175b5e7992SMatthew G. Knepley 818c6a43d28SMatthew G. Knepley Input Parameter: 81920f4b53cSBarry Smith . label - the `DMLabel` 820c6a43d28SMatthew G. Knepley 821c6a43d28SMatthew G. Knepley Output Parameters: 822c6a43d28SMatthew G. Knepley + pStart - The smallest point 823c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 824c6a43d28SMatthew G. Knepley 825c6a43d28SMatthew G. Knepley Level: intermediate 826c6a43d28SMatthew G. Knepley 82720f4b53cSBarry Smith Note: 82820f4b53cSBarry Smith This will compute an index for the label if one does not exist. 82920f4b53cSBarry Smith 83020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 831c6a43d28SMatthew G. Knepley @*/ 832d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 833d71ae5a4SJacob Faibussowitsch { 834c6a43d28SMatthew G. Knepley PetscFunctionBegin; 835c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8369566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 837c6a43d28SMatthew G. Knepley if (pStart) { 8384f572ea9SToby Isaac PetscAssertPointer(pStart, 2); 839c6a43d28SMatthew G. Knepley *pStart = label->pStart; 840c6a43d28SMatthew G. Knepley } 841c6a43d28SMatthew G. Knepley if (pEnd) { 8424f572ea9SToby Isaac PetscAssertPointer(pEnd, 3); 843c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 844c6a43d28SMatthew G. Knepley } 8453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 846c6a43d28SMatthew G. Knepley } 847c6a43d28SMatthew G. Knepley 848c6a43d28SMatthew G. Knepley /*@ 849c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 850c58f1c22SToby Isaac 85120f4b53cSBarry Smith Not Collective 8525b5e7992SMatthew G. Knepley 853c58f1c22SToby Isaac Input Parameters: 85420f4b53cSBarry Smith + label - the `DMLabel` 855c58f1c22SToby Isaac - value - the value 856c58f1c22SToby Isaac 857c58f1c22SToby Isaac Output Parameter: 858c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 859c58f1c22SToby Isaac 860c58f1c22SToby Isaac Level: developer 861c58f1c22SToby Isaac 86220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 863c58f1c22SToby Isaac @*/ 864d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 865d71ae5a4SJacob Faibussowitsch { 866c58f1c22SToby Isaac PetscInt v; 867c58f1c22SToby Isaac 868c58f1c22SToby Isaac PetscFunctionBegin; 869d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8704f572ea9SToby Isaac PetscAssertPointer(contains, 3); 8719566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8720c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 8733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 874c58f1c22SToby Isaac } 875c58f1c22SToby Isaac 876c58f1c22SToby Isaac /*@ 877c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 878c58f1c22SToby Isaac 87920f4b53cSBarry Smith Not Collective 8805b5e7992SMatthew G. Knepley 881c58f1c22SToby Isaac Input Parameters: 88220f4b53cSBarry Smith + label - the `DMLabel` 883c58f1c22SToby Isaac - point - the point 884c58f1c22SToby Isaac 885c58f1c22SToby Isaac Output Parameter: 886c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 887c58f1c22SToby Isaac 888c58f1c22SToby Isaac Level: developer 889c58f1c22SToby Isaac 89020f4b53cSBarry Smith Note: 89120f4b53cSBarry Smith The user must call `DMLabelCreateIndex()` before this function. 89220f4b53cSBarry Smith 89320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 894c58f1c22SToby Isaac @*/ 895d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 896d71ae5a4SJacob Faibussowitsch { 897c58f1c22SToby Isaac PetscFunctionBeginHot; 898d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8994f572ea9SToby Isaac PetscAssertPointer(contains, 3); 9009566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 90176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 90228b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 90363a3b9bcSJacob Faibussowitsch PetscCheck(!(point < label->pStart) && !(point >= label->pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->pStart, label->pEnd); 90476bd3646SJed Brown } 905c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 9063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 907c58f1c22SToby Isaac } 908c58f1c22SToby Isaac 909c58f1c22SToby Isaac /*@ 910c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 911c58f1c22SToby Isaac 91220f4b53cSBarry Smith Not Collective 9135b5e7992SMatthew G. Knepley 914c58f1c22SToby Isaac Input Parameters: 91520f4b53cSBarry Smith + label - the `DMLabel` 916c58f1c22SToby Isaac . value - the stratum value 917c58f1c22SToby Isaac - point - the point 918c58f1c22SToby Isaac 919c58f1c22SToby Isaac Output Parameter: 920c58f1c22SToby Isaac . contains - true if the stratum contains the point 921c58f1c22SToby Isaac 922c58f1c22SToby Isaac Level: intermediate 923c58f1c22SToby Isaac 92420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 925c58f1c22SToby Isaac @*/ 926d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 927d71ae5a4SJacob Faibussowitsch { 9280c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 929d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9304f572ea9SToby Isaac PetscAssertPointer(contains, 4); 931cffad2c9SToby Isaac if (value == label->defaultValue) { 932cffad2c9SToby Isaac PetscInt pointVal; 9330c3c4a36SLisandro Dalcin 934cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 935cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 936cffad2c9SToby Isaac } else { 937cffad2c9SToby Isaac PetscInt v; 938cffad2c9SToby Isaac 939cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 940cffad2c9SToby Isaac if (v >= 0) { 9419f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 9429f6c5813SMatthew G. Knepley IS is; 943c58f1c22SToby Isaac PetscInt i; 944c58f1c22SToby Isaac 9459f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 9469f6c5813SMatthew G. Knepley PetscCall(ISLocate(is, point, &i)); 9479f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 948cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 949c58f1c22SToby Isaac } else { 950cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 951cffad2c9SToby Isaac } 952cffad2c9SToby Isaac } else { // value is not present 953cffad2c9SToby Isaac *contains = PETSC_FALSE; 954cffad2c9SToby Isaac } 955c58f1c22SToby Isaac } 9563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 957c58f1c22SToby Isaac } 958c58f1c22SToby Isaac 95984f0b6dfSMatthew G. Knepley /*@ 96020f4b53cSBarry Smith DMLabelGetDefaultValue - Get the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9615aa44df4SToby Isaac When a label is created, it is initialized to -1. 9625aa44df4SToby Isaac 96320f4b53cSBarry Smith Not Collective 9645b5e7992SMatthew G. Knepley 96560225df5SJacob Faibussowitsch Input Parameter: 96620f4b53cSBarry Smith . label - a `DMLabel` object 9675aa44df4SToby Isaac 96860225df5SJacob Faibussowitsch Output Parameter: 9695aa44df4SToby Isaac . defaultValue - the default value 9705aa44df4SToby Isaac 9715aa44df4SToby Isaac Level: beginner 9725aa44df4SToby Isaac 97320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 97484f0b6dfSMatthew G. Knepley @*/ 975d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 976d71ae5a4SJacob Faibussowitsch { 9775aa44df4SToby Isaac PetscFunctionBegin; 978d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9795aa44df4SToby Isaac *defaultValue = label->defaultValue; 9803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9815aa44df4SToby Isaac } 9825aa44df4SToby Isaac 98384f0b6dfSMatthew G. Knepley /*@ 98420f4b53cSBarry Smith DMLabelSetDefaultValue - Set the default value returned by `DMLabelGetValue()` if a point has not been explicitly given a value. 9855aa44df4SToby Isaac When a label is created, it is initialized to -1. 9865aa44df4SToby Isaac 98720f4b53cSBarry Smith Not Collective 9885b5e7992SMatthew G. Knepley 98960225df5SJacob Faibussowitsch Input Parameter: 99020f4b53cSBarry Smith . label - a `DMLabel` object 9915aa44df4SToby Isaac 99260225df5SJacob Faibussowitsch Output Parameter: 9935aa44df4SToby Isaac . defaultValue - the default value 9945aa44df4SToby Isaac 9955aa44df4SToby Isaac Level: beginner 9965aa44df4SToby Isaac 99720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 99884f0b6dfSMatthew G. Knepley @*/ 999d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 1000d71ae5a4SJacob Faibussowitsch { 10015aa44df4SToby Isaac PetscFunctionBegin; 1002d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10035aa44df4SToby Isaac label->defaultValue = defaultValue; 10043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10055aa44df4SToby Isaac } 10065aa44df4SToby Isaac 1007c58f1c22SToby Isaac /*@ 100820f4b53cSBarry Smith DMLabelGetValue - Return the value a label assigns to a point, or the label's default value (which is initially -1, and can be changed with 100920f4b53cSBarry Smith `DMLabelSetDefaultValue()`) 1010c58f1c22SToby Isaac 101120f4b53cSBarry Smith Not Collective 10125b5e7992SMatthew G. Knepley 1013c58f1c22SToby Isaac Input Parameters: 101420f4b53cSBarry Smith + label - the `DMLabel` 1015c58f1c22SToby Isaac - point - the point 1016c58f1c22SToby Isaac 1017c58f1c22SToby Isaac Output Parameter: 10188e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 1019c58f1c22SToby Isaac 1020c58f1c22SToby Isaac Level: intermediate 1021c58f1c22SToby Isaac 102220f4b53cSBarry Smith Note: 102320f4b53cSBarry Smith A label may assign multiple values to a point. No guarantees are made about which value is returned in that case. 102420f4b53cSBarry Smith Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum. 102520f4b53cSBarry Smith 102620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1027c58f1c22SToby Isaac @*/ 1028d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 1029d71ae5a4SJacob Faibussowitsch { 1030c58f1c22SToby Isaac PetscInt v; 1031c58f1c22SToby Isaac 10320c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 1033d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10344f572ea9SToby Isaac PetscAssertPointer(value, 3); 10355aa44df4SToby Isaac *value = label->defaultValue; 1036c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 10379f6c5813SMatthew G. Knepley if (label->validIS[v] || label->readonly) { 10389f6c5813SMatthew G. Knepley IS is; 1039c58f1c22SToby Isaac PetscInt i; 1040c58f1c22SToby Isaac 10419f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 10429566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 10439f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1044c58f1c22SToby Isaac if (i >= 0) { 1045c58f1c22SToby Isaac *value = label->stratumValues[v]; 1046c58f1c22SToby Isaac break; 1047c58f1c22SToby Isaac } 1048c58f1c22SToby Isaac } else { 1049c58f1c22SToby Isaac PetscBool has; 1050c58f1c22SToby Isaac 10519566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 1052c58f1c22SToby Isaac if (has) { 1053c58f1c22SToby Isaac *value = label->stratumValues[v]; 1054c58f1c22SToby Isaac break; 1055c58f1c22SToby Isaac } 1056c58f1c22SToby Isaac } 1057c58f1c22SToby Isaac } 10583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1059c58f1c22SToby Isaac } 1060c58f1c22SToby Isaac 1061c58f1c22SToby Isaac /*@ 106220f4b53cSBarry Smith DMLabelSetValue - Set the value a label assigns to a point. If the value is the same as the label's default value (which is initially -1, and can 106320f4b53cSBarry Smith be changed with `DMLabelSetDefaultValue()` to something different), then this function will do nothing. 1064c58f1c22SToby Isaac 106520f4b53cSBarry Smith Not Collective 10665b5e7992SMatthew G. Knepley 1067c58f1c22SToby Isaac Input Parameters: 106820f4b53cSBarry Smith + label - the `DMLabel` 1069c58f1c22SToby Isaac . point - the point 1070c58f1c22SToby Isaac - value - The point value 1071c58f1c22SToby Isaac 1072c58f1c22SToby Isaac Level: intermediate 1073c58f1c22SToby Isaac 107420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1075c58f1c22SToby Isaac @*/ 1076d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1077d71ae5a4SJacob Faibussowitsch { 1078c58f1c22SToby Isaac PetscInt v; 1079c58f1c22SToby Isaac 1080c58f1c22SToby Isaac PetscFunctionBegin; 1081d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10820c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10833ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 10849f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 10859566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1086c58f1c22SToby Isaac /* Set key */ 10879566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10889566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 10893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1090c58f1c22SToby Isaac } 1091c58f1c22SToby Isaac 1092c58f1c22SToby Isaac /*@ 1093c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1094c58f1c22SToby Isaac 109520f4b53cSBarry Smith Not Collective 10965b5e7992SMatthew G. Knepley 1097c58f1c22SToby Isaac Input Parameters: 109820f4b53cSBarry Smith + label - the `DMLabel` 1099c58f1c22SToby Isaac . point - the point 1100c58f1c22SToby Isaac - value - The point value 1101c58f1c22SToby Isaac 1102c58f1c22SToby Isaac Level: intermediate 1103c58f1c22SToby Isaac 110420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1105c58f1c22SToby Isaac @*/ 1106d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1107d71ae5a4SJacob Faibussowitsch { 1108ad8374ffSToby Isaac PetscInt v; 1109c58f1c22SToby Isaac 1110c58f1c22SToby Isaac PetscFunctionBegin; 1111d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11129f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 1113c58f1c22SToby Isaac /* Find label value */ 11149566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 11153ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 11160c3c4a36SLisandro Dalcin 1117eeed21e7SToby Isaac if (label->bt) { 111863a3b9bcSJacob Faibussowitsch PetscCheck(!(point < label->pStart) && !(point >= label->pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->pStart, label->pEnd); 11199566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1120eeed21e7SToby Isaac } 11210c3c4a36SLisandro Dalcin 11220c3c4a36SLisandro Dalcin /* Delete key */ 11239566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11249566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 11253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1126c58f1c22SToby Isaac } 1127c58f1c22SToby Isaac 1128c58f1c22SToby Isaac /*@ 112920f4b53cSBarry Smith DMLabelInsertIS - Set all points in the `IS` to a value 1130c58f1c22SToby Isaac 113120f4b53cSBarry Smith Not Collective 11325b5e7992SMatthew G. Knepley 1133c58f1c22SToby Isaac Input Parameters: 113420f4b53cSBarry Smith + label - the `DMLabel` 11352fe279fdSBarry Smith . is - the point `IS` 1136c58f1c22SToby Isaac - value - The point value 1137c58f1c22SToby Isaac 1138c58f1c22SToby Isaac Level: intermediate 1139c58f1c22SToby Isaac 114020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1141c58f1c22SToby Isaac @*/ 1142d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1143d71ae5a4SJacob Faibussowitsch { 11440c3c4a36SLisandro Dalcin PetscInt v, n, p; 1145c58f1c22SToby Isaac const PetscInt *points; 1146c58f1c22SToby Isaac 1147c58f1c22SToby Isaac PetscFunctionBegin; 1148d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1149c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 11500c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11513ba16761SJacob Faibussowitsch if (value == label->defaultValue) PetscFunctionReturn(PETSC_SUCCESS); 11529f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 11539566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 11540c3c4a36SLisandro Dalcin /* Set keys */ 11559566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11569566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 11579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 11589566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 11599566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 11603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1161c58f1c22SToby Isaac } 1162c58f1c22SToby Isaac 116384f0b6dfSMatthew G. Knepley /*@ 116420f4b53cSBarry Smith DMLabelGetNumValues - Get the number of values that the `DMLabel` takes 116584f0b6dfSMatthew G. Knepley 116620f4b53cSBarry Smith Not Collective 11675b5e7992SMatthew G. Knepley 116884f0b6dfSMatthew G. Knepley Input Parameter: 116920f4b53cSBarry Smith . label - the `DMLabel` 117084f0b6dfSMatthew G. Knepley 117101d2d390SJose E. Roman Output Parameter: 117284f0b6dfSMatthew G. Knepley . numValues - the number of values 117384f0b6dfSMatthew G. Knepley 117484f0b6dfSMatthew G. Knepley Level: intermediate 117584f0b6dfSMatthew G. Knepley 117620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 117784f0b6dfSMatthew G. Knepley @*/ 1178d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1179d71ae5a4SJacob Faibussowitsch { 1180c58f1c22SToby Isaac PetscFunctionBegin; 1181d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11824f572ea9SToby Isaac PetscAssertPointer(numValues, 2); 1183c58f1c22SToby Isaac *numValues = label->numStrata; 11843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1185c58f1c22SToby Isaac } 1186c58f1c22SToby Isaac 118784f0b6dfSMatthew G. Knepley /*@ 118820f4b53cSBarry Smith DMLabelGetValueIS - Get an `IS` of all values that the `DMlabel` takes 118984f0b6dfSMatthew G. Knepley 119020f4b53cSBarry Smith Not Collective 11915b5e7992SMatthew G. Knepley 119284f0b6dfSMatthew G. Knepley Input Parameter: 119320f4b53cSBarry Smith . label - the `DMLabel` 119484f0b6dfSMatthew G. Knepley 119501d2d390SJose E. Roman Output Parameter: 119660225df5SJacob Faibussowitsch . values - the value `IS` 119784f0b6dfSMatthew G. Knepley 119884f0b6dfSMatthew G. Knepley Level: intermediate 119984f0b6dfSMatthew G. Knepley 12001d04cbbeSVaclav Hapla Notes: 120120f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 120220f4b53cSBarry Smith Strata which are allocated but empty [`DMLabelGetStratumSize()` yields 0] are counted. 120320f4b53cSBarry Smith If you need to count only nonempty strata, use `DMLabelGetNonEmptyStratumValuesIS()`. 12041d04cbbeSVaclav Hapla 120520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 120684f0b6dfSMatthew G. Knepley @*/ 1207d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1208d71ae5a4SJacob Faibussowitsch { 1209c58f1c22SToby Isaac PetscFunctionBegin; 1210d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12114f572ea9SToby Isaac PetscAssertPointer(values, 2); 12129566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1214c58f1c22SToby Isaac } 1215c58f1c22SToby Isaac 121684f0b6dfSMatthew G. Knepley /*@ 1217*8696263dSMatthew G. Knepley DMLabelGetValueBounds - Return the smallest and largest value in the label 1218*8696263dSMatthew G. Knepley 1219*8696263dSMatthew G. Knepley Not Collective 1220*8696263dSMatthew G. Knepley 1221*8696263dSMatthew G. Knepley Input Parameter: 1222*8696263dSMatthew G. Knepley . label - the `DMLabel` 1223*8696263dSMatthew G. Knepley 1224*8696263dSMatthew G. Knepley Output Parameters: 1225*8696263dSMatthew G. Knepley + minValue - The smallest value 1226*8696263dSMatthew G. Knepley - maxValue - The largest value 1227*8696263dSMatthew G. Knepley 1228*8696263dSMatthew G. Knepley Level: intermediate 1229*8696263dSMatthew G. Knepley 1230*8696263dSMatthew G. Knepley .seealso: `DMLabel`, `DM`, `DMLabelGetBounds()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1231*8696263dSMatthew G. Knepley @*/ 1232*8696263dSMatthew G. Knepley PetscErrorCode DMLabelGetValueBounds(DMLabel label, PetscInt *minValue, PetscInt *maxValue) 1233*8696263dSMatthew G. Knepley { 1234*8696263dSMatthew G. Knepley PetscInt min = PETSC_MAX_INT, max = PETSC_MIN_INT; 1235*8696263dSMatthew G. Knepley 1236*8696263dSMatthew G. Knepley PetscFunctionBegin; 1237*8696263dSMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1238*8696263dSMatthew G. Knepley for (PetscInt v = 0; v < label->numStrata; ++v) { 1239*8696263dSMatthew G. Knepley min = PetscMin(min, label->stratumValues[v]); 1240*8696263dSMatthew G. Knepley max = PetscMax(max, label->stratumValues[v]); 1241*8696263dSMatthew G. Knepley } 1242*8696263dSMatthew G. Knepley if (minValue) { 1243*8696263dSMatthew G. Knepley PetscAssertPointer(minValue, 2); 1244*8696263dSMatthew G. Knepley *minValue = min; 1245*8696263dSMatthew G. Knepley } 1246*8696263dSMatthew G. Knepley if (maxValue) { 1247*8696263dSMatthew G. Knepley PetscAssertPointer(maxValue, 3); 1248*8696263dSMatthew G. Knepley *maxValue = max; 1249*8696263dSMatthew G. Knepley } 1250*8696263dSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1251*8696263dSMatthew G. Knepley } 1252*8696263dSMatthew G. Knepley 1253*8696263dSMatthew G. Knepley /*@ 125420f4b53cSBarry Smith DMLabelGetNonEmptyStratumValuesIS - Get an `IS` of all values that the `DMlabel` takes 12551d04cbbeSVaclav Hapla 125620f4b53cSBarry Smith Not Collective 12571d04cbbeSVaclav Hapla 12581d04cbbeSVaclav Hapla Input Parameter: 125920f4b53cSBarry Smith . label - the `DMLabel` 12601d04cbbeSVaclav Hapla 1261d5b43468SJose E. Roman Output Parameter: 126260225df5SJacob Faibussowitsch . values - the value `IS` 12631d04cbbeSVaclav Hapla 12641d04cbbeSVaclav Hapla Level: intermediate 12651d04cbbeSVaclav Hapla 12661d04cbbeSVaclav Hapla Notes: 126720f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 126820f4b53cSBarry Smith This is similar to `DMLabelGetValueIS()` but counts only nonempty strata. 12691d04cbbeSVaclav Hapla 127020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 12711d04cbbeSVaclav Hapla @*/ 1272d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 1273d71ae5a4SJacob Faibussowitsch { 12741d04cbbeSVaclav Hapla PetscInt i, j; 12751d04cbbeSVaclav Hapla PetscInt *valuesArr; 12761d04cbbeSVaclav Hapla 12771d04cbbeSVaclav Hapla PetscFunctionBegin; 12781d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12794f572ea9SToby Isaac PetscAssertPointer(values, 2); 12809566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 12811d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 12821d04cbbeSVaclav Hapla PetscInt n; 12831d04cbbeSVaclav Hapla 12849566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 12851d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 12861d04cbbeSVaclav Hapla } 12871d04cbbeSVaclav Hapla if (j == label->numStrata) { 12889566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 12891d04cbbeSVaclav Hapla } else { 12909566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 12911d04cbbeSVaclav Hapla } 12929566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 12933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12941d04cbbeSVaclav Hapla } 12951d04cbbeSVaclav Hapla 12961d04cbbeSVaclav Hapla /*@ 129720f4b53cSBarry Smith DMLabelGetValueIndex - Get the index of a given value in the list of values for the `DMlabel`, or -1 if it is not present 1298d123abd9SMatthew G. Knepley 129920f4b53cSBarry Smith Not Collective 1300d123abd9SMatthew G. Knepley 1301d123abd9SMatthew G. Knepley Input Parameters: 130220f4b53cSBarry Smith + label - the `DMLabel` 130397bb3fdcSJose E. Roman - value - the value 1304d123abd9SMatthew G. Knepley 130501d2d390SJose E. Roman Output Parameter: 1306d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1307d123abd9SMatthew G. Knepley 1308d123abd9SMatthew G. Knepley Level: intermediate 1309d123abd9SMatthew G. Knepley 131020f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1311d123abd9SMatthew G. Knepley @*/ 1312d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1313d71ae5a4SJacob Faibussowitsch { 1314d123abd9SMatthew G. Knepley PetscInt v; 1315d123abd9SMatthew G. Knepley 1316d123abd9SMatthew G. Knepley PetscFunctionBegin; 1317d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13184f572ea9SToby Isaac PetscAssertPointer(index, 3); 1319d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 13209371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 13219371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1322d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1323d123abd9SMatthew G. Knepley else *index = v; 13243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1325d123abd9SMatthew G. Knepley } 1326d123abd9SMatthew G. Knepley 1327d123abd9SMatthew G. Knepley /*@ 132884f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 132984f0b6dfSMatthew G. Knepley 133020f4b53cSBarry Smith Not Collective 13315b5e7992SMatthew G. Knepley 133284f0b6dfSMatthew G. Knepley Input Parameters: 133320f4b53cSBarry Smith + label - the `DMLabel` 133484f0b6dfSMatthew G. Knepley - value - the stratum value 133584f0b6dfSMatthew G. Knepley 133601d2d390SJose E. Roman Output Parameter: 133784f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 133884f0b6dfSMatthew G. Knepley 133984f0b6dfSMatthew G. Knepley Level: intermediate 134084f0b6dfSMatthew G. Knepley 134120f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 134284f0b6dfSMatthew G. Knepley @*/ 1343d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1344d71ae5a4SJacob Faibussowitsch { 1345fada774cSMatthew G. Knepley PetscInt v; 1346fada774cSMatthew G. Knepley 1347fada774cSMatthew G. Knepley PetscFunctionBegin; 1348d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13494f572ea9SToby Isaac PetscAssertPointer(exists, 3); 13509566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13510c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 13523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1353fada774cSMatthew G. Knepley } 1354fada774cSMatthew G. Knepley 135584f0b6dfSMatthew G. Knepley /*@ 135684f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 135784f0b6dfSMatthew G. Knepley 135820f4b53cSBarry Smith Not Collective 13595b5e7992SMatthew G. Knepley 136084f0b6dfSMatthew G. Knepley Input Parameters: 136120f4b53cSBarry Smith + label - the `DMLabel` 136284f0b6dfSMatthew G. Knepley - value - the stratum value 136384f0b6dfSMatthew G. Knepley 136401d2d390SJose E. Roman Output Parameter: 136584f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 136684f0b6dfSMatthew G. Knepley 136784f0b6dfSMatthew G. Knepley Level: intermediate 136884f0b6dfSMatthew G. Knepley 136920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 137084f0b6dfSMatthew G. Knepley @*/ 1371d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1372d71ae5a4SJacob Faibussowitsch { 1373c58f1c22SToby Isaac PetscInt v; 1374c58f1c22SToby Isaac 1375c58f1c22SToby Isaac PetscFunctionBegin; 1376d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13774f572ea9SToby Isaac PetscAssertPointer(size, 3); 13789566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13799566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 13803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1381c58f1c22SToby Isaac } 1382c58f1c22SToby Isaac 138384f0b6dfSMatthew G. Knepley /*@ 138484f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 138584f0b6dfSMatthew G. Knepley 138620f4b53cSBarry Smith Not Collective 13875b5e7992SMatthew G. Knepley 138884f0b6dfSMatthew G. Knepley Input Parameters: 138920f4b53cSBarry Smith + label - the `DMLabel` 139084f0b6dfSMatthew G. Knepley - value - the stratum value 139184f0b6dfSMatthew G. Knepley 139201d2d390SJose E. Roman Output Parameters: 139384f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 139484f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 139584f0b6dfSMatthew G. Knepley 139684f0b6dfSMatthew G. Knepley Level: intermediate 139784f0b6dfSMatthew G. Knepley 139820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 139984f0b6dfSMatthew G. Knepley @*/ 1400d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1401d71ae5a4SJacob Faibussowitsch { 14029f6c5813SMatthew G. Knepley IS is; 14030c3c4a36SLisandro Dalcin PetscInt v, min, max; 1404c58f1c22SToby Isaac 1405c58f1c22SToby Isaac PetscFunctionBegin; 1406d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14079371c9d4SSatish Balay if (start) { 14084f572ea9SToby Isaac PetscAssertPointer(start, 3); 14099371c9d4SSatish Balay *start = -1; 14109371c9d4SSatish Balay } 14119371c9d4SSatish Balay if (end) { 14124f572ea9SToby Isaac PetscAssertPointer(end, 4); 14139371c9d4SSatish Balay *end = -1; 14149371c9d4SSatish Balay } 14159566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14163ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14179566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14183ba16761SJacob Faibussowitsch if (label->stratumSizes[v] <= 0) PetscFunctionReturn(PETSC_SUCCESS); 14199f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &is); 14209f6c5813SMatthew G. Knepley PetscCall(ISGetMinMax(is, &min, &max)); 14219f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&is)); 1422d6cb179aSToby Isaac if (start) *start = min; 1423d6cb179aSToby Isaac if (end) *end = max + 1; 14243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1425c58f1c22SToby Isaac } 1426c58f1c22SToby Isaac 142766976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelGetStratumIS_Concrete(DMLabel label, PetscInt v, IS *pointIS) 14289f6c5813SMatthew G. Knepley { 14299f6c5813SMatthew G. Knepley PetscFunctionBegin; 14309f6c5813SMatthew G. Knepley PetscCall(PetscObjectReference((PetscObject)label->points[v])); 14319f6c5813SMatthew G. Knepley *pointIS = label->points[v]; 14323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14339f6c5813SMatthew G. Knepley } 14349f6c5813SMatthew G. Knepley 143584f0b6dfSMatthew G. Knepley /*@ 143620f4b53cSBarry Smith DMLabelGetStratumIS - Get an `IS` with the stratum points 143784f0b6dfSMatthew G. Knepley 143820f4b53cSBarry Smith Not Collective 14395b5e7992SMatthew G. Knepley 144084f0b6dfSMatthew G. Knepley Input Parameters: 144120f4b53cSBarry Smith + label - the `DMLabel` 144284f0b6dfSMatthew G. Knepley - value - the stratum value 144384f0b6dfSMatthew G. Knepley 144401d2d390SJose E. Roman Output Parameter: 144584f0b6dfSMatthew G. Knepley . points - The stratum points 144684f0b6dfSMatthew G. Knepley 144784f0b6dfSMatthew G. Knepley Level: intermediate 144884f0b6dfSMatthew G. Knepley 1449593ce467SVaclav Hapla Notes: 145020f4b53cSBarry Smith The output `IS` should be destroyed when no longer needed. 145120f4b53cSBarry Smith Returns `NULL` if the stratum is empty. 1452593ce467SVaclav Hapla 145320f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 145484f0b6dfSMatthew G. Knepley @*/ 1455d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1456d71ae5a4SJacob Faibussowitsch { 1457c58f1c22SToby Isaac PetscInt v; 1458c58f1c22SToby Isaac 1459c58f1c22SToby Isaac PetscFunctionBegin; 1460d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14614f572ea9SToby Isaac PetscAssertPointer(points, 3); 1462c58f1c22SToby Isaac *points = NULL; 14639566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14643ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 14659566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14669f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, points); 14673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1468c58f1c22SToby Isaac } 1469c58f1c22SToby Isaac 147084f0b6dfSMatthew G. Knepley /*@ 147120f4b53cSBarry Smith DMLabelSetStratumIS - Set the stratum points using an `IS` 147284f0b6dfSMatthew G. Knepley 147320f4b53cSBarry Smith Not Collective 14745b5e7992SMatthew G. Knepley 147584f0b6dfSMatthew G. Knepley Input Parameters: 147620f4b53cSBarry Smith + label - the `DMLabel` 147784f0b6dfSMatthew G. Knepley . value - the stratum value 147860225df5SJacob Faibussowitsch - is - The stratum points 147984f0b6dfSMatthew G. Knepley 148084f0b6dfSMatthew G. Knepley Level: intermediate 148184f0b6dfSMatthew G. Knepley 148220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 148384f0b6dfSMatthew G. Knepley @*/ 1484d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 1485d71ae5a4SJacob Faibussowitsch { 14860c3c4a36SLisandro Dalcin PetscInt v; 14874de306b1SToby Isaac 14884de306b1SToby Isaac PetscFunctionBegin; 1489d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1490d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 14919f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 14929566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 14933ba16761SJacob Faibussowitsch if (is == label->points[v]) PetscFunctionReturn(PETSC_SUCCESS); 14949566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 1495f4f49eeaSPierre Jolivet PetscCall(ISGetLocalSize(is, &label->stratumSizes[v])); 14969566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 1497f4f49eeaSPierre Jolivet PetscCall(ISDestroy(&label->points[v])); 14980c3c4a36SLisandro Dalcin label->points[v] = is; 14990c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 15009566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 15014de306b1SToby Isaac if (label->bt) { 15024de306b1SToby Isaac const PetscInt *points; 15034de306b1SToby Isaac PetscInt p; 15044de306b1SToby Isaac 15059566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 15064de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 15074de306b1SToby Isaac const PetscInt point = points[p]; 15084de306b1SToby Isaac 150963a3b9bcSJacob 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); 15109566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 15114de306b1SToby Isaac } 15124de306b1SToby Isaac } 15133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15144de306b1SToby Isaac } 15154de306b1SToby Isaac 151684f0b6dfSMatthew G. Knepley /*@ 151784f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 15184de306b1SToby Isaac 151920f4b53cSBarry Smith Not Collective 15205b5e7992SMatthew G. Knepley 152184f0b6dfSMatthew G. Knepley Input Parameters: 152220f4b53cSBarry Smith + label - the `DMLabel` 152384f0b6dfSMatthew G. Knepley - value - the stratum value 152484f0b6dfSMatthew G. Knepley 152584f0b6dfSMatthew G. Knepley Level: intermediate 152684f0b6dfSMatthew G. Knepley 152720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 152884f0b6dfSMatthew G. Knepley @*/ 1529d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1530d71ae5a4SJacob Faibussowitsch { 1531c58f1c22SToby Isaac PetscInt v; 1532c58f1c22SToby Isaac 1533c58f1c22SToby Isaac PetscFunctionBegin; 1534d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15359f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 15369566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 15373ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 15384de306b1SToby Isaac if (label->validIS[v]) { 15394de306b1SToby Isaac if (label->bt) { 1540c58f1c22SToby Isaac PetscInt i; 1541ad8374ffSToby Isaac const PetscInt *points; 1542c58f1c22SToby Isaac 15439566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1544c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1545ad8374ffSToby Isaac const PetscInt point = points[i]; 1546c58f1c22SToby Isaac 154763a3b9bcSJacob 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); 15489566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1549c58f1c22SToby Isaac } 15509566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1551c58f1c22SToby Isaac } 1552c58f1c22SToby Isaac label->stratumSizes[v] = 0; 15539566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 15549566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 15559566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 15569566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1557c58f1c22SToby Isaac } else { 15589566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1559c58f1c22SToby Isaac } 15603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1561c58f1c22SToby Isaac } 1562c58f1c22SToby Isaac 156384f0b6dfSMatthew G. Knepley /*@ 1564412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1565412e9a14SMatthew G. Knepley 156620f4b53cSBarry Smith Not Collective 1567412e9a14SMatthew G. Knepley 1568412e9a14SMatthew G. Knepley Input Parameters: 156920f4b53cSBarry Smith + label - The `DMLabel` 1570412e9a14SMatthew G. Knepley . value - The label value for all points 1571412e9a14SMatthew G. Knepley . pStart - The first point 1572412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1573412e9a14SMatthew G. Knepley 1574412e9a14SMatthew G. Knepley Level: intermediate 1575412e9a14SMatthew G. Knepley 157620f4b53cSBarry Smith Note: 157720f4b53cSBarry Smith The marks points are [`pStart`, `pEnd`), and only the bounds are stored. 157820f4b53cSBarry Smith 157920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1580412e9a14SMatthew G. Knepley @*/ 1581d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1582d71ae5a4SJacob Faibussowitsch { 1583412e9a14SMatthew G. Knepley IS pIS; 1584412e9a14SMatthew G. Knepley 1585412e9a14SMatthew G. Knepley PetscFunctionBegin; 15869566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 15879566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 15889566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 15893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1590412e9a14SMatthew G. Knepley } 1591412e9a14SMatthew G. Knepley 1592412e9a14SMatthew G. Knepley /*@ 1593d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1594d123abd9SMatthew G. Knepley 159520f4b53cSBarry Smith Not Collective 1596d123abd9SMatthew G. Knepley 1597d123abd9SMatthew G. Knepley Input Parameters: 159820f4b53cSBarry Smith + label - The `DMLabel` 1599d123abd9SMatthew G. Knepley . value - The label value 1600d123abd9SMatthew G. Knepley - p - A point with this value 1601d123abd9SMatthew G. Knepley 1602d123abd9SMatthew G. Knepley Output Parameter: 1603d123abd9SMatthew 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 1604d123abd9SMatthew G. Knepley 1605d123abd9SMatthew G. Knepley Level: intermediate 1606d123abd9SMatthew G. Knepley 160720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1608d123abd9SMatthew G. Knepley @*/ 1609d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1610d71ae5a4SJacob Faibussowitsch { 16119f6c5813SMatthew G. Knepley IS pointIS; 1612d123abd9SMatthew G. Knepley const PetscInt *indices; 1613d123abd9SMatthew G. Knepley PetscInt v; 1614d123abd9SMatthew G. Knepley 1615d123abd9SMatthew G. Knepley PetscFunctionBegin; 1616d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16174f572ea9SToby Isaac PetscAssertPointer(index, 4); 1618d123abd9SMatthew G. Knepley *index = -1; 16199566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 16203ba16761SJacob Faibussowitsch if (v < 0) PetscFunctionReturn(PETSC_SUCCESS); 16219566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 16229f6c5813SMatthew G. Knepley PetscUseTypeMethod(label, getstratumis, v, &pointIS); 16239f6c5813SMatthew G. Knepley PetscCall(ISGetIndices(pointIS, &indices)); 16249566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 16259f6c5813SMatthew G. Knepley PetscCall(ISRestoreIndices(pointIS, &indices)); 16269f6c5813SMatthew G. Knepley PetscCall(ISDestroy(&pointIS)); 16273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1628d123abd9SMatthew G. Knepley } 1629d123abd9SMatthew G. Knepley 1630d123abd9SMatthew G. Knepley /*@ 163120f4b53cSBarry Smith DMLabelFilter - Remove all points outside of [`start`, `end`) 163284f0b6dfSMatthew G. Knepley 163320f4b53cSBarry Smith Not Collective 16345b5e7992SMatthew G. Knepley 163584f0b6dfSMatthew G. Knepley Input Parameters: 163620f4b53cSBarry Smith + label - the `DMLabel` 163722cd2cdaSVaclav Hapla . start - the first point kept 163822cd2cdaSVaclav Hapla - end - one more than the last point kept 163984f0b6dfSMatthew G. Knepley 164084f0b6dfSMatthew G. Knepley Level: intermediate 164184f0b6dfSMatthew G. Knepley 164220f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 164384f0b6dfSMatthew G. Knepley @*/ 1644d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1645d71ae5a4SJacob Faibussowitsch { 1646c58f1c22SToby Isaac PetscInt v; 1647c58f1c22SToby Isaac 1648c58f1c22SToby Isaac PetscFunctionBegin; 1649d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16509f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16519566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 16529566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16539f6c5813SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 16549f6c5813SMatthew G. Knepley PetscCall(ISGeneralFilter(label->points[v], start, end)); 16559f6c5813SMatthew G. Knepley PetscCall(ISGetLocalSize(label->points[v], &label->stratumSizes[v])); 16569f6c5813SMatthew G. Knepley } 16579566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 16583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1659c58f1c22SToby Isaac } 1660c58f1c22SToby Isaac 166184f0b6dfSMatthew G. Knepley /*@ 166284f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 166384f0b6dfSMatthew G. Knepley 166420f4b53cSBarry Smith Not Collective 16655b5e7992SMatthew G. Knepley 166684f0b6dfSMatthew G. Knepley Input Parameters: 166720f4b53cSBarry Smith + label - the `DMLabel` 166884f0b6dfSMatthew G. Knepley - permutation - the point permutation 166984f0b6dfSMatthew G. Knepley 167084f0b6dfSMatthew G. Knepley Output Parameter: 167160225df5SJacob Faibussowitsch . labelNew - the new label containing the permuted points 167284f0b6dfSMatthew G. Knepley 167384f0b6dfSMatthew G. Knepley Level: intermediate 167484f0b6dfSMatthew G. Knepley 167520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 167684f0b6dfSMatthew G. Knepley @*/ 1677d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1678d71ae5a4SJacob Faibussowitsch { 1679c58f1c22SToby Isaac const PetscInt *perm; 1680c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1681c58f1c22SToby Isaac 1682c58f1c22SToby Isaac PetscFunctionBegin; 1683d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1684d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 16859f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 16869566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 16879566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 16889566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 16899566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 16909566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1691c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1692c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1693ad8374ffSToby Isaac const PetscInt *points; 1694ad8374ffSToby Isaac PetscInt *pointsNew; 1695c58f1c22SToby Isaac 16969566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 16979f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1(size, &pointsNew)); 1698c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1699ad8374ffSToby Isaac const PetscInt point = points[q]; 1700c58f1c22SToby Isaac 170163a3b9bcSJacob 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); 1702ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1703c58f1c22SToby Isaac } 17049566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 17059566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 17069566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1707fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 17089566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 17099566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1710fa8e8ae5SToby Isaac } else { 17119566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1712fa8e8ae5SToby Isaac } 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1714c58f1c22SToby Isaac } 17159566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1716c58f1c22SToby Isaac if (label->bt) { 17179566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 17189566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1719c58f1c22SToby Isaac } 17203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1721c58f1c22SToby Isaac } 1722c58f1c22SToby Isaac 172366976f2fSJacob Faibussowitsch static PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 1724d71ae5a4SJacob Faibussowitsch { 172526c55118SMichael Lange MPI_Comm comm; 1726eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 172726c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 172826c55118SMichael Lange PetscSection rootSection; 172926c55118SMichael Lange PetscSF labelSF; 173026c55118SMichael Lange 173126c55118SMichael Lange PetscFunctionBegin; 17329566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 17339566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 173426c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 173526c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 17369566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 17389566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 173926c55118SMichael Lange if (label) { 174026c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1741ad8374ffSToby Isaac const PetscInt *points; 1742ad8374ffSToby Isaac 17439566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 174448a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 17459566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 174626c55118SMichael Lange } 174726c55118SMichael Lange } 17489566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 174926c55118SMichael Lange /* Create a point-wise array of stratum values */ 17509566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 17519566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 17529566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 175326c55118SMichael Lange if (label) { 175426c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1755ad8374ffSToby Isaac const PetscInt *points; 1756ad8374ffSToby Isaac 17579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 175826c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1759ad8374ffSToby Isaac const PetscInt p = points[l]; 17609566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 176126c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 176226c55118SMichael Lange } 17639566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 176426c55118SMichael Lange } 176526c55118SMichael Lange } 176626c55118SMichael Lange /* Build SF that maps label points to remote processes */ 17679566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 17689566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 17699566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 17709566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 177126c55118SMichael Lange /* Send the strata for each point over the derived SF */ 17729566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 17739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 17749566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 17759566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 177626c55118SMichael Lange /* Clean up */ 17779566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 17789566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 17799566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 17809566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 17813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 178226c55118SMichael Lange } 178326c55118SMichael Lange 178484f0b6dfSMatthew G. Knepley /*@ 178520f4b53cSBarry Smith DMLabelDistribute - Create a new label pushed forward over the `PetscSF` 178684f0b6dfSMatthew G. Knepley 178720f4b53cSBarry Smith Collective 17885b5e7992SMatthew G. Knepley 178984f0b6dfSMatthew G. Knepley Input Parameters: 179020f4b53cSBarry Smith + label - the `DMLabel` 179184f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 179284f0b6dfSMatthew G. Knepley 179384f0b6dfSMatthew G. Knepley Output Parameter: 179460225df5SJacob Faibussowitsch . labelNew - the new redistributed label 179584f0b6dfSMatthew G. Knepley 179684f0b6dfSMatthew G. Knepley Level: intermediate 179784f0b6dfSMatthew G. Knepley 179820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 179984f0b6dfSMatthew G. Knepley @*/ 1800d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1801d71ae5a4SJacob Faibussowitsch { 1802c58f1c22SToby Isaac MPI_Comm comm; 180326c55118SMichael Lange PetscSection leafSection; 180426c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 180526c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1806ad8374ffSToby Isaac PetscInt **points; 1807d67d17b1SMatthew G. Knepley const char *lname = NULL; 1808c58f1c22SToby Isaac char *name; 1809c58f1c22SToby Isaac PetscInt nameSize; 1810e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1811c58f1c22SToby Isaac size_t len = 0; 181226c55118SMichael Lange PetscMPIInt rank; 1813c58f1c22SToby Isaac 1814c58f1c22SToby Isaac PetscFunctionBegin; 1815d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1816f018e600SMatthew G. Knepley if (label) { 1817f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 18189f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 18199566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1820f018e600SMatthew G. Knepley } 18219566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 18229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1823c58f1c22SToby Isaac /* Bcast name */ 1824dd400576SPatrick Sanan if (rank == 0) { 18259566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 18269566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1827d67d17b1SMatthew G. Knepley } 1828c58f1c22SToby Isaac nameSize = len; 18299566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 18309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 18319566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 18329566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 18339566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 18349566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 183577d236dfSMichael Lange /* Bcast defaultValue */ 1836dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 18379566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 183826c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 18399566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 18405cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 18419566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 18429566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 18439566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 18449566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 18459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1846ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 18479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 18485cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 18495cbdf6fcSMichael Lange offset = 0; 18509566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 18519566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 185248a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 18535cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1854231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 18559371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 18569371c9d4SSatish Balay leafStrata[p] = s; 18579371c9d4SSatish Balay break; 18589371c9d4SSatish Balay } 18595cbdf6fcSMichael Lange } 18605cbdf6fcSMichael Lange } 1861c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 18629566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 18639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1864c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18669566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1867ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1868c58f1c22SToby Isaac } 18699566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 18709f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 18719f6c5813SMatthew G. Knepley PetscCall(PetscCalloc1((*labelNew)->numStrata, &points)); 1872c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 18739566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 1874f4f49eeaSPierre Jolivet PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &points[s])); 1875c58f1c22SToby Isaac } 1876c58f1c22SToby Isaac /* Insert points into new strata */ 18779566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 18789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1879c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 18809566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 18819566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1882c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1883c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1884ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1885c58f1c22SToby Isaac } 1886c58f1c22SToby Isaac } 1887ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1888f4f49eeaSPierre Jolivet PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &points[s][0], PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 18899566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1890ad8374ffSToby Isaac } 18919566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 18929566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 18939566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 18949566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 18959566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 18963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1897c58f1c22SToby Isaac } 1898c58f1c22SToby Isaac 18997937d9ceSMichael Lange /*@ 19007937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 19017937d9ceSMichael Lange 190220f4b53cSBarry Smith Collective 19035b5e7992SMatthew G. Knepley 19047937d9ceSMichael Lange Input Parameters: 190520f4b53cSBarry Smith + label - the `DMLabel` 190620f4b53cSBarry Smith - sf - the `PetscSF` communication map 19077937d9ceSMichael Lange 19082fe279fdSBarry Smith Output Parameter: 190920f4b53cSBarry Smith . labelNew - the new `DMLabel` with localised leaf values 19107937d9ceSMichael Lange 19117937d9ceSMichael Lange Level: developer 19127937d9ceSMichael Lange 191320f4b53cSBarry Smith Note: 191420f4b53cSBarry Smith This is the inverse operation to `DMLabelDistribute()`. 19157937d9ceSMichael Lange 191620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 19177937d9ceSMichael Lange @*/ 1918d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 1919d71ae5a4SJacob Faibussowitsch { 19207937d9ceSMichael Lange MPI_Comm comm; 19217937d9ceSMichael Lange PetscSection rootSection; 19227937d9ceSMichael Lange PetscSF sfLabel; 19237937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 19247937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 19257937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 19267937d9ceSMichael Lange PetscInt *rootStrata; 1927d67d17b1SMatthew G. Knepley const char *lname; 19287937d9ceSMichael Lange char *name; 19297937d9ceSMichael Lange PetscInt nameSize; 19307937d9ceSMichael Lange size_t len = 0; 19319852e123SBarry Smith PetscMPIInt rank, size; 19327937d9ceSMichael Lange 19337937d9ceSMichael Lange PetscFunctionBegin; 1934d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1935d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 19369f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 19379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 19389566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 19399566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 19407937d9ceSMichael Lange /* Bcast name */ 1941dd400576SPatrick Sanan if (rank == 0) { 19429566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 19439566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1944d67d17b1SMatthew G. Knepley } 19457937d9ceSMichael Lange nameSize = len; 19469566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 19479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 19489566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 19499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 19509566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 19519566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 19527937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 19537937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 19547937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 19559566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 19569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1957dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 19587937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 19598212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 19608212dd46SStefano Zampini 19618212dd46SStefano Zampini leafPoints[ilp].index = ilp; 19628212dd46SStefano Zampini leafPoints[ilp].rank = rank; 19637937d9ceSMichael Lange } 19649566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 19659566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 19667937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 19679566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 19689566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 19699566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 19709566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 19719566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 19727937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 19739566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 19747937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 19757937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 19767937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 19779566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 19789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 19799566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 19807937d9ceSMichael Lange } 19817937d9ceSMichael Lange idx += rootDegree[p]; 19827937d9ceSMichael Lange } 19839566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 19849566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 19859566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 19869566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 19873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 19887937d9ceSMichael Lange } 19897937d9ceSMichael Lange 1990d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1991d71ae5a4SJacob Faibussowitsch { 1992d42890abSMatthew G. Knepley const PetscInt *degree; 1993d42890abSMatthew G. Knepley const PetscInt *points; 1994d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1995d42890abSMatthew G. Knepley 1996d42890abSMatthew G. Knepley PetscFunctionBegin; 1997d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1998d42890abSMatthew G. Knepley /* Add in leaves */ 1999d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 2000d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 2001d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 2002d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 2003d42890abSMatthew G. Knepley } 2004d42890abSMatthew G. Knepley /* Add in 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 PetscCall(DMLabelGetValue(label, r, &val)); 2010d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 2011d42890abSMatthew G. Knepley } 2012d42890abSMatthew G. Knepley } 20133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2014d42890abSMatthew G. Knepley } 2015d42890abSMatthew G. Knepley 2016d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 2017d71ae5a4SJacob Faibussowitsch { 2018d42890abSMatthew G. Knepley const PetscInt *degree; 2019d42890abSMatthew G. Knepley const PetscInt *points; 2020d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 2021d42890abSMatthew G. Knepley 2022d42890abSMatthew G. Knepley PetscFunctionBegin; 2023d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2024d42890abSMatthew G. Knepley /* Read out leaves */ 2025d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 2026d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 2027d42890abSMatthew G. Knepley const PetscInt p = points[l]; 2028d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 2029d42890abSMatthew G. Knepley 2030d42890abSMatthew G. Knepley if (cval != defVal) { 2031d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 2032d42890abSMatthew G. Knepley if (val == defVal) { 2033d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 203448a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 2035d42890abSMatthew G. Knepley } 2036d42890abSMatthew G. Knepley } 2037d42890abSMatthew G. Knepley } 2038d42890abSMatthew G. Knepley /* Read out shared roots */ 2039d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 2040d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 2041d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 2042d42890abSMatthew G. Knepley if (degree[r]) { 2043d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 2044d42890abSMatthew G. Knepley 2045d42890abSMatthew G. Knepley if (cval != defVal) { 2046d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 2047d42890abSMatthew G. Knepley if (val == defVal) { 2048d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 204948a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 2050d42890abSMatthew G. Knepley } 2051d42890abSMatthew G. Knepley } 2052d42890abSMatthew G. Knepley } 2053d42890abSMatthew G. Knepley } 20543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2055d42890abSMatthew G. Knepley } 2056d42890abSMatthew G. Knepley 2057d42890abSMatthew G. Knepley /*@ 2058d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 2059d42890abSMatthew G. Knepley 206020f4b53cSBarry Smith Collective 2061d42890abSMatthew G. Knepley 2062d42890abSMatthew G. Knepley Input Parameters: 206320f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 206420f4b53cSBarry Smith - sf - The `PetscSF` describing parallel layout of the label points 2065d42890abSMatthew G. Knepley 2066d42890abSMatthew G. Knepley Level: intermediate 2067d42890abSMatthew G. Knepley 206820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 2069d42890abSMatthew G. Knepley @*/ 2070d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 2071d71ae5a4SJacob Faibussowitsch { 2072d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 2073d42890abSMatthew G. Knepley PetscMPIInt size; 2074d42890abSMatthew G. Knepley 2075d42890abSMatthew G. Knepley PetscFunctionBegin; 20769f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2077d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 2078d42890abSMatthew G. Knepley if (size > 1) { 2079d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 2080d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 2081d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 2082d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 2083d42890abSMatthew G. Knepley } 20843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2085d42890abSMatthew G. Knepley } 2086d42890abSMatthew G. Knepley 2087d42890abSMatthew G. Knepley /*@ 2088d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 2089d42890abSMatthew G. Knepley 209020f4b53cSBarry Smith Collective 2091d42890abSMatthew G. Knepley 2092d42890abSMatthew G. Knepley Input Parameters: 209320f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 209460225df5SJacob Faibussowitsch - pointSF - The `PetscSF` describing parallel layout of the label points 2095d42890abSMatthew G. Knepley 2096d42890abSMatthew G. Knepley Level: intermediate 2097d42890abSMatthew G. Knepley 209820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 2099d42890abSMatthew G. Knepley @*/ 2100d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 2101d71ae5a4SJacob Faibussowitsch { 2102d42890abSMatthew G. Knepley PetscFunctionBegin; 21039f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2104d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 2105d42890abSMatthew G. Knepley label->propArray = NULL; 21063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2107d42890abSMatthew G. Knepley } 2108d42890abSMatthew G. Knepley 2109d42890abSMatthew G. Knepley /*@C 2110d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 2111d42890abSMatthew G. Knepley 211220f4b53cSBarry Smith Collective 2113d42890abSMatthew G. Knepley 2114d42890abSMatthew G. Knepley Input Parameters: 211520f4b53cSBarry Smith + label - The `DMLabel` to propagate across processes 2116a4e35b19SJacob Faibussowitsch . pointSF - The `PetscSF` describing parallel layout of the label points 211720f4b53cSBarry Smith . markPoint - An optional callback that is called when a point is marked, or `NULL` 211820f4b53cSBarry Smith - ctx - An optional user context for the callback, or `NULL` 2119d42890abSMatthew G. Knepley 212020f4b53cSBarry Smith Calling sequence of `markPoint`: 212120f4b53cSBarry Smith + label - The `DMLabel` 2122d42890abSMatthew G. Knepley . p - The point being marked 2123a4e35b19SJacob Faibussowitsch . val - The label value for `p` 2124d42890abSMatthew G. Knepley - ctx - An optional user context 2125d42890abSMatthew G. Knepley 2126d42890abSMatthew G. Knepley Level: intermediate 2127d42890abSMatthew G. Knepley 212820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2129d42890abSMatthew G. Knepley @*/ 2130a4e35b19SJacob Faibussowitsch PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel label, PetscInt p, PetscInt val, void *ctx), void *ctx) 2131d71ae5a4SJacob Faibussowitsch { 2132c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2133d42890abSMatthew G. Knepley PetscMPIInt size; 2134d42890abSMatthew G. Knepley 2135d42890abSMatthew G. Knepley PetscFunctionBegin; 21369f6c5813SMatthew G. Knepley PetscCheck(!label->readonly, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_WRONG, "Read-only labels cannot be altered"); 2137d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 2138c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2139c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2140d42890abSMatthew G. Knepley /* Communicate marked edges 2141d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2142d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2143d42890abSMatthew G. Knepley 2144d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2145d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2146d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2147d42890abSMatthew G. Knepley 2148d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2149d42890abSMatthew 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 2150d42890abSMatthew G. Knepley edge to the queue. 2151d42890abSMatthew G. Knepley */ 2152d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2153d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2154d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2155d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2156d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2157d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2158d42890abSMatthew G. Knepley } 21593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2160d42890abSMatthew G. Knepley } 2161d42890abSMatthew G. Knepley 216284f0b6dfSMatthew G. Knepley /*@ 216320f4b53cSBarry Smith DMLabelConvertToSection - Make a `PetscSection`/`IS` pair that encodes the label 216484f0b6dfSMatthew G. Knepley 216520f4b53cSBarry Smith Not Collective 21665b5e7992SMatthew G. Knepley 216784f0b6dfSMatthew G. Knepley Input Parameter: 216820f4b53cSBarry Smith . label - the `DMLabel` 216984f0b6dfSMatthew G. Knepley 217084f0b6dfSMatthew G. Knepley Output Parameters: 217184f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 217220f4b53cSBarry Smith - is - An `IS` containing all the label points 217384f0b6dfSMatthew G. Knepley 217484f0b6dfSMatthew G. Knepley Level: developer 217584f0b6dfSMatthew G. Knepley 217620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelDistribute()` 217784f0b6dfSMatthew G. Knepley @*/ 2178d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2179d71ae5a4SJacob Faibussowitsch { 2180c58f1c22SToby Isaac IS vIS; 2181c58f1c22SToby Isaac const PetscInt *values; 2182c58f1c22SToby Isaac PetscInt *points; 2183c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2184c58f1c22SToby Isaac 2185c58f1c22SToby Isaac PetscFunctionBegin; 2186d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 21879566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 21889566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 21899566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 21909371c9d4SSatish Balay if (nV) { 21919371c9d4SSatish Balay vS = values[0]; 21929371c9d4SSatish Balay vE = values[0] + 1; 21939371c9d4SSatish Balay } 2194c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2195c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2196c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2197c58f1c22SToby Isaac } 21989566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 21999566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2200c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2201c58f1c22SToby Isaac PetscInt n; 2202c58f1c22SToby Isaac 22039566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 22049566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2205c58f1c22SToby Isaac } 22069566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 22079566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 22089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2209c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2210c58f1c22SToby Isaac IS is; 2211c58f1c22SToby Isaac const PetscInt *spoints; 2212c58f1c22SToby Isaac PetscInt dof, off, p; 2213c58f1c22SToby Isaac 22149566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 22159566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 22169566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 22179566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2218c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 22199566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 22209566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2221c58f1c22SToby Isaac } 22229566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 22239566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 22249566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 22253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2226c58f1c22SToby Isaac } 2227c58f1c22SToby Isaac 22289f6c5813SMatthew G. Knepley /*@C 22299f6c5813SMatthew G. Knepley DMLabelRegister - Adds a new label component implementation 22309f6c5813SMatthew G. Knepley 22319f6c5813SMatthew G. Knepley Not Collective 22329f6c5813SMatthew G. Knepley 22339f6c5813SMatthew G. Knepley Input Parameters: 22349f6c5813SMatthew G. Knepley + name - The name of a new user-defined creation routine 22359f6c5813SMatthew G. Knepley - create_func - The creation routine itself 22369f6c5813SMatthew G. Knepley 22379f6c5813SMatthew G. Knepley Notes: 22389f6c5813SMatthew G. Knepley `DMLabelRegister()` may be called multiple times to add several user-defined labels 22399f6c5813SMatthew G. Knepley 224060225df5SJacob Faibussowitsch Example Usage: 22419f6c5813SMatthew G. Knepley .vb 22429f6c5813SMatthew G. Knepley DMLabelRegister("my_label", MyLabelCreate); 22439f6c5813SMatthew G. Knepley .ve 22449f6c5813SMatthew G. Knepley 22459f6c5813SMatthew G. Knepley Then, your label type can be chosen with the procedural interface via 22469f6c5813SMatthew G. Knepley .vb 22479f6c5813SMatthew G. Knepley DMLabelCreate(MPI_Comm, DMLabel *); 22489f6c5813SMatthew G. Knepley DMLabelSetType(DMLabel, "my_label"); 22499f6c5813SMatthew G. Knepley .ve 22509f6c5813SMatthew G. Knepley or at runtime via the option 22519f6c5813SMatthew G. Knepley .vb 22529f6c5813SMatthew G. Knepley -dm_label_type my_label 22539f6c5813SMatthew G. Knepley .ve 22549f6c5813SMatthew G. Knepley 22559f6c5813SMatthew G. Knepley Level: advanced 22569f6c5813SMatthew G. Knepley 225760225df5SJacob Faibussowitsch .seealso: `DMLabel`, `DM`, `DMLabelType`, `DMLabelRegisterAll()`, `DMLabelRegisterDestroy()` 22589f6c5813SMatthew G. Knepley @*/ 22599f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegister(const char name[], PetscErrorCode (*create_func)(DMLabel)) 22609f6c5813SMatthew G. Knepley { 22619f6c5813SMatthew G. Knepley PetscFunctionBegin; 22629f6c5813SMatthew G. Knepley PetscCall(DMInitializePackage()); 22639f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListAdd(&DMLabelList, name, create_func)); 22643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22659f6c5813SMatthew G. Knepley } 22669f6c5813SMatthew G. Knepley 22679f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel); 22689f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Ephemeral(DMLabel); 22699f6c5813SMatthew G. Knepley 22709f6c5813SMatthew G. Knepley /*@C 22719f6c5813SMatthew G. Knepley DMLabelRegisterAll - Registers all of the `DMLabel` implementations in the `DM` package. 22729f6c5813SMatthew G. Knepley 22739f6c5813SMatthew G. Knepley Not Collective 22749f6c5813SMatthew G. Knepley 22759f6c5813SMatthew G. Knepley Level: advanced 22769f6c5813SMatthew G. Knepley 227720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMRegisterAll()`, `DMLabelRegisterDestroy()` 22789f6c5813SMatthew G. Knepley @*/ 22799f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterAll(void) 22809f6c5813SMatthew G. Knepley { 22819f6c5813SMatthew G. Knepley PetscFunctionBegin; 22823ba16761SJacob Faibussowitsch if (DMLabelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 22839f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_TRUE; 22849f6c5813SMatthew G. Knepley 22859f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELCONCRETE, DMLabelCreate_Concrete)); 22869f6c5813SMatthew G. Knepley PetscCall(DMLabelRegister(DMLABELEPHEMERAL, DMLabelCreate_Ephemeral)); 22873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22889f6c5813SMatthew G. Knepley } 22899f6c5813SMatthew G. Knepley 22909f6c5813SMatthew G. Knepley /*@C 22919f6c5813SMatthew G. Knepley DMLabelRegisterDestroy - This function destroys the `DMLabel` registry. It is called from `PetscFinalize()`. 22929f6c5813SMatthew G. Knepley 22939f6c5813SMatthew G. Knepley Level: developer 22949f6c5813SMatthew G. Knepley 229520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscInitialize()` 22969f6c5813SMatthew G. Knepley @*/ 22979f6c5813SMatthew G. Knepley PetscErrorCode DMLabelRegisterDestroy(void) 22989f6c5813SMatthew G. Knepley { 22999f6c5813SMatthew G. Knepley PetscFunctionBegin; 23009f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMLabelList)); 23019f6c5813SMatthew G. Knepley DMLabelRegisterAllCalled = PETSC_FALSE; 23023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23039f6c5813SMatthew G. Knepley } 23049f6c5813SMatthew G. Knepley 23059f6c5813SMatthew G. Knepley /*@C 23069f6c5813SMatthew G. Knepley DMLabelSetType - Sets the particular implementation for a label. 23079f6c5813SMatthew G. Knepley 230820f4b53cSBarry Smith Collective 23099f6c5813SMatthew G. Knepley 23109f6c5813SMatthew G. Knepley Input Parameters: 23119f6c5813SMatthew G. Knepley + label - The label 23129f6c5813SMatthew G. Knepley - method - The name of the label type 23139f6c5813SMatthew G. Knepley 23149f6c5813SMatthew G. Knepley Options Database Key: 231520f4b53cSBarry Smith . -dm_label_type <type> - Sets the label type; use -help for a list of available types or see `DMLabelType` 23169f6c5813SMatthew G. Knepley 23179f6c5813SMatthew G. Knepley Level: intermediate 23189f6c5813SMatthew G. Knepley 231920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelGetType()`, `DMLabelCreate()` 23209f6c5813SMatthew G. Knepley @*/ 23219f6c5813SMatthew G. Knepley PetscErrorCode DMLabelSetType(DMLabel label, DMLabelType method) 23229f6c5813SMatthew G. Knepley { 23239f6c5813SMatthew G. Knepley PetscErrorCode (*r)(DMLabel); 23249f6c5813SMatthew G. Knepley PetscBool match; 23259f6c5813SMatthew G. Knepley 23269f6c5813SMatthew G. Knepley PetscFunctionBegin; 23279f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23289f6c5813SMatthew G. Knepley PetscCall(PetscObjectTypeCompare((PetscObject)label, method, &match)); 23293ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 23309f6c5813SMatthew G. Knepley 23319f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23329f6c5813SMatthew G. Knepley PetscCall(PetscFunctionListFind(DMLabelList, method, &r)); 23339f6c5813SMatthew G. Knepley PetscCheck(r, PetscObjectComm((PetscObject)label), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMLabel type: %s", method); 23349f6c5813SMatthew G. Knepley 23359f6c5813SMatthew G. Knepley PetscTryTypeMethod(label, destroy); 23369f6c5813SMatthew G. Knepley PetscCall(PetscMemzero(label->ops, sizeof(*label->ops))); 23379f6c5813SMatthew G. Knepley PetscCall(PetscObjectChangeTypeName((PetscObject)label, method)); 23389f6c5813SMatthew G. Knepley PetscCall((*r)(label)); 23393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23409f6c5813SMatthew G. Knepley } 23419f6c5813SMatthew G. Knepley 23429f6c5813SMatthew G. Knepley /*@C 23439f6c5813SMatthew G. Knepley DMLabelGetType - Gets the type name (as a string) from the label. 23449f6c5813SMatthew G. Knepley 23459f6c5813SMatthew G. Knepley Not Collective 23469f6c5813SMatthew G. Knepley 23479f6c5813SMatthew G. Knepley Input Parameter: 234820f4b53cSBarry Smith . label - The `DMLabel` 23499f6c5813SMatthew G. Knepley 23509f6c5813SMatthew G. Knepley Output Parameter: 235120f4b53cSBarry Smith . type - The `DMLabel` type name 23529f6c5813SMatthew G. Knepley 23539f6c5813SMatthew G. Knepley Level: intermediate 23549f6c5813SMatthew G. Knepley 235520f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `DMLabelSetType()`, `DMLabelCreate()` 23569f6c5813SMatthew G. Knepley @*/ 23579f6c5813SMatthew G. Knepley PetscErrorCode DMLabelGetType(DMLabel label, DMLabelType *type) 23589f6c5813SMatthew G. Knepley { 23599f6c5813SMatthew G. Knepley PetscFunctionBegin; 23609f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23614f572ea9SToby Isaac PetscAssertPointer(type, 2); 23629f6c5813SMatthew G. Knepley PetscCall(DMLabelRegisterAll()); 23639f6c5813SMatthew G. Knepley *type = ((PetscObject)label)->type_name; 23643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23659f6c5813SMatthew G. Knepley } 23669f6c5813SMatthew G. Knepley 23679f6c5813SMatthew G. Knepley static PetscErrorCode DMLabelInitialize_Concrete(DMLabel label) 23689f6c5813SMatthew G. Knepley { 23699f6c5813SMatthew G. Knepley PetscFunctionBegin; 23709f6c5813SMatthew G. Knepley label->ops->view = DMLabelView_Concrete; 23719f6c5813SMatthew G. Knepley label->ops->setup = NULL; 23729f6c5813SMatthew G. Knepley label->ops->duplicate = DMLabelDuplicate_Concrete; 23739f6c5813SMatthew G. Knepley label->ops->getstratumis = DMLabelGetStratumIS_Concrete; 23743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23759f6c5813SMatthew G. Knepley } 23769f6c5813SMatthew G. Knepley 23779f6c5813SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMLabelCreate_Concrete(DMLabel label) 23789f6c5813SMatthew G. Knepley { 23799f6c5813SMatthew G. Knepley PetscFunctionBegin; 23809f6c5813SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 23819f6c5813SMatthew G. Knepley PetscCall(DMLabelInitialize_Concrete(label)); 23823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23839f6c5813SMatthew G. Knepley } 23849f6c5813SMatthew G. Knepley 238584f0b6dfSMatthew G. Knepley /*@ 2386c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 238720f4b53cSBarry Smith the local section and an `PetscSF` describing the section point overlap. 2388c58f1c22SToby Isaac 238920f4b53cSBarry Smith Collective 23905b5e7992SMatthew G. Knepley 2391c58f1c22SToby Isaac Input Parameters: 239220f4b53cSBarry Smith + s - The `PetscSection` for the local field layout 239320f4b53cSBarry Smith . sf - The `PetscSF` describing parallel layout of the section points 239420f4b53cSBarry Smith . includeConstraints - By default this is `PETSC_FALSE`, meaning that the global field vector will not possess constrained dofs 2395c58f1c22SToby Isaac . label - The label specifying the points 2396c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2397c58f1c22SToby Isaac 2398c58f1c22SToby Isaac Output Parameter: 239920f4b53cSBarry Smith . gsection - The `PetscSection` for the global field layout 2400c58f1c22SToby Isaac 2401c58f1c22SToby Isaac Level: developer 2402c58f1c22SToby Isaac 240320f4b53cSBarry Smith Note: 240420f4b53cSBarry Smith This gives negative sizes and offsets to points not owned by this process 240520f4b53cSBarry Smith 240620f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionCreate()` 2407c58f1c22SToby Isaac @*/ 2408d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2409d71ae5a4SJacob Faibussowitsch { 2410c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2411c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2412c58f1c22SToby Isaac 2413c58f1c22SToby Isaac PetscFunctionBegin; 2414d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2415d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2416d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 24179566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 24189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 24199566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 24209566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2421c58f1c22SToby Isaac if (nroots >= 0) { 242263a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 24239566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2424c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24259566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2426c58f1c22SToby Isaac } else { 2427c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2428c58f1c22SToby Isaac } 2429c58f1c22SToby Isaac } 2430c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2431c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2432c58f1c22SToby Isaac PetscInt value; 2433c58f1c22SToby Isaac 24349566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2435c58f1c22SToby Isaac if (value != labelValue) continue; 24369566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 24379566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 24389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 24399566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2440c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2441c58f1c22SToby Isaac } 24429566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2443c58f1c22SToby Isaac if (nroots >= 0) { 24449566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24459566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2446c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24479371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24489371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 24499371c9d4SSatish Balay } 2450c58f1c22SToby Isaac } 2451c58f1c22SToby Isaac } 245235cb6cd3SPierre Jolivet /* Calculate new sizes, get process offset, and calculate point offsets */ 2453c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2454c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2455c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2456c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2457c58f1c22SToby Isaac } 24589566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2459c58f1c22SToby Isaac globalOff -= off; 2460c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2461c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2462c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2463c58f1c22SToby Isaac } 2464c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2465c58f1c22SToby Isaac if (nroots >= 0) { 24669566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 24679566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2468c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 24699371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 24709371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 24719371c9d4SSatish Balay } 2472c58f1c22SToby Isaac } 2473c58f1c22SToby Isaac } 24749566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 24759566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 24763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2477c58f1c22SToby Isaac } 2478c58f1c22SToby Isaac 24799371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 24805fdea053SToby Isaac DMLabel label; 24815fdea053SToby Isaac PetscCopyMode *modes; 24825fdea053SToby Isaac PetscInt *sizes; 24835fdea053SToby Isaac const PetscInt ***perms; 24845fdea053SToby Isaac const PetscScalar ***rots; 24855fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 24865fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 24875fdea053SToby Isaac } PetscSectionSym_Label; 24885fdea053SToby Isaac 2489d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 2490d71ae5a4SJacob Faibussowitsch { 24915fdea053SToby Isaac PetscInt i, j; 24925fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 24935fdea053SToby Isaac 24945fdea053SToby Isaac PetscFunctionBegin; 24955fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24965fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 24975fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 24989566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 24999566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 25005fdea053SToby Isaac } 25015fdea053SToby Isaac if (sl->perms[i]) { 25025fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 25035fdea053SToby Isaac 25049566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 25055fdea053SToby Isaac } 25065fdea053SToby Isaac if (sl->rots[i]) { 25075fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 25085fdea053SToby Isaac 25099566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 25105fdea053SToby Isaac } 25115fdea053SToby Isaac } 25125fdea053SToby Isaac } 25139566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 25149566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 25155fdea053SToby Isaac sl->numStrata = 0; 25163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25175fdea053SToby Isaac } 25185fdea053SToby Isaac 2519d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 2520d71ae5a4SJacob Faibussowitsch { 25215fdea053SToby Isaac PetscFunctionBegin; 25229566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 25239566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 25243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25255fdea053SToby Isaac } 25265fdea053SToby Isaac 2527d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 2528d71ae5a4SJacob Faibussowitsch { 25295fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 25305fdea053SToby Isaac PetscBool isAscii; 25315fdea053SToby Isaac DMLabel label = sl->label; 2532d67d17b1SMatthew G. Knepley const char *name; 25335fdea053SToby Isaac 25345fdea053SToby Isaac PetscFunctionBegin; 25359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 25365fdea053SToby Isaac if (isAscii) { 25375fdea053SToby Isaac PetscInt i, j, k; 25385fdea053SToby Isaac PetscViewerFormat format; 25395fdea053SToby Isaac 25409566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25415fdea053SToby Isaac if (label) { 25429566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 25435fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25459566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 25469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25475fdea053SToby Isaac } else { 25489566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 25499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 25505fdea053SToby Isaac } 25515fdea053SToby Isaac } else { 25529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 25535fdea053SToby Isaac } 25549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25555fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 25565fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 25575fdea053SToby Isaac 25585fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 255963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 25605fdea053SToby Isaac } else { 256163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 25629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 256363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 25645fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 25659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25665fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 25675fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 256863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 25695fdea053SToby Isaac } else { 25705fdea053SToby Isaac PetscInt tab; 25715fdea053SToby Isaac 257263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 25739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 25749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 25755fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 25769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 25779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 257863a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 25799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25815fdea053SToby Isaac } 25825fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 25839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 25849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 25855fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 258663a3b9bcSJacob 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]))); 25875fdea053SToby Isaac #else 258863a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 25895fdea053SToby Isaac #endif 25909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 25919566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 25925fdea053SToby Isaac } 25939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25945fdea053SToby Isaac } 25955fdea053SToby Isaac } 25969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25975fdea053SToby Isaac } 25989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 25995fdea053SToby Isaac } 26005fdea053SToby Isaac } 26019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 26025fdea053SToby Isaac } 26033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26045fdea053SToby Isaac } 26055fdea053SToby Isaac 26065fdea053SToby Isaac /*@ 26075fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 26085fdea053SToby Isaac 260920f4b53cSBarry Smith Logically 26105fdea053SToby Isaac 261160225df5SJacob Faibussowitsch Input Parameters: 26125fdea053SToby Isaac + sym - the section symmetries 261320f4b53cSBarry Smith - label - the `DMLabel` describing the types of points 26145fdea053SToby Isaac 26155fdea053SToby Isaac Level: developer: 26165fdea053SToby Isaac 261720f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 26185fdea053SToby Isaac @*/ 2619d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 2620d71ae5a4SJacob Faibussowitsch { 26215fdea053SToby Isaac PetscSectionSym_Label *sl; 26225fdea053SToby Isaac 26235fdea053SToby Isaac PetscFunctionBegin; 26245fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 26255fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 26269566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 26275fdea053SToby Isaac if (label) { 26285fdea053SToby Isaac sl->label = label; 26299566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 26309566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 26319566063dSJacob 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)); 26329566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 26339566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 26349566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 26359566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 26369566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 26375fdea053SToby Isaac } 26383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26395fdea053SToby Isaac } 26405fdea053SToby Isaac 26415fdea053SToby Isaac /*@C 2642b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2643b004864fSMatthew G. Knepley 264420f4b53cSBarry Smith Logically Collective 2645b004864fSMatthew G. Knepley 2646b004864fSMatthew G. Knepley Input Parameters: 2647b004864fSMatthew G. Knepley + sym - the section symmetries 2648b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2649b004864fSMatthew G. Knepley 2650b004864fSMatthew G. Knepley Output Parameters: 265120f4b53cSBarry Smith + size - the number of dofs for points in the `stratum` of the label 265220f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 265320f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a ppoint in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 265420f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 265520f4b53cSBarry 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 2656b004864fSMatthew G. Knepley 2657b004864fSMatthew G. Knepley Level: developer 2658b004864fSMatthew G. Knepley 265920f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2660b004864fSMatthew G. Knepley @*/ 2661d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2662d71ae5a4SJacob Faibussowitsch { 2663b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2664b004864fSMatthew G. Knepley const char *name; 2665b004864fSMatthew G. Knepley PetscInt i; 2666b004864fSMatthew G. Knepley 2667b004864fSMatthew G. Knepley PetscFunctionBegin; 2668b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2669b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2670b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2671b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2672b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2673b004864fSMatthew G. Knepley 2674b004864fSMatthew G. Knepley if (stratum == value) break; 2675b004864fSMatthew G. Knepley } 26769566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2677b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 26789371c9d4SSatish Balay if (size) { 26794f572ea9SToby Isaac PetscAssertPointer(size, 3); 26809371c9d4SSatish Balay *size = sl->sizes[i]; 26819371c9d4SSatish Balay } 26829371c9d4SSatish Balay if (minOrient) { 26834f572ea9SToby Isaac PetscAssertPointer(minOrient, 4); 26849371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 26859371c9d4SSatish Balay } 26869371c9d4SSatish Balay if (maxOrient) { 26874f572ea9SToby Isaac PetscAssertPointer(maxOrient, 5); 26889371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 26899371c9d4SSatish Balay } 26909371c9d4SSatish Balay if (perms) { 26914f572ea9SToby Isaac PetscAssertPointer(perms, 6); 26928e3a54c0SPierre Jolivet *perms = PetscSafePointerPlusOffset(sl->perms[i], sl->minMaxOrients[i][0]); 26939371c9d4SSatish Balay } 26949371c9d4SSatish Balay if (rots) { 26954f572ea9SToby Isaac PetscAssertPointer(rots, 7); 26968e3a54c0SPierre Jolivet *rots = PetscSafePointerPlusOffset(sl->rots[i], sl->minMaxOrients[i][0]); 26979371c9d4SSatish Balay } 26983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2699b004864fSMatthew G. Knepley } 2700b004864fSMatthew G. Knepley 2701b004864fSMatthew G. Knepley /*@C 27025fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 27035fdea053SToby Isaac 270420f4b53cSBarry Smith Logically 27055fdea053SToby Isaac 27065fdea053SToby Isaac Input Parameters: 27075b5e7992SMatthew G. Knepley + sym - the section symmetries 27085fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 270920f4b53cSBarry Smith . size - the number of dofs for points in the `stratum` of the label 271020f4b53cSBarry Smith . minOrient - the smallest orientation for a point in this `stratum` 271120f4b53cSBarry Smith . maxOrient - one greater than the largest orientation for a point in this `stratum` (i.e., orientations are in the range [`minOrient`, `maxOrient`)) 271220f4b53cSBarry Smith . mode - how `sym` should copy the `perms` and `rots` arrays 271320f4b53cSBarry Smith . perms - `NULL` if there are no permutations, or (`maxOrient` - `minOrient`) permutations, one for each orientation. A `NULL` permutation is the identity 271420f4b53cSBarry 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 27155fdea053SToby Isaac 27165fdea053SToby Isaac Level: developer 27175fdea053SToby Isaac 271820f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 27195fdea053SToby Isaac @*/ 2720d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 2721d71ae5a4SJacob Faibussowitsch { 27225fdea053SToby Isaac PetscSectionSym_Label *sl; 2723d67d17b1SMatthew G. Knepley const char *name; 2724d67d17b1SMatthew G. Knepley PetscInt i, j, k; 27255fdea053SToby Isaac 27265fdea053SToby Isaac PetscFunctionBegin; 27275fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 27285fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2729b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 27305fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 27315fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 27325fdea053SToby Isaac 27335fdea053SToby Isaac if (stratum == value) break; 27345fdea053SToby Isaac } 27359566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 273663a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 27375fdea053SToby Isaac sl->sizes[i] = size; 27385fdea053SToby Isaac sl->modes[i] = mode; 27395fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 27405fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 27415fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 27425fdea053SToby Isaac if (perms) { 27435fdea053SToby Isaac PetscInt **ownPerms; 27445fdea053SToby Isaac 27459566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 27465fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27475fdea053SToby Isaac if (perms[j]) { 27489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2749ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 27505fdea053SToby Isaac } 27515fdea053SToby Isaac } 27525fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 27535fdea053SToby Isaac } 27545fdea053SToby Isaac if (rots) { 27555fdea053SToby Isaac PetscScalar **ownRots; 27565fdea053SToby Isaac 27579566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 27585fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 27595fdea053SToby Isaac if (rots[j]) { 27609566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2761ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 27625fdea053SToby Isaac } 27635fdea053SToby Isaac } 27645fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 27655fdea053SToby Isaac } 27665fdea053SToby Isaac } else { 27678e3a54c0SPierre Jolivet sl->perms[i] = PetscSafePointerPlusOffset(perms, -minOrient); 27688e3a54c0SPierre Jolivet sl->rots[i] = PetscSafePointerPlusOffset(rots, -minOrient); 27695fdea053SToby Isaac } 27703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27715fdea053SToby Isaac } 27725fdea053SToby Isaac 2773d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 2774d71ae5a4SJacob Faibussowitsch { 27755fdea053SToby Isaac PetscInt i, j, numStrata; 27765fdea053SToby Isaac PetscSectionSym_Label *sl; 27775fdea053SToby Isaac DMLabel label; 27785fdea053SToby Isaac 27795fdea053SToby Isaac PetscFunctionBegin; 27805fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 27815fdea053SToby Isaac numStrata = sl->numStrata; 27825fdea053SToby Isaac label = sl->label; 27835fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 27845fdea053SToby Isaac PetscInt point = points[2 * i]; 27855fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 27865fdea053SToby Isaac 27875fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 27885fdea053SToby Isaac if (label->validIS[j]) { 27895fdea053SToby Isaac PetscInt k; 27905fdea053SToby Isaac 27919566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j], point, &k)); 27925fdea053SToby Isaac if (k >= 0) break; 27935fdea053SToby Isaac } else { 27945fdea053SToby Isaac PetscBool has; 27955fdea053SToby Isaac 27969566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 27975fdea053SToby Isaac if (has) break; 27985fdea053SToby Isaac } 27995fdea053SToby Isaac } 28009371c9d4SSatish 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], 28019371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2802ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2803ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 28045fdea053SToby Isaac } 28053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28065fdea053SToby Isaac } 28075fdea053SToby Isaac 2808d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2809d71ae5a4SJacob Faibussowitsch { 2810b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2811b004864fSMatthew G. Knepley IS valIS; 2812b004864fSMatthew G. Knepley const PetscInt *values; 2813b004864fSMatthew G. Knepley PetscInt Nv, v; 2814b004864fSMatthew G. Knepley 2815b004864fSMatthew G. Knepley PetscFunctionBegin; 28169566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 28179566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 28189566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2819b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2820b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2821b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2822b004864fSMatthew G. Knepley const PetscInt **perms; 2823b004864fSMatthew G. Knepley const PetscScalar **rots; 2824b004864fSMatthew G. Knepley 28259566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 28269566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2827b004864fSMatthew G. Knepley } 28289566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 28293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2830b004864fSMatthew G. Knepley } 2831b004864fSMatthew G. Knepley 2832d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2833d71ae5a4SJacob Faibussowitsch { 2834b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2835b004864fSMatthew G. Knepley DMLabel dlabel; 2836b004864fSMatthew G. Knepley 2837b004864fSMatthew G. Knepley PetscFunctionBegin; 28389566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 28399566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 28409566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 28419566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 28423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2843b004864fSMatthew G. Knepley } 2844b004864fSMatthew G. Knepley 2845d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 2846d71ae5a4SJacob Faibussowitsch { 28475fdea053SToby Isaac PetscSectionSym_Label *sl; 28485fdea053SToby Isaac 28495fdea053SToby Isaac PetscFunctionBegin; 28504dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 28515fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2852b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2853b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 28545fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 28555fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 28565fdea053SToby Isaac sym->data = (void *)sl; 28573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28585fdea053SToby Isaac } 28595fdea053SToby Isaac 28605fdea053SToby Isaac /*@ 28615fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 28625fdea053SToby Isaac 28635fdea053SToby Isaac Collective 28645fdea053SToby Isaac 28655fdea053SToby Isaac Input Parameters: 28665fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 28675fdea053SToby Isaac - label - the label defining the strata 28685fdea053SToby Isaac 28692fe279fdSBarry Smith Output Parameter: 28705fdea053SToby Isaac . sym - the section symmetries 28715fdea053SToby Isaac 28725fdea053SToby Isaac Level: developer 28735fdea053SToby Isaac 287420f4b53cSBarry Smith .seealso: `DMLabel`, `DM`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 28755fdea053SToby Isaac @*/ 2876d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 2877d71ae5a4SJacob Faibussowitsch { 28785fdea053SToby Isaac PetscFunctionBegin; 28799566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 28809566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 28819566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 28829566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 28833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28845fdea053SToby Isaac } 2885