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 7c58f1c22SToby Isaac /*@C 8c58f1c22SToby Isaac DMLabelCreate - Create a DMLabel object, which is a multimap 9c58f1c22SToby Isaac 105b5e7992SMatthew G. Knepley Collective 115b5e7992SMatthew G. Knepley 12d67d17b1SMatthew G. Knepley Input parameters: 13d67d17b1SMatthew G. Knepley + comm - The communicator, usually PETSC_COMM_SELF 14d67d17b1SMatthew G. Knepley - name - The label name 15c58f1c22SToby Isaac 16c58f1c22SToby Isaac Output parameter: 17c58f1c22SToby Isaac . label - The DMLabel 18c58f1c22SToby Isaac 19c58f1c22SToby Isaac Level: beginner 20c58f1c22SToby Isaac 2105ab7a9fSVaclav Hapla Notes: 2205ab7a9fSVaclav Hapla The label name is actually usual PetscObject name. 2305ab7a9fSVaclav Hapla One can get/set it with PetscObjectGetName()/PetscObjectSetName(). 2405ab7a9fSVaclav Hapla 25db781477SPatrick Sanan .seealso: `DMLabelDestroy()` 26c58f1c22SToby Isaac @*/ 27d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreate(MPI_Comm comm, const char name[], DMLabel *label) 28d71ae5a4SJacob Faibussowitsch { 29c58f1c22SToby Isaac PetscFunctionBegin; 30064a246eSJacob Faibussowitsch PetscValidPointer(label, 3); 319566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 32c58f1c22SToby Isaac 339566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(*label, DMLABEL_CLASSID, "DMLabel", "DMLabel", "DM", comm, DMLabelDestroy, DMLabelView)); 34d67d17b1SMatthew G. Knepley 35c58f1c22SToby Isaac (*label)->numStrata = 0; 365aa44df4SToby Isaac (*label)->defaultValue = -1; 37c58f1c22SToby Isaac (*label)->stratumValues = NULL; 38ad8374ffSToby Isaac (*label)->validIS = NULL; 39c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 40c58f1c22SToby Isaac (*label)->points = NULL; 41c58f1c22SToby Isaac (*label)->ht = NULL; 42c58f1c22SToby Isaac (*label)->pStart = -1; 43c58f1c22SToby Isaac (*label)->pEnd = -1; 44c58f1c22SToby Isaac (*label)->bt = NULL; 459566063dSJacob Faibussowitsch PetscCall(PetscHMapICreate(&(*label)->hmap)); 469566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*label, name)); 47c58f1c22SToby Isaac PetscFunctionReturn(0); 48c58f1c22SToby Isaac } 49c58f1c22SToby Isaac 50c58f1c22SToby Isaac /* 51c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 52c58f1c22SToby Isaac 535b5e7992SMatthew G. Knepley Not collective 545b5e7992SMatthew G. Knepley 55c58f1c22SToby Isaac Input parameter: 56c58f1c22SToby Isaac + label - The DMLabel 57c58f1c22SToby Isaac - v - The stratum value 58c58f1c22SToby Isaac 59c58f1c22SToby Isaac Output parameter: 60c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format 61c58f1c22SToby Isaac 62c58f1c22SToby Isaac Level: developer 63c58f1c22SToby Isaac 64db781477SPatrick Sanan .seealso: `DMLabelCreate()` 65c58f1c22SToby Isaac */ 66d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) 67d71ae5a4SJacob Faibussowitsch { 68277ea44aSLisandro Dalcin IS is; 69b9907514SLisandro Dalcin PetscInt off = 0, *pointArray, p; 70c58f1c22SToby Isaac 71b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) return 0; 72c58f1c22SToby Isaac PetscFunctionBegin; 731dca8a05SBarry 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); 749566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v])); 759566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->stratumSizes[v], &pointArray)); 769566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(label->ht[v], &off, pointArray)); 779566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 789566063dSJacob Faibussowitsch PetscCall(PetscSortInt(label->stratumSizes[v], pointArray)); 79c58f1c22SToby Isaac if (label->bt) { 80c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 81ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 8263a3b9bcSJacob 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); 839566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 84c58f1c22SToby Isaac } 85c58f1c22SToby Isaac } 86ba2698f1SMatthew G. Knepley if (label->stratumSizes[v] > 0 && pointArray[label->stratumSizes[v] - 1] == pointArray[0] + label->stratumSizes[v] - 1) { 879566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, label->stratumSizes[v], pointArray[0], 1, &is)); 889566063dSJacob Faibussowitsch PetscCall(PetscFree(pointArray)); 89ba2698f1SMatthew G. Knepley } else { 909566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is)); 91ba2698f1SMatthew G. Knepley } 929566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)is, "indices")); 93277ea44aSLisandro Dalcin label->points[v] = is; 94ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 959566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 96c58f1c22SToby Isaac PetscFunctionReturn(0); 97c58f1c22SToby Isaac } 98c58f1c22SToby Isaac 99c58f1c22SToby Isaac /* 100c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 101c58f1c22SToby Isaac 1025b5e7992SMatthew G. Knepley Not collective 1035b5e7992SMatthew G. Knepley 104c58f1c22SToby Isaac Input parameter: 105c58f1c22SToby Isaac . label - The DMLabel 106c58f1c22SToby Isaac 107c58f1c22SToby Isaac Output parameter: 108c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format 109c58f1c22SToby Isaac 110c58f1c22SToby Isaac Level: developer 111c58f1c22SToby Isaac 112db781477SPatrick Sanan .seealso: `DMLabelCreate()` 113c58f1c22SToby Isaac */ 114d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 115d71ae5a4SJacob Faibussowitsch { 116c58f1c22SToby Isaac PetscInt v; 117c58f1c22SToby Isaac 118c58f1c22SToby Isaac PetscFunctionBegin; 11948a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeValid_Private(label, v)); 120c58f1c22SToby Isaac PetscFunctionReturn(0); 121c58f1c22SToby Isaac } 122c58f1c22SToby Isaac 123c58f1c22SToby Isaac /* 124c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 125c58f1c22SToby Isaac 1265b5e7992SMatthew G. Knepley Not collective 1275b5e7992SMatthew G. Knepley 128c58f1c22SToby Isaac Input parameter: 129c58f1c22SToby Isaac + label - The DMLabel 130c58f1c22SToby Isaac - v - The stratum value 131c58f1c22SToby Isaac 132c58f1c22SToby Isaac Output parameter: 133c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format 134c58f1c22SToby Isaac 135c58f1c22SToby Isaac Level: developer 136c58f1c22SToby Isaac 137db781477SPatrick Sanan .seealso: `DMLabelCreate()` 138c58f1c22SToby Isaac */ 139d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 140d71ae5a4SJacob Faibussowitsch { 141c58f1c22SToby Isaac PetscInt p; 142ad8374ffSToby Isaac const PetscInt *points; 143c58f1c22SToby Isaac 144b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) return 0; 145c58f1c22SToby Isaac PetscFunctionBegin; 1461dca8a05SBarry 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); 147ad8374ffSToby Isaac if (label->points[v]) { 1489566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 14948a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 1509566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1519566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 152ad8374ffSToby Isaac } 153ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 154c58f1c22SToby Isaac PetscFunctionReturn(0); 155c58f1c22SToby Isaac } 156c58f1c22SToby Isaac 157d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelMakeAllInvalid_Internal(DMLabel label) 158d71ae5a4SJacob Faibussowitsch { 159695799ffSMatthew G. Knepley PetscInt v; 160695799ffSMatthew G. Knepley 161695799ffSMatthew G. Knepley PetscFunctionBegin; 16248a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeInvalid_Private(label, v)); 163695799ffSMatthew G. Knepley PetscFunctionReturn(0); 164695799ffSMatthew G. Knepley } 165695799ffSMatthew G. Knepley 166b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 167b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 168b9907514SLisandro Dalcin #endif 169b9907514SLisandro Dalcin 170d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 171d71ae5a4SJacob Faibussowitsch { 1720c3c4a36SLisandro Dalcin PetscInt v; 1730e79e033SBarry Smith 1740c3c4a36SLisandro Dalcin PetscFunctionBegin; 1750e79e033SBarry Smith *index = -1; 176b9907514SLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 177b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 1789371c9d4SSatish Balay if (label->stratumValues[v] == value) { 1799371c9d4SSatish Balay *index = v; 1809371c9d4SSatish Balay break; 1819371c9d4SSatish Balay } 182b9907514SLisandro Dalcin } else { 1839566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index)); 1840e79e033SBarry Smith } 18576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* Check strata hash map consistency */ 18690e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 1879566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len)); 18808401ef6SPierre Jolivet PetscCheck(len == label->numStrata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 18990e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 1909566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc)); 19190e9b2aeSLisandro Dalcin } else { 19290e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 1939371c9d4SSatish Balay if (label->stratumValues[v] == value) { 1949371c9d4SSatish Balay loc = v; 1959371c9d4SSatish Balay break; 1969371c9d4SSatish Balay } 19790e9b2aeSLisandro Dalcin } 19808401ef6SPierre Jolivet PetscCheck(loc == *index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 19990e9b2aeSLisandro Dalcin } 2000c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 2010c3c4a36SLisandro Dalcin } 2020c3c4a36SLisandro Dalcin 203d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 204d71ae5a4SJacob Faibussowitsch { 205b9907514SLisandro Dalcin PetscInt v; 206b9907514SLisandro Dalcin PetscInt *tmpV; 207b9907514SLisandro Dalcin PetscInt *tmpS; 208b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 209b9907514SLisandro Dalcin IS *tmpP, is; 210c58f1c22SToby Isaac PetscBool *tmpB; 211b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 212c58f1c22SToby Isaac 213c58f1c22SToby Isaac PetscFunctionBegin; 214b9907514SLisandro Dalcin v = label->numStrata; 215b9907514SLisandro Dalcin tmpV = label->stratumValues; 216b9907514SLisandro Dalcin tmpS = label->stratumSizes; 217b9907514SLisandro Dalcin tmpH = label->ht; 218b9907514SLisandro Dalcin tmpP = label->points; 219b9907514SLisandro Dalcin tmpB = label->validIS; 2208e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2218e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2228e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2238e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2248e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2258e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2269566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpV), &tmpV)); 2279566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpS), &tmpS)); 2289566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpH), &tmpH)); 2299566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpP), &tmpP)); 2309566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpB), &tmpB)); 2319566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v)); 2329566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v)); 2339566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v)); 2349566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v)); 2359566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v)); 2369566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV)); 2379566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS)); 2389566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH)); 2399566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP)); 2409566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB)); 2418e1f8cf0SLisandro Dalcin } 242b9907514SLisandro Dalcin label->numStrata = v + 1; 243c58f1c22SToby Isaac label->stratumValues = tmpV; 244c58f1c22SToby Isaac label->stratumSizes = tmpS; 245c58f1c22SToby Isaac label->ht = tmpH; 246c58f1c22SToby Isaac label->points = tmpP; 247ad8374ffSToby Isaac label->validIS = tmpB; 2489566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 2499566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 2509566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v)); 251b9907514SLisandro Dalcin tmpV[v] = value; 252b9907514SLisandro Dalcin tmpS[v] = 0; 253b9907514SLisandro Dalcin tmpH[v] = ht; 254b9907514SLisandro Dalcin tmpP[v] = is; 255b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 2569566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 2570c3c4a36SLisandro Dalcin *index = v; 2580c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 2590c3c4a36SLisandro Dalcin } 2600c3c4a36SLisandro Dalcin 261d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 262d71ae5a4SJacob Faibussowitsch { 263b9907514SLisandro Dalcin PetscFunctionBegin; 2649566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index)); 2659566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index)); 266b9907514SLisandro Dalcin PetscFunctionReturn(0); 267b9907514SLisandro Dalcin } 268b9907514SLisandro Dalcin 269d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) 270d71ae5a4SJacob Faibussowitsch { 2719e63cc69SVaclav Hapla PetscFunctionBegin; 2729e63cc69SVaclav Hapla *size = 0; 2739e63cc69SVaclav Hapla if (v < 0) PetscFunctionReturn(0); 2749e63cc69SVaclav Hapla if (label->validIS[v]) { 2759e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 2769e63cc69SVaclav Hapla } else { 2779566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size)); 2789e63cc69SVaclav Hapla } 2799e63cc69SVaclav Hapla PetscFunctionReturn(0); 2809e63cc69SVaclav Hapla } 2819e63cc69SVaclav Hapla 282b9907514SLisandro Dalcin /*@ 283b9907514SLisandro Dalcin DMLabelAddStratum - Adds a new stratum value in a DMLabel 284b9907514SLisandro Dalcin 285d8d19677SJose E. Roman Input Parameters: 286b9907514SLisandro Dalcin + label - The DMLabel 287b9907514SLisandro Dalcin - value - The stratum value 288b9907514SLisandro Dalcin 289b9907514SLisandro Dalcin Level: beginner 290b9907514SLisandro Dalcin 291db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 292b9907514SLisandro Dalcin @*/ 293d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 294d71ae5a4SJacob Faibussowitsch { 2950c3c4a36SLisandro Dalcin PetscInt v; 2960c3c4a36SLisandro Dalcin 2970c3c4a36SLisandro Dalcin PetscFunctionBegin; 298d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 2999566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 300b9907514SLisandro Dalcin PetscFunctionReturn(0); 301b9907514SLisandro Dalcin } 302b9907514SLisandro Dalcin 303b9907514SLisandro Dalcin /*@ 304b9907514SLisandro Dalcin DMLabelAddStrata - Adds new stratum values in a DMLabel 305b9907514SLisandro Dalcin 3065b5e7992SMatthew G. Knepley Not collective 3075b5e7992SMatthew G. Knepley 308d8d19677SJose E. Roman Input Parameters: 309b9907514SLisandro Dalcin + label - The DMLabel 310b9907514SLisandro Dalcin . numStrata - The number of stratum values 311b9907514SLisandro Dalcin - stratumValues - The stratum values 312b9907514SLisandro Dalcin 313b9907514SLisandro Dalcin Level: beginner 314b9907514SLisandro Dalcin 315db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 316b9907514SLisandro Dalcin @*/ 317d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 318d71ae5a4SJacob Faibussowitsch { 319b9907514SLisandro Dalcin PetscInt *values, v; 320b9907514SLisandro Dalcin 321b9907514SLisandro Dalcin PetscFunctionBegin; 322b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 323b9907514SLisandro Dalcin if (numStrata) PetscValidIntPointer(stratumValues, 3); 3249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &values)); 3259566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(values, stratumValues, numStrata)); 3269566063dSJacob Faibussowitsch PetscCall(PetscSortRemoveDupsInt(&numStrata, values)); 327b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 328b9907514SLisandro Dalcin PetscInt *tmpV; 329b9907514SLisandro Dalcin PetscInt *tmpS; 330b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 331b9907514SLisandro Dalcin IS *tmpP, is; 332b9907514SLisandro Dalcin PetscBool *tmpB; 333b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 334b9907514SLisandro Dalcin 3359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpV)); 3369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpS)); 3379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpH)); 3389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpP)); 3399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpB)); 340b9907514SLisandro Dalcin label->numStrata = numStrata; 341b9907514SLisandro Dalcin label->stratumValues = tmpV; 342b9907514SLisandro Dalcin label->stratumSizes = tmpS; 343b9907514SLisandro Dalcin label->ht = tmpH; 344b9907514SLisandro Dalcin label->points = tmpP; 345b9907514SLisandro Dalcin label->validIS = tmpB; 346b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 3479566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 3489566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 3499566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, values[v], v)); 350b9907514SLisandro Dalcin tmpV[v] = values[v]; 351b9907514SLisandro Dalcin tmpS[v] = 0; 352b9907514SLisandro Dalcin tmpH[v] = ht; 353b9907514SLisandro Dalcin tmpP[v] = is; 354b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 355b9907514SLisandro Dalcin } 3569566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 357b9907514SLisandro Dalcin } else { 35848a46eb9SPierre Jolivet for (v = 0; v < numStrata; ++v) PetscCall(DMLabelAddStratum(label, values[v])); 359b9907514SLisandro Dalcin } 3609566063dSJacob Faibussowitsch PetscCall(PetscFree(values)); 361b9907514SLisandro Dalcin PetscFunctionReturn(0); 362b9907514SLisandro Dalcin } 363b9907514SLisandro Dalcin 364b9907514SLisandro Dalcin /*@ 365b9907514SLisandro Dalcin DMLabelAddStrataIS - Adds new stratum values in a DMLabel 366b9907514SLisandro Dalcin 3675b5e7992SMatthew G. Knepley Not collective 3685b5e7992SMatthew G. Knepley 369d8d19677SJose E. Roman Input Parameters: 370b9907514SLisandro Dalcin + label - The DMLabel 371b9907514SLisandro Dalcin - valueIS - Index set with stratum values 372b9907514SLisandro Dalcin 373b9907514SLisandro Dalcin Level: beginner 374b9907514SLisandro Dalcin 375db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 376b9907514SLisandro Dalcin @*/ 377d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 378d71ae5a4SJacob Faibussowitsch { 379b9907514SLisandro Dalcin PetscInt numStrata; 380b9907514SLisandro Dalcin const PetscInt *stratumValues; 381b9907514SLisandro Dalcin 382b9907514SLisandro Dalcin PetscFunctionBegin; 383b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 384b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 3859566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata)); 3869566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues)); 3879566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues)); 388c58f1c22SToby Isaac PetscFunctionReturn(0); 389c58f1c22SToby Isaac } 390c58f1c22SToby Isaac 391d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) 392d71ae5a4SJacob Faibussowitsch { 393c58f1c22SToby Isaac PetscInt v; 394c58f1c22SToby Isaac PetscMPIInt rank; 395c58f1c22SToby Isaac 396c58f1c22SToby Isaac PetscFunctionBegin; 3979566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 3989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 399c58f1c22SToby Isaac if (label) { 400d67d17b1SMatthew G. Knepley const char *name; 401d67d17b1SMatthew G. Knepley 4029566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 4039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name)); 40463a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd)); 405c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 406c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 407ad8374ffSToby Isaac const PetscInt *points; 408c58f1c22SToby Isaac PetscInt p; 409c58f1c22SToby Isaac 4109566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 41148a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 4129566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 413c58f1c22SToby Isaac } 414c58f1c22SToby Isaac } 4159566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 4169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 417c58f1c22SToby Isaac PetscFunctionReturn(0); 418c58f1c22SToby Isaac } 419c58f1c22SToby Isaac 420c58f1c22SToby Isaac /*@C 421c58f1c22SToby Isaac DMLabelView - View the label 422c58f1c22SToby Isaac 4235b5e7992SMatthew G. Knepley Collective on viewer 4245b5e7992SMatthew G. Knepley 425c58f1c22SToby Isaac Input Parameters: 426c58f1c22SToby Isaac + label - The DMLabel 427c58f1c22SToby Isaac - viewer - The PetscViewer 428c58f1c22SToby Isaac 429c58f1c22SToby Isaac Level: intermediate 430c58f1c22SToby Isaac 431db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 432c58f1c22SToby Isaac @*/ 433d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 434d71ae5a4SJacob Faibussowitsch { 435c58f1c22SToby Isaac PetscBool iascii; 436c58f1c22SToby Isaac 437c58f1c22SToby Isaac PetscFunctionBegin; 438d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 4399566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer)); 440c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4419566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 4429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4431baa6e33SBarry Smith if (iascii) PetscCall(DMLabelView_Ascii(label, viewer)); 444c58f1c22SToby Isaac PetscFunctionReturn(0); 445c58f1c22SToby Isaac } 446c58f1c22SToby Isaac 44784f0b6dfSMatthew G. Knepley /*@ 448d67d17b1SMatthew G. Knepley DMLabelReset - Destroys internal data structures in a DMLabel 449d67d17b1SMatthew G. Knepley 4505b5e7992SMatthew G. Knepley Not collective 4515b5e7992SMatthew G. Knepley 452d67d17b1SMatthew G. Knepley Input Parameter: 453d67d17b1SMatthew G. Knepley . label - The DMLabel 454d67d17b1SMatthew G. Knepley 455d67d17b1SMatthew G. Knepley Level: beginner 456d67d17b1SMatthew G. Knepley 457db781477SPatrick Sanan .seealso: `DMLabelDestroy()`, `DMLabelCreate()` 458d67d17b1SMatthew G. Knepley @*/ 459d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelReset(DMLabel label) 460d71ae5a4SJacob Faibussowitsch { 461d67d17b1SMatthew G. Knepley PetscInt v; 462d67d17b1SMatthew G. Knepley 463d67d17b1SMatthew G. Knepley PetscFunctionBegin; 464d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 465d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 4669566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&label->ht[v])); 4679566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 468d67d17b1SMatthew G. Knepley } 469b9907514SLisandro Dalcin label->numStrata = 0; 4709566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues)); 4719566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes)); 4729566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht)); 4739566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points)); 4749566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS)); 475f9244615SMatthew G. Knepley label->stratumValues = NULL; 476f9244615SMatthew G. Knepley label->stratumSizes = NULL; 477f9244615SMatthew G. Knepley label->ht = NULL; 478f9244615SMatthew G. Knepley label->points = NULL; 479f9244615SMatthew G. Knepley label->validIS = NULL; 4809566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 481b9907514SLisandro Dalcin label->pStart = -1; 482b9907514SLisandro Dalcin label->pEnd = -1; 4839566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 484d67d17b1SMatthew G. Knepley PetscFunctionReturn(0); 485d67d17b1SMatthew G. Knepley } 486d67d17b1SMatthew G. Knepley 487d67d17b1SMatthew G. Knepley /*@ 48884f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 48984f0b6dfSMatthew G. Knepley 4905b5e7992SMatthew G. Knepley Collective on label 4915b5e7992SMatthew G. Knepley 49284f0b6dfSMatthew G. Knepley Input Parameter: 49384f0b6dfSMatthew G. Knepley . label - The DMLabel 49484f0b6dfSMatthew G. Knepley 49584f0b6dfSMatthew G. Knepley Level: beginner 49684f0b6dfSMatthew G. Knepley 497db781477SPatrick Sanan .seealso: `DMLabelReset()`, `DMLabelCreate()` 49884f0b6dfSMatthew G. Knepley @*/ 499d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroy(DMLabel *label) 500d71ae5a4SJacob Faibussowitsch { 501c58f1c22SToby Isaac PetscFunctionBegin; 502d67d17b1SMatthew G. Knepley if (!*label) PetscFunctionReturn(0); 503d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label), DMLABEL_CLASSID, 1); 5049371c9d4SSatish Balay if (--((PetscObject)(*label))->refct > 0) { 5059371c9d4SSatish Balay *label = NULL; 5069371c9d4SSatish Balay PetscFunctionReturn(0); 5079371c9d4SSatish Balay } 5089566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 5099566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 5109566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 511c58f1c22SToby Isaac PetscFunctionReturn(0); 512c58f1c22SToby Isaac } 513c58f1c22SToby Isaac 51484f0b6dfSMatthew G. Knepley /*@ 51584f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 51684f0b6dfSMatthew G. Knepley 5175b5e7992SMatthew G. Knepley Collective on label 5185b5e7992SMatthew G. Knepley 51984f0b6dfSMatthew G. Knepley Input Parameter: 52084f0b6dfSMatthew G. Knepley . label - The DMLabel 52184f0b6dfSMatthew G. Knepley 52284f0b6dfSMatthew G. Knepley Output Parameter: 52384f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 52484f0b6dfSMatthew G. Knepley 52584f0b6dfSMatthew G. Knepley Level: intermediate 52684f0b6dfSMatthew G. Knepley 527db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 52884f0b6dfSMatthew G. Knepley @*/ 529d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 530d71ae5a4SJacob Faibussowitsch { 531d67d17b1SMatthew G. Knepley const char *name; 532ad8374ffSToby Isaac PetscInt v; 533c58f1c22SToby Isaac 534c58f1c22SToby Isaac PetscFunctionBegin; 535d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 5369566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 5379566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 5389566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)label), name, labelnew)); 539c58f1c22SToby Isaac 540c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5415aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 5429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 5439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 5449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->ht)); 5459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->points)); 5469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 547c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 5489566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 549c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 550c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 5519566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)(label->points[v]))); 552ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 553b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 554c58f1c22SToby Isaac } 5559566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5569566063dSJacob Faibussowitsch PetscCall(PetscHMapIDuplicate(label->hmap, &(*labelnew)->hmap)); 557c58f1c22SToby Isaac (*labelnew)->pStart = -1; 558c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 559c58f1c22SToby Isaac (*labelnew)->bt = NULL; 560c58f1c22SToby Isaac PetscFunctionReturn(0); 561c58f1c22SToby Isaac } 562c58f1c22SToby Isaac 563609dae6eSVaclav Hapla /*@C 564609dae6eSVaclav Hapla DMLabelCompare - Compare two DMLabel objects 565609dae6eSVaclav Hapla 5665efe38ccSVaclav Hapla Collective on comm 567609dae6eSVaclav Hapla 568609dae6eSVaclav Hapla Input Parameters: 569f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 570f1a722f8SMatthew G. Knepley . l0 - First DMLabel 571609dae6eSVaclav Hapla - l1 - Second DMLabel 572609dae6eSVaclav Hapla 573609dae6eSVaclav Hapla Output Parameters 5745efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 5755efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 576609dae6eSVaclav Hapla 577609dae6eSVaclav Hapla Level: intermediate 578609dae6eSVaclav Hapla 579609dae6eSVaclav Hapla Notes: 5805efe38ccSVaclav Hapla The output flag equal is the same on all processes. 5815efe38ccSVaclav Hapla If it is passed as NULL and difference is found, an error is thrown on all processes. 5825efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 583609dae6eSVaclav Hapla 5845efe38ccSVaclav Hapla The output message is set independently on each rank. 5855efe38ccSVaclav Hapla It is set to NULL if no difference was found on the current rank. It must be freed by user. 5865efe38ccSVaclav Hapla If message is passed as NULL and difference is found, the difference description is printed to stderr in synchronized manner. 5875efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 588609dae6eSVaclav Hapla 589609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 590609dae6eSVaclav Hapla 5915efe38ccSVaclav Hapla The communicator needs to be specified because currently DMLabel can live on PETSC_COMM_SELF even if the underlying DM is parallel. 5925efe38ccSVaclav Hapla 593609dae6eSVaclav Hapla Fortran Notes: 594609dae6eSVaclav Hapla This function is currently not available from Fortran. 595609dae6eSVaclav Hapla 596db781477SPatrick Sanan .seealso: `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 597609dae6eSVaclav Hapla @*/ 598d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 599d71ae5a4SJacob Faibussowitsch { 600609dae6eSVaclav Hapla const char *name0, *name1; 601609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 6025efe38ccSVaclav Hapla PetscBool eq; 6035efe38ccSVaclav Hapla PetscMPIInt rank; 604609dae6eSVaclav Hapla 605609dae6eSVaclav Hapla PetscFunctionBegin; 6065efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 6075efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6085efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal, 4); 6095efe38ccSVaclav Hapla if (message) PetscValidPointer(message, 5); 6109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6119566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6129566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 613609dae6eSVaclav Hapla { 614609dae6eSVaclav Hapla PetscInt v0, v1; 615609dae6eSVaclav Hapla 6169566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6179566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6185efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 61948a46eb9SPierre 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)); 6209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6215efe38ccSVaclav Hapla if (!eq) goto finish; 622609dae6eSVaclav Hapla } 623609dae6eSVaclav Hapla { 624609dae6eSVaclav Hapla IS is0, is1; 625609dae6eSVaclav Hapla 6269566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6279566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6289566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6299566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6309566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 63148a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 6329566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6335efe38ccSVaclav Hapla if (!eq) goto finish; 634609dae6eSVaclav Hapla } 635609dae6eSVaclav Hapla { 636609dae6eSVaclav Hapla PetscInt i, nValues; 637609dae6eSVaclav Hapla 6389566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 639609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 640609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 641609dae6eSVaclav Hapla PetscInt n; 642609dae6eSVaclav Hapla IS is0, is1; 643609dae6eSVaclav Hapla 6449566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 645609dae6eSVaclav Hapla if (!n) continue; 6469566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6479566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6489566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6499566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6509566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6515efe38ccSVaclav Hapla if (!eq) { 65263a3b9bcSJacob 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)); 6535efe38ccSVaclav Hapla break; 654609dae6eSVaclav Hapla } 655609dae6eSVaclav Hapla } 6569566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 657609dae6eSVaclav Hapla } 658609dae6eSVaclav Hapla finish: 6595efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 660609dae6eSVaclav Hapla if (message) { 661609dae6eSVaclav Hapla *message = NULL; 66248a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 6635efe38ccSVaclav Hapla } else { 66448a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 6659566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 6665efe38ccSVaclav Hapla } 6675efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 6685efe38ccSVaclav Hapla if (equal) *equal = eq; 66963a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 670609dae6eSVaclav Hapla PetscFunctionReturn(0); 671609dae6eSVaclav Hapla } 672609dae6eSVaclav Hapla 673c6a43d28SMatthew G. Knepley /*@ 674c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 675c6a43d28SMatthew G. Knepley 6765b5e7992SMatthew G. Knepley Not collective 6775b5e7992SMatthew G. Knepley 678c6a43d28SMatthew G. Knepley Input Parameter: 679c6a43d28SMatthew G. Knepley . label - The DMLabel 680c6a43d28SMatthew G. Knepley 681c6a43d28SMatthew G. Knepley Level: intermediate 682c6a43d28SMatthew G. Knepley 683db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 684c6a43d28SMatthew G. Knepley @*/ 685d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelComputeIndex(DMLabel label) 686d71ae5a4SJacob Faibussowitsch { 687c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 688c6a43d28SMatthew G. Knepley 689c6a43d28SMatthew G. Knepley PetscFunctionBegin; 690c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 6919566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 692c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 693c6a43d28SMatthew G. Knepley const PetscInt *points; 694c6a43d28SMatthew G. Knepley PetscInt i; 695c6a43d28SMatthew G. Knepley 6969566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 697c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 698c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 699c6a43d28SMatthew G. Knepley 700c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 701c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 702c6a43d28SMatthew G. Knepley } 7039566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 704c6a43d28SMatthew G. Knepley } 705c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 706c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7079566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 708c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 709c6a43d28SMatthew G. Knepley } 710c6a43d28SMatthew G. Knepley 711c6a43d28SMatthew G. Knepley /*@ 712c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 713c6a43d28SMatthew G. Knepley 7145b5e7992SMatthew G. Knepley Not collective 7155b5e7992SMatthew G. Knepley 716c6a43d28SMatthew G. Knepley Input Parameters: 717c6a43d28SMatthew G. Knepley + label - The DMLabel 718c6a43d28SMatthew G. Knepley . pStart - The smallest point 719c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 720c6a43d28SMatthew G. Knepley 721c6a43d28SMatthew G. Knepley Level: intermediate 722c6a43d28SMatthew G. Knepley 723db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 724c6a43d28SMatthew G. Knepley @*/ 725d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 726d71ae5a4SJacob Faibussowitsch { 727c58f1c22SToby Isaac PetscInt v; 728c58f1c22SToby Isaac 729c58f1c22SToby Isaac PetscFunctionBegin; 730d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7319566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7329566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 733c58f1c22SToby Isaac label->pStart = pStart; 734c58f1c22SToby Isaac label->pEnd = pEnd; 735c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7369566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 737c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 738ad8374ffSToby Isaac const PetscInt *points; 739c58f1c22SToby Isaac PetscInt i; 740c58f1c22SToby Isaac 7419566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 742c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 743ad8374ffSToby Isaac const PetscInt point = points[i]; 744c58f1c22SToby Isaac 74563a3b9bcSJacob Faibussowitsch PetscCheck(!(point < pStart) && !(point >= pEnd), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, pStart, pEnd); 7469566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 747c58f1c22SToby Isaac } 7489566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 749c58f1c22SToby Isaac } 750c58f1c22SToby Isaac PetscFunctionReturn(0); 751c58f1c22SToby Isaac } 752c58f1c22SToby Isaac 753c6a43d28SMatthew G. Knepley /*@ 754c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 755c6a43d28SMatthew G. Knepley 7565b5e7992SMatthew G. Knepley Not collective 7575b5e7992SMatthew G. Knepley 758c6a43d28SMatthew G. Knepley Input Parameter: 759c6a43d28SMatthew G. Knepley . label - the DMLabel 760c6a43d28SMatthew G. Knepley 761c6a43d28SMatthew G. Knepley Level: intermediate 762c6a43d28SMatthew G. Knepley 763db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 764c6a43d28SMatthew G. Knepley @*/ 765d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDestroyIndex(DMLabel label) 766d71ae5a4SJacob Faibussowitsch { 767c58f1c22SToby Isaac PetscFunctionBegin; 768d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 769c58f1c22SToby Isaac label->pStart = -1; 770c58f1c22SToby Isaac label->pEnd = -1; 7719566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 772c58f1c22SToby Isaac PetscFunctionReturn(0); 773c58f1c22SToby Isaac } 774c58f1c22SToby Isaac 775c58f1c22SToby Isaac /*@ 776c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 777c6a43d28SMatthew G. Knepley 7785b5e7992SMatthew G. Knepley Not collective 7795b5e7992SMatthew G. Knepley 780c6a43d28SMatthew G. Knepley Input Parameter: 781c6a43d28SMatthew G. Knepley . label - the DMLabel 782c6a43d28SMatthew G. Knepley 783c6a43d28SMatthew G. Knepley Output Parameters: 784c6a43d28SMatthew G. Knepley + pStart - The smallest point 785c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 786c6a43d28SMatthew G. Knepley 787c6a43d28SMatthew G. Knepley Note: This will compute an index for the label if one does not exist. 788c6a43d28SMatthew G. Knepley 789c6a43d28SMatthew G. Knepley Level: intermediate 790c6a43d28SMatthew G. Knepley 791db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 792c6a43d28SMatthew G. Knepley @*/ 793d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 794d71ae5a4SJacob Faibussowitsch { 795c6a43d28SMatthew G. Knepley PetscFunctionBegin; 796c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7979566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 798c6a43d28SMatthew G. Knepley if (pStart) { 799534a8f05SLisandro Dalcin PetscValidIntPointer(pStart, 2); 800c6a43d28SMatthew G. Knepley *pStart = label->pStart; 801c6a43d28SMatthew G. Knepley } 802c6a43d28SMatthew G. Knepley if (pEnd) { 803534a8f05SLisandro Dalcin PetscValidIntPointer(pEnd, 3); 804c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 805c6a43d28SMatthew G. Knepley } 806c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 807c6a43d28SMatthew G. Knepley } 808c6a43d28SMatthew G. Knepley 809c6a43d28SMatthew G. Knepley /*@ 810c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 811c58f1c22SToby Isaac 8125b5e7992SMatthew G. Knepley Not collective 8135b5e7992SMatthew G. Knepley 814c58f1c22SToby Isaac Input Parameters: 815c58f1c22SToby Isaac + label - the DMLabel 816c58f1c22SToby Isaac - value - the value 817c58f1c22SToby Isaac 818c58f1c22SToby Isaac Output Parameter: 819c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 820c58f1c22SToby Isaac 821c58f1c22SToby Isaac Level: developer 822c58f1c22SToby Isaac 823db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 824c58f1c22SToby Isaac @*/ 825d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 826d71ae5a4SJacob Faibussowitsch { 827c58f1c22SToby Isaac PetscInt v; 828c58f1c22SToby Isaac 829c58f1c22SToby Isaac PetscFunctionBegin; 830d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 831534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8329566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8330c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 834c58f1c22SToby Isaac PetscFunctionReturn(0); 835c58f1c22SToby Isaac } 836c58f1c22SToby Isaac 837c58f1c22SToby Isaac /*@ 838c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 839c58f1c22SToby Isaac 8405b5e7992SMatthew G. Knepley Not collective 8415b5e7992SMatthew G. Knepley 842c58f1c22SToby Isaac Input Parameters: 843c58f1c22SToby Isaac + label - the DMLabel 844c58f1c22SToby Isaac - point - the point 845c58f1c22SToby Isaac 846c58f1c22SToby Isaac Output Parameter: 847c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 848c58f1c22SToby Isaac 849c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 850c58f1c22SToby Isaac 851c58f1c22SToby Isaac Level: developer 852c58f1c22SToby Isaac 853db781477SPatrick Sanan .seealso: `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 854c58f1c22SToby Isaac @*/ 855d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 856d71ae5a4SJacob Faibussowitsch { 857c58f1c22SToby Isaac PetscFunctionBeginHot; 858d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 859534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8609566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 86176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 86228b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 86363a3b9bcSJacob 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); 86476bd3646SJed Brown } 865c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 866c58f1c22SToby Isaac PetscFunctionReturn(0); 867c58f1c22SToby Isaac } 868c58f1c22SToby Isaac 869c58f1c22SToby Isaac /*@ 870c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 871c58f1c22SToby Isaac 8725b5e7992SMatthew G. Knepley Not collective 8735b5e7992SMatthew G. Knepley 874c58f1c22SToby Isaac Input Parameters: 875c58f1c22SToby Isaac + label - the DMLabel 876c58f1c22SToby Isaac . value - the stratum value 877c58f1c22SToby Isaac - point - the point 878c58f1c22SToby Isaac 879c58f1c22SToby Isaac Output Parameter: 880c58f1c22SToby Isaac . contains - true if the stratum contains the point 881c58f1c22SToby Isaac 882c58f1c22SToby Isaac Level: intermediate 883c58f1c22SToby Isaac 884db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 885c58f1c22SToby Isaac @*/ 886d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 887d71ae5a4SJacob Faibussowitsch { 8880c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 889d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 890534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 4); 891cffad2c9SToby Isaac if (value == label->defaultValue) { 892cffad2c9SToby Isaac PetscInt pointVal; 8930c3c4a36SLisandro Dalcin 894cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 895cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 896cffad2c9SToby Isaac } else { 897cffad2c9SToby Isaac PetscInt v; 898cffad2c9SToby Isaac 899cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 900cffad2c9SToby Isaac if (v >= 0) { 901ad8374ffSToby Isaac if (label->validIS[v]) { 902c58f1c22SToby Isaac PetscInt i; 903c58f1c22SToby Isaac 9049566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 905cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 906c58f1c22SToby Isaac } else { 907cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 908cffad2c9SToby Isaac } 909cffad2c9SToby Isaac } else { // value is not present 910cffad2c9SToby Isaac *contains = PETSC_FALSE; 911cffad2c9SToby Isaac } 912c58f1c22SToby Isaac } 913c58f1c22SToby Isaac PetscFunctionReturn(0); 914c58f1c22SToby Isaac } 915c58f1c22SToby Isaac 91684f0b6dfSMatthew G. Knepley /*@ 9175aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9185aa44df4SToby Isaac When a label is created, it is initialized to -1. 9195aa44df4SToby Isaac 9205b5e7992SMatthew G. Knepley Not collective 9215b5e7992SMatthew G. Knepley 9225aa44df4SToby Isaac Input parameter: 9235aa44df4SToby Isaac . label - a DMLabel object 9245aa44df4SToby Isaac 9255aa44df4SToby Isaac Output parameter: 9265aa44df4SToby Isaac . defaultValue - the default value 9275aa44df4SToby Isaac 9285aa44df4SToby Isaac Level: beginner 9295aa44df4SToby Isaac 930db781477SPatrick Sanan .seealso: `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 93184f0b6dfSMatthew G. Knepley @*/ 932d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 933d71ae5a4SJacob Faibussowitsch { 9345aa44df4SToby Isaac PetscFunctionBegin; 935d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9365aa44df4SToby Isaac *defaultValue = label->defaultValue; 9375aa44df4SToby Isaac PetscFunctionReturn(0); 9385aa44df4SToby Isaac } 9395aa44df4SToby Isaac 94084f0b6dfSMatthew G. Knepley /*@ 9415aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9425aa44df4SToby Isaac When a label is created, it is initialized to -1. 9435aa44df4SToby Isaac 9445b5e7992SMatthew G. Knepley Not collective 9455b5e7992SMatthew G. Knepley 9465aa44df4SToby Isaac Input parameter: 9475aa44df4SToby Isaac . label - a DMLabel object 9485aa44df4SToby Isaac 9495aa44df4SToby Isaac Output parameter: 9505aa44df4SToby Isaac . defaultValue - the default value 9515aa44df4SToby Isaac 9525aa44df4SToby Isaac Level: beginner 9535aa44df4SToby Isaac 954db781477SPatrick Sanan .seealso: `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 95584f0b6dfSMatthew G. Knepley @*/ 956d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 957d71ae5a4SJacob Faibussowitsch { 9585aa44df4SToby Isaac PetscFunctionBegin; 959d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9605aa44df4SToby Isaac label->defaultValue = defaultValue; 9615aa44df4SToby Isaac PetscFunctionReturn(0); 9625aa44df4SToby Isaac } 9635aa44df4SToby Isaac 964c58f1c22SToby Isaac /*@ 9655aa44df4SToby Isaac 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 DMLabelSetDefaultValue()) 966c58f1c22SToby Isaac 9675b5e7992SMatthew G. Knepley Not collective 9685b5e7992SMatthew G. Knepley 969c58f1c22SToby Isaac Input Parameters: 970c58f1c22SToby Isaac + label - the DMLabel 971c58f1c22SToby Isaac - point - the point 972c58f1c22SToby Isaac 973c58f1c22SToby Isaac Output Parameter: 9748e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 975c58f1c22SToby Isaac 976cffad2c9SToby Isaac Note: a label may assign multiple values to a point. No guarantees are made about which value is returned in that case. Use `DMLabelStratumHasPoint()` to check for inclusion in a specific value stratum. 977cffad2c9SToby Isaac 978c58f1c22SToby Isaac Level: intermediate 979c58f1c22SToby Isaac 980db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 981c58f1c22SToby Isaac @*/ 982d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 983d71ae5a4SJacob Faibussowitsch { 984c58f1c22SToby Isaac PetscInt v; 985c58f1c22SToby Isaac 9860c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 987d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 988dadcf809SJacob Faibussowitsch PetscValidIntPointer(value, 3); 9895aa44df4SToby Isaac *value = label->defaultValue; 990c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 991ad8374ffSToby Isaac if (label->validIS[v]) { 992c58f1c22SToby Isaac PetscInt i; 993c58f1c22SToby Isaac 9949566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 995c58f1c22SToby Isaac if (i >= 0) { 996c58f1c22SToby Isaac *value = label->stratumValues[v]; 997c58f1c22SToby Isaac break; 998c58f1c22SToby Isaac } 999c58f1c22SToby Isaac } else { 1000c58f1c22SToby Isaac PetscBool has; 1001c58f1c22SToby Isaac 10029566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 1003c58f1c22SToby Isaac if (has) { 1004c58f1c22SToby Isaac *value = label->stratumValues[v]; 1005c58f1c22SToby Isaac break; 1006c58f1c22SToby Isaac } 1007c58f1c22SToby Isaac } 1008c58f1c22SToby Isaac } 1009c58f1c22SToby Isaac PetscFunctionReturn(0); 1010c58f1c22SToby Isaac } 1011c58f1c22SToby Isaac 1012c58f1c22SToby Isaac /*@ 1013367003a6SStefano Zampini 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 be changed with DMLabelSetDefaultValue() to something different), then this function will do nothing. 1014c58f1c22SToby Isaac 10155b5e7992SMatthew G. Knepley Not collective 10165b5e7992SMatthew G. Knepley 1017c58f1c22SToby Isaac Input Parameters: 1018c58f1c22SToby Isaac + label - the DMLabel 1019c58f1c22SToby Isaac . point - the point 1020c58f1c22SToby Isaac - value - The point value 1021c58f1c22SToby Isaac 1022c58f1c22SToby Isaac Level: intermediate 1023c58f1c22SToby Isaac 1024db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1025c58f1c22SToby Isaac @*/ 1026d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1027d71ae5a4SJacob Faibussowitsch { 1028c58f1c22SToby Isaac PetscInt v; 1029c58f1c22SToby Isaac 1030c58f1c22SToby Isaac PetscFunctionBegin; 1031d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10320c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10335aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 10349566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1035c58f1c22SToby Isaac /* Set key */ 10369566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10379566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 1038c58f1c22SToby Isaac PetscFunctionReturn(0); 1039c58f1c22SToby Isaac } 1040c58f1c22SToby Isaac 1041c58f1c22SToby Isaac /*@ 1042c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1043c58f1c22SToby Isaac 10445b5e7992SMatthew G. Knepley Not collective 10455b5e7992SMatthew G. Knepley 1046c58f1c22SToby Isaac Input Parameters: 1047c58f1c22SToby Isaac + label - the DMLabel 1048c58f1c22SToby Isaac . point - the point 1049c58f1c22SToby Isaac - value - The point value 1050c58f1c22SToby Isaac 1051c58f1c22SToby Isaac Level: intermediate 1052c58f1c22SToby Isaac 1053db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1054c58f1c22SToby Isaac @*/ 1055d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1056d71ae5a4SJacob Faibussowitsch { 1057ad8374ffSToby Isaac PetscInt v; 1058c58f1c22SToby Isaac 1059c58f1c22SToby Isaac PetscFunctionBegin; 1060d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1061c58f1c22SToby Isaac /* Find label value */ 10629566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 10630c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 10640c3c4a36SLisandro Dalcin 1065eeed21e7SToby Isaac if (label->bt) { 106663a3b9bcSJacob 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); 10679566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1068eeed21e7SToby Isaac } 10690c3c4a36SLisandro Dalcin 10700c3c4a36SLisandro Dalcin /* Delete key */ 10719566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10729566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 1073c58f1c22SToby Isaac PetscFunctionReturn(0); 1074c58f1c22SToby Isaac } 1075c58f1c22SToby Isaac 1076c58f1c22SToby Isaac /*@ 1077c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 1078c58f1c22SToby Isaac 10795b5e7992SMatthew G. Knepley Not collective 10805b5e7992SMatthew G. Knepley 1081c58f1c22SToby Isaac Input Parameters: 1082c58f1c22SToby Isaac + label - the DMLabel 1083c58f1c22SToby Isaac . is - the point IS 1084c58f1c22SToby Isaac - value - The point value 1085c58f1c22SToby Isaac 1086c58f1c22SToby Isaac Level: intermediate 1087c58f1c22SToby Isaac 1088db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1089c58f1c22SToby Isaac @*/ 1090d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1091d71ae5a4SJacob Faibussowitsch { 10920c3c4a36SLisandro Dalcin PetscInt v, n, p; 1093c58f1c22SToby Isaac const PetscInt *points; 1094c58f1c22SToby Isaac 1095c58f1c22SToby Isaac PetscFunctionBegin; 1096d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1097c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 10980c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10990c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 11009566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 11010c3c4a36SLisandro Dalcin /* Set keys */ 11029566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 11039566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 11049566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 11059566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 11069566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 1107c58f1c22SToby Isaac PetscFunctionReturn(0); 1108c58f1c22SToby Isaac } 1109c58f1c22SToby Isaac 111084f0b6dfSMatthew G. Knepley /*@ 111184f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 111284f0b6dfSMatthew G. Knepley 11135b5e7992SMatthew G. Knepley Not collective 11145b5e7992SMatthew G. Knepley 111584f0b6dfSMatthew G. Knepley Input Parameter: 111684f0b6dfSMatthew G. Knepley . label - the DMLabel 111784f0b6dfSMatthew G. Knepley 111801d2d390SJose E. Roman Output Parameter: 111984f0b6dfSMatthew G. Knepley . numValues - the number of values 112084f0b6dfSMatthew G. Knepley 112184f0b6dfSMatthew G. Knepley Level: intermediate 112284f0b6dfSMatthew G. Knepley 1123db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 112484f0b6dfSMatthew G. Knepley @*/ 1125d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1126d71ae5a4SJacob Faibussowitsch { 1127c58f1c22SToby Isaac PetscFunctionBegin; 1128d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1129dadcf809SJacob Faibussowitsch PetscValidIntPointer(numValues, 2); 1130c58f1c22SToby Isaac *numValues = label->numStrata; 1131c58f1c22SToby Isaac PetscFunctionReturn(0); 1132c58f1c22SToby Isaac } 1133c58f1c22SToby Isaac 113484f0b6dfSMatthew G. Knepley /*@ 113584f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 113684f0b6dfSMatthew G. Knepley 11375b5e7992SMatthew G. Knepley Not collective 11385b5e7992SMatthew G. Knepley 113984f0b6dfSMatthew G. Knepley Input Parameter: 114084f0b6dfSMatthew G. Knepley . label - the DMLabel 114184f0b6dfSMatthew G. Knepley 114201d2d390SJose E. Roman Output Parameter: 114384f0b6dfSMatthew G. Knepley . is - the value IS 114484f0b6dfSMatthew G. Knepley 114584f0b6dfSMatthew G. Knepley Level: intermediate 114684f0b6dfSMatthew G. Knepley 11471d04cbbeSVaclav Hapla Notes: 11481d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11491d04cbbeSVaclav Hapla Strata which are allocated but empty [DMLabelGetStratumSize() yields 0] are counted. 11501d04cbbeSVaclav Hapla If you need to count only nonempty strata, use DMLabelGetNonEmptyStratumValuesIS(). 11511d04cbbeSVaclav Hapla 1152db781477SPatrick Sanan .seealso: `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 115384f0b6dfSMatthew G. Knepley @*/ 1154d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1155d71ae5a4SJacob Faibussowitsch { 1156c58f1c22SToby Isaac PetscFunctionBegin; 1157d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1158c58f1c22SToby Isaac PetscValidPointer(values, 2); 11599566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 1160c58f1c22SToby Isaac PetscFunctionReturn(0); 1161c58f1c22SToby Isaac } 1162c58f1c22SToby Isaac 116384f0b6dfSMatthew G. Knepley /*@ 11641d04cbbeSVaclav Hapla DMLabelGetNonEmptyStratumValuesIS - Get an IS of all values that the DMlabel takes 11651d04cbbeSVaclav Hapla 11661d04cbbeSVaclav Hapla Not collective 11671d04cbbeSVaclav Hapla 11681d04cbbeSVaclav Hapla Input Parameter: 11691d04cbbeSVaclav Hapla . label - the DMLabel 11701d04cbbeSVaclav Hapla 1171*d5b43468SJose E. Roman Output Parameter: 11721d04cbbeSVaclav Hapla . is - the value IS 11731d04cbbeSVaclav Hapla 11741d04cbbeSVaclav Hapla Level: intermediate 11751d04cbbeSVaclav Hapla 11761d04cbbeSVaclav Hapla Notes: 11771d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11781d04cbbeSVaclav Hapla This is similar to DMLabelGetValueIS() but counts only nonempty strata. 11791d04cbbeSVaclav Hapla 1180db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 11811d04cbbeSVaclav Hapla @*/ 1182d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 1183d71ae5a4SJacob Faibussowitsch { 11841d04cbbeSVaclav Hapla PetscInt i, j; 11851d04cbbeSVaclav Hapla PetscInt *valuesArr; 11861d04cbbeSVaclav Hapla 11871d04cbbeSVaclav Hapla PetscFunctionBegin; 11881d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11891d04cbbeSVaclav Hapla PetscValidPointer(values, 2); 11909566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 11911d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 11921d04cbbeSVaclav Hapla PetscInt n; 11931d04cbbeSVaclav Hapla 11949566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 11951d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 11961d04cbbeSVaclav Hapla } 11971d04cbbeSVaclav Hapla if (j == label->numStrata) { 11989566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 11991d04cbbeSVaclav Hapla } else { 12009566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 12011d04cbbeSVaclav Hapla } 12029566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 12031d04cbbeSVaclav Hapla PetscFunctionReturn(0); 12041d04cbbeSVaclav Hapla } 12051d04cbbeSVaclav Hapla 12061d04cbbeSVaclav Hapla /*@ 1207d123abd9SMatthew G. Knepley DMLabelGetValueIndex - Get the index of a given value in the list of values for the DMlabel, or -1 if it is not present 1208d123abd9SMatthew G. Knepley 1209d123abd9SMatthew G. Knepley Not collective 1210d123abd9SMatthew G. Knepley 1211d123abd9SMatthew G. Knepley Input Parameters: 1212d123abd9SMatthew G. Knepley + label - the DMLabel 121397bb3fdcSJose E. Roman - value - the value 1214d123abd9SMatthew G. Knepley 121501d2d390SJose E. Roman Output Parameter: 1216d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1217d123abd9SMatthew G. Knepley 1218d123abd9SMatthew G. Knepley Level: intermediate 1219d123abd9SMatthew G. Knepley 1220db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1221d123abd9SMatthew G. Knepley @*/ 1222d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1223d71ae5a4SJacob Faibussowitsch { 1224d123abd9SMatthew G. Knepley PetscInt v; 1225d123abd9SMatthew G. Knepley 1226d123abd9SMatthew G. Knepley PetscFunctionBegin; 1227d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1228dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 3); 1229d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 12309371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 12319371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1232d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1233d123abd9SMatthew G. Knepley else *index = v; 1234d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1235d123abd9SMatthew G. Knepley } 1236d123abd9SMatthew G. Knepley 1237d123abd9SMatthew G. Knepley /*@ 123884f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 123984f0b6dfSMatthew G. Knepley 12405b5e7992SMatthew G. Knepley Not collective 12415b5e7992SMatthew G. Knepley 124284f0b6dfSMatthew G. Knepley Input Parameters: 124384f0b6dfSMatthew G. Knepley + label - the DMLabel 124484f0b6dfSMatthew G. Knepley - value - the stratum value 124584f0b6dfSMatthew G. Knepley 124601d2d390SJose E. Roman Output Parameter: 124784f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 124884f0b6dfSMatthew G. Knepley 124984f0b6dfSMatthew G. Knepley Level: intermediate 125084f0b6dfSMatthew G. Knepley 1251db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 125284f0b6dfSMatthew G. Knepley @*/ 1253d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1254d71ae5a4SJacob Faibussowitsch { 1255fada774cSMatthew G. Knepley PetscInt v; 1256fada774cSMatthew G. Knepley 1257fada774cSMatthew G. Knepley PetscFunctionBegin; 1258d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1259dadcf809SJacob Faibussowitsch PetscValidBoolPointer(exists, 3); 12609566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12610c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 1262fada774cSMatthew G. Knepley PetscFunctionReturn(0); 1263fada774cSMatthew G. Knepley } 1264fada774cSMatthew G. Knepley 126584f0b6dfSMatthew G. Knepley /*@ 126684f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 126784f0b6dfSMatthew G. Knepley 12685b5e7992SMatthew G. Knepley Not collective 12695b5e7992SMatthew G. Knepley 127084f0b6dfSMatthew G. Knepley Input Parameters: 127184f0b6dfSMatthew G. Knepley + label - the DMLabel 127284f0b6dfSMatthew G. Knepley - value - the stratum value 127384f0b6dfSMatthew G. Knepley 127401d2d390SJose E. Roman Output Parameter: 127584f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 127684f0b6dfSMatthew G. Knepley 127784f0b6dfSMatthew G. Knepley Level: intermediate 127884f0b6dfSMatthew G. Knepley 1279db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 128084f0b6dfSMatthew G. Knepley @*/ 1281d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1282d71ae5a4SJacob Faibussowitsch { 1283c58f1c22SToby Isaac PetscInt v; 1284c58f1c22SToby Isaac 1285c58f1c22SToby Isaac PetscFunctionBegin; 1286d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1287dadcf809SJacob Faibussowitsch PetscValidIntPointer(size, 3); 12889566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12899566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 1290c58f1c22SToby Isaac PetscFunctionReturn(0); 1291c58f1c22SToby Isaac } 1292c58f1c22SToby Isaac 129384f0b6dfSMatthew G. Knepley /*@ 129484f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 129584f0b6dfSMatthew G. Knepley 12965b5e7992SMatthew G. Knepley Not collective 12975b5e7992SMatthew G. Knepley 129884f0b6dfSMatthew G. Knepley Input Parameters: 129984f0b6dfSMatthew G. Knepley + label - the DMLabel 130084f0b6dfSMatthew G. Knepley - value - the stratum value 130184f0b6dfSMatthew G. Knepley 130201d2d390SJose E. Roman Output Parameters: 130384f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 130484f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 130584f0b6dfSMatthew G. Knepley 130684f0b6dfSMatthew G. Knepley Level: intermediate 130784f0b6dfSMatthew G. Knepley 1308db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 130984f0b6dfSMatthew G. Knepley @*/ 1310d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1311d71ae5a4SJacob Faibussowitsch { 13120c3c4a36SLisandro Dalcin PetscInt v, min, max; 1313c58f1c22SToby Isaac 1314c58f1c22SToby Isaac PetscFunctionBegin; 1315d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13169371c9d4SSatish Balay if (start) { 13179371c9d4SSatish Balay PetscValidIntPointer(start, 3); 13189371c9d4SSatish Balay *start = -1; 13199371c9d4SSatish Balay } 13209371c9d4SSatish Balay if (end) { 13219371c9d4SSatish Balay PetscValidIntPointer(end, 4); 13229371c9d4SSatish Balay *end = -1; 13239371c9d4SSatish Balay } 13249566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13250c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13269566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13270c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 13289566063dSJacob Faibussowitsch PetscCall(ISGetMinMax(label->points[v], &min, &max)); 1329d6cb179aSToby Isaac if (start) *start = min; 1330d6cb179aSToby Isaac if (end) *end = max + 1; 1331c58f1c22SToby Isaac PetscFunctionReturn(0); 1332c58f1c22SToby Isaac } 1333c58f1c22SToby Isaac 133484f0b6dfSMatthew G. Knepley /*@ 133584f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 133684f0b6dfSMatthew G. Knepley 13375b5e7992SMatthew G. Knepley Not collective 13385b5e7992SMatthew G. Knepley 133984f0b6dfSMatthew G. Knepley Input Parameters: 134084f0b6dfSMatthew G. Knepley + label - the DMLabel 134184f0b6dfSMatthew G. Knepley - value - the stratum value 134284f0b6dfSMatthew G. Knepley 134301d2d390SJose E. Roman Output Parameter: 134484f0b6dfSMatthew G. Knepley . points - The stratum points 134584f0b6dfSMatthew G. Knepley 134684f0b6dfSMatthew G. Knepley Level: intermediate 134784f0b6dfSMatthew G. Knepley 1348593ce467SVaclav Hapla Notes: 1349593ce467SVaclav Hapla The output IS should be destroyed when no longer needed. 1350593ce467SVaclav Hapla Returns NULL if the stratum is empty. 1351593ce467SVaclav Hapla 1352db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 135384f0b6dfSMatthew G. Knepley @*/ 1354d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1355d71ae5a4SJacob Faibussowitsch { 1356c58f1c22SToby Isaac PetscInt v; 1357c58f1c22SToby Isaac 1358c58f1c22SToby Isaac PetscFunctionBegin; 1359d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1360c58f1c22SToby Isaac PetscValidPointer(points, 3); 1361c58f1c22SToby Isaac *points = NULL; 13629566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13630c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13649566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13659566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label->points[v])); 1366ad8374ffSToby Isaac *points = label->points[v]; 1367c58f1c22SToby Isaac PetscFunctionReturn(0); 1368c58f1c22SToby Isaac } 1369c58f1c22SToby Isaac 137084f0b6dfSMatthew G. Knepley /*@ 137184f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 137284f0b6dfSMatthew G. Knepley 13735b5e7992SMatthew G. Knepley Not collective 13745b5e7992SMatthew G. Knepley 137584f0b6dfSMatthew G. Knepley Input Parameters: 137684f0b6dfSMatthew G. Knepley + label - the DMLabel 137784f0b6dfSMatthew G. Knepley . value - the stratum value 137884f0b6dfSMatthew G. Knepley - points - The stratum points 137984f0b6dfSMatthew G. Knepley 138084f0b6dfSMatthew G. Knepley Level: intermediate 138184f0b6dfSMatthew G. Knepley 1382db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 138384f0b6dfSMatthew G. Knepley @*/ 1384d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 1385d71ae5a4SJacob Faibussowitsch { 13860c3c4a36SLisandro Dalcin PetscInt v; 13874de306b1SToby Isaac 13884de306b1SToby Isaac PetscFunctionBegin; 1389d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1390d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 13919566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 13924de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 13939566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 13949566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &(label->stratumSizes[v]))); 13959566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 13969566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 13970c3c4a36SLisandro Dalcin label->points[v] = is; 13980c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 13999566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 14004de306b1SToby Isaac if (label->bt) { 14014de306b1SToby Isaac const PetscInt *points; 14024de306b1SToby Isaac PetscInt p; 14034de306b1SToby Isaac 14049566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 14054de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 14064de306b1SToby Isaac const PetscInt point = points[p]; 14074de306b1SToby Isaac 140863a3b9bcSJacob 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); 14099566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 14104de306b1SToby Isaac } 14114de306b1SToby Isaac } 14124de306b1SToby Isaac PetscFunctionReturn(0); 14134de306b1SToby Isaac } 14144de306b1SToby Isaac 141584f0b6dfSMatthew G. Knepley /*@ 141684f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 14174de306b1SToby Isaac 14185b5e7992SMatthew G. Knepley Not collective 14195b5e7992SMatthew G. Knepley 142084f0b6dfSMatthew G. Knepley Input Parameters: 142184f0b6dfSMatthew G. Knepley + label - the DMLabel 142284f0b6dfSMatthew G. Knepley - value - the stratum value 142384f0b6dfSMatthew G. Knepley 142484f0b6dfSMatthew G. Knepley Level: intermediate 142584f0b6dfSMatthew G. Knepley 1426db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 142784f0b6dfSMatthew G. Knepley @*/ 1428d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1429d71ae5a4SJacob Faibussowitsch { 1430c58f1c22SToby Isaac PetscInt v; 1431c58f1c22SToby Isaac 1432c58f1c22SToby Isaac PetscFunctionBegin; 1433d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14349566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14350c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 14364de306b1SToby Isaac if (label->validIS[v]) { 14374de306b1SToby Isaac if (label->bt) { 1438c58f1c22SToby Isaac PetscInt i; 1439ad8374ffSToby Isaac const PetscInt *points; 1440c58f1c22SToby Isaac 14419566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1442c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1443ad8374ffSToby Isaac const PetscInt point = points[i]; 1444c58f1c22SToby Isaac 144563a3b9bcSJacob 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); 14469566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1447c58f1c22SToby Isaac } 14489566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1449c58f1c22SToby Isaac } 1450c58f1c22SToby Isaac label->stratumSizes[v] = 0; 14519566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 14529566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 14539566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 14549566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1455c58f1c22SToby Isaac } else { 14569566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1457c58f1c22SToby Isaac } 1458c58f1c22SToby Isaac PetscFunctionReturn(0); 1459c58f1c22SToby Isaac } 1460c58f1c22SToby Isaac 146184f0b6dfSMatthew G. Knepley /*@ 1462412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1463412e9a14SMatthew G. Knepley 1464412e9a14SMatthew G. Knepley Not collective 1465412e9a14SMatthew G. Knepley 1466412e9a14SMatthew G. Knepley Input Parameters: 1467412e9a14SMatthew G. Knepley + label - The DMLabel 1468412e9a14SMatthew G. Knepley . value - The label value for all points 1469412e9a14SMatthew G. Knepley . pStart - The first point 1470412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1471412e9a14SMatthew G. Knepley 1472412e9a14SMatthew G. Knepley Note: The marks points are [pStart, pEnd), and only the bounds are stored. 1473412e9a14SMatthew G. Knepley 1474412e9a14SMatthew G. Knepley Level: intermediate 1475412e9a14SMatthew G. Knepley 1476db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1477412e9a14SMatthew G. Knepley @*/ 1478d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1479d71ae5a4SJacob Faibussowitsch { 1480412e9a14SMatthew G. Knepley IS pIS; 1481412e9a14SMatthew G. Knepley 1482412e9a14SMatthew G. Knepley PetscFunctionBegin; 14839566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 14849566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 14859566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 1486412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1487412e9a14SMatthew G. Knepley } 1488412e9a14SMatthew G. Knepley 1489412e9a14SMatthew G. Knepley /*@ 1490d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1491d123abd9SMatthew G. Knepley 1492d123abd9SMatthew G. Knepley Not collective 1493d123abd9SMatthew G. Knepley 1494d123abd9SMatthew G. Knepley Input Parameters: 1495d123abd9SMatthew G. Knepley + label - The DMLabel 1496d123abd9SMatthew G. Knepley . value - The label value 1497d123abd9SMatthew G. Knepley - p - A point with this value 1498d123abd9SMatthew G. Knepley 1499d123abd9SMatthew G. Knepley Output Parameter: 1500d123abd9SMatthew 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 1501d123abd9SMatthew G. Knepley 1502d123abd9SMatthew G. Knepley Level: intermediate 1503d123abd9SMatthew G. Knepley 1504db781477SPatrick Sanan .seealso: `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1505d123abd9SMatthew G. Knepley @*/ 1506d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1507d71ae5a4SJacob Faibussowitsch { 1508d123abd9SMatthew G. Knepley const PetscInt *indices; 1509d123abd9SMatthew G. Knepley PetscInt v; 1510d123abd9SMatthew G. Knepley 1511d123abd9SMatthew G. Knepley PetscFunctionBegin; 1512d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1513dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 4); 1514d123abd9SMatthew G. Knepley *index = -1; 15159566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 1516d123abd9SMatthew G. Knepley if (v < 0) PetscFunctionReturn(0); 15179566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 15189566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &indices)); 15199566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 15209566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &indices)); 1521d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1522d123abd9SMatthew G. Knepley } 1523d123abd9SMatthew G. Knepley 1524d123abd9SMatthew G. Knepley /*@ 152584f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 152684f0b6dfSMatthew G. Knepley 15275b5e7992SMatthew G. Knepley Not collective 15285b5e7992SMatthew G. Knepley 152984f0b6dfSMatthew G. Knepley Input Parameters: 153084f0b6dfSMatthew G. Knepley + label - the DMLabel 153122cd2cdaSVaclav Hapla . start - the first point kept 153222cd2cdaSVaclav Hapla - end - one more than the last point kept 153384f0b6dfSMatthew G. Knepley 153484f0b6dfSMatthew G. Knepley Level: intermediate 153584f0b6dfSMatthew G. Knepley 1536db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 153784f0b6dfSMatthew G. Knepley @*/ 1538d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1539d71ae5a4SJacob Faibussowitsch { 1540c58f1c22SToby Isaac PetscInt v; 1541c58f1c22SToby Isaac 1542c58f1c22SToby Isaac PetscFunctionBegin; 1543d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15449566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 15459566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 154648a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; ++v) PetscCall(ISGeneralFilter(label->points[v], start, end)); 15479566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 1548c58f1c22SToby Isaac PetscFunctionReturn(0); 1549c58f1c22SToby Isaac } 1550c58f1c22SToby Isaac 155184f0b6dfSMatthew G. Knepley /*@ 155284f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 155384f0b6dfSMatthew G. Knepley 15545b5e7992SMatthew G. Knepley Not collective 15555b5e7992SMatthew G. Knepley 155684f0b6dfSMatthew G. Knepley Input Parameters: 155784f0b6dfSMatthew G. Knepley + label - the DMLabel 155884f0b6dfSMatthew G. Knepley - permutation - the point permutation 155984f0b6dfSMatthew G. Knepley 156084f0b6dfSMatthew G. Knepley Output Parameter: 156184f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 156284f0b6dfSMatthew G. Knepley 156384f0b6dfSMatthew G. Knepley Level: intermediate 156484f0b6dfSMatthew G. Knepley 1565db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 156684f0b6dfSMatthew G. Knepley @*/ 1567d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1568d71ae5a4SJacob Faibussowitsch { 1569c58f1c22SToby Isaac const PetscInt *perm; 1570c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1571c58f1c22SToby Isaac 1572c58f1c22SToby Isaac PetscFunctionBegin; 1573d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1574d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 15759566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 15769566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 15779566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 15789566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 15799566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1580c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1581c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1582ad8374ffSToby Isaac const PetscInt *points; 1583ad8374ffSToby Isaac PetscInt *pointsNew; 1584c58f1c22SToby Isaac 15859566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 15869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &pointsNew)); 1587c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1588ad8374ffSToby Isaac const PetscInt point = points[q]; 1589c58f1c22SToby Isaac 159063a3b9bcSJacob 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); 1591ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1592c58f1c22SToby Isaac } 15939566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 15949566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 15959566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1596fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 15979566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 15989566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1599fa8e8ae5SToby Isaac } else { 16009566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1601fa8e8ae5SToby Isaac } 16029566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1603c58f1c22SToby Isaac } 16049566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1605c58f1c22SToby Isaac if (label->bt) { 16069566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 16079566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1608c58f1c22SToby Isaac } 1609c58f1c22SToby Isaac PetscFunctionReturn(0); 1610c58f1c22SToby Isaac } 1611c58f1c22SToby Isaac 1612d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 1613d71ae5a4SJacob Faibussowitsch { 161426c55118SMichael Lange MPI_Comm comm; 1615eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 161626c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 161726c55118SMichael Lange PetscSection rootSection; 161826c55118SMichael Lange PetscSF labelSF; 161926c55118SMichael Lange 162026c55118SMichael Lange PetscFunctionBegin; 16219566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 16229566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 162326c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 162426c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 16259566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 16269566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 16279566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 162826c55118SMichael Lange if (label) { 162926c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1630ad8374ffSToby Isaac const PetscInt *points; 1631ad8374ffSToby Isaac 16329566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 163348a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 16349566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 163526c55118SMichael Lange } 163626c55118SMichael Lange } 16379566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 163826c55118SMichael Lange /* Create a point-wise array of stratum values */ 16399566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 16409566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 16419566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 164226c55118SMichael Lange if (label) { 164326c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1644ad8374ffSToby Isaac const PetscInt *points; 1645ad8374ffSToby Isaac 16469566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 164726c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1648ad8374ffSToby Isaac const PetscInt p = points[l]; 16499566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 165026c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 165126c55118SMichael Lange } 16529566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 165326c55118SMichael Lange } 165426c55118SMichael Lange } 165526c55118SMichael Lange /* Build SF that maps label points to remote processes */ 16569566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 16579566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 16589566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 16599566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 166026c55118SMichael Lange /* Send the strata for each point over the derived SF */ 16619566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 16629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 16639566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 16649566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 166526c55118SMichael Lange /* Clean up */ 16669566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 16679566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 16689566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 16699566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 167026c55118SMichael Lange PetscFunctionReturn(0); 167126c55118SMichael Lange } 167226c55118SMichael Lange 167384f0b6dfSMatthew G. Knepley /*@ 167484f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 167584f0b6dfSMatthew G. Knepley 16765b5e7992SMatthew G. Knepley Collective on sf 16775b5e7992SMatthew G. Knepley 167884f0b6dfSMatthew G. Knepley Input Parameters: 167984f0b6dfSMatthew G. Knepley + label - the DMLabel 168084f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 168184f0b6dfSMatthew G. Knepley 168284f0b6dfSMatthew G. Knepley Output Parameter: 168384f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 168484f0b6dfSMatthew G. Knepley 168584f0b6dfSMatthew G. Knepley Level: intermediate 168684f0b6dfSMatthew G. Knepley 1687db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 168884f0b6dfSMatthew G. Knepley @*/ 1689d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1690d71ae5a4SJacob Faibussowitsch { 1691c58f1c22SToby Isaac MPI_Comm comm; 169226c55118SMichael Lange PetscSection leafSection; 169326c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 169426c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1695ad8374ffSToby Isaac PetscInt **points; 1696d67d17b1SMatthew G. Knepley const char *lname = NULL; 1697c58f1c22SToby Isaac char *name; 1698c58f1c22SToby Isaac PetscInt nameSize; 1699e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1700c58f1c22SToby Isaac size_t len = 0; 170126c55118SMichael Lange PetscMPIInt rank; 1702c58f1c22SToby Isaac 1703c58f1c22SToby Isaac PetscFunctionBegin; 1704d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1705f018e600SMatthew G. Knepley if (label) { 1706f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 17079566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1708f018e600SMatthew G. Knepley } 17099566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 17109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1711c58f1c22SToby Isaac /* Bcast name */ 1712dd400576SPatrick Sanan if (rank == 0) { 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 17149566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1715d67d17b1SMatthew G. Knepley } 1716c58f1c22SToby Isaac nameSize = len; 17179566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 17189566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 17199566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 17209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 17219566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 17229566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 172377d236dfSMichael Lange /* Bcast defaultValue */ 1724dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 17259566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 172626c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 17279566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 17285cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 17299566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 17309566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 17319566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 17329566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 17339566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1734ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 17359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 17365cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 17375cbdf6fcSMichael Lange offset = 0; 17389566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 17399566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 174048a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 17415cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1742231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 17439371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 17449371c9d4SSatish Balay leafStrata[p] = s; 17459371c9d4SSatish Balay break; 17469371c9d4SSatish Balay } 17475cbdf6fcSMichael Lange } 17485cbdf6fcSMichael Lange } 1749c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 17509566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 17519566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1752c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 17539566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1755ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1756c58f1c22SToby Isaac } 17579566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 17589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 17599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &points)); 1760c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 17619566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 17629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]))); 1763c58f1c22SToby Isaac } 1764c58f1c22SToby Isaac /* Insert points into new strata */ 17659566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 17669566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1767c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 17689566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17699566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1770c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1771c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1772ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1773c58f1c22SToby Isaac } 1774c58f1c22SToby Isaac } 1775ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 17769566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &(points[s][0]), PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 17779566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1778ad8374ffSToby Isaac } 17799566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 17809566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 17819566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 17829566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 17839566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 1784c58f1c22SToby Isaac PetscFunctionReturn(0); 1785c58f1c22SToby Isaac } 1786c58f1c22SToby Isaac 17877937d9ceSMichael Lange /*@ 17887937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 17897937d9ceSMichael Lange 17905b5e7992SMatthew G. Knepley Collective on sf 17915b5e7992SMatthew G. Knepley 17927937d9ceSMichael Lange Input Parameters: 17937937d9ceSMichael Lange + label - the DMLabel 179484f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 17957937d9ceSMichael Lange 179684f0b6dfSMatthew G. Knepley Output Parameters: 179784f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 17987937d9ceSMichael Lange 17997937d9ceSMichael Lange Level: developer 18007937d9ceSMichael Lange 18017937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 18027937d9ceSMichael Lange 1803db781477SPatrick Sanan .seealso: `DMLabelDistribute()` 18047937d9ceSMichael Lange @*/ 1805d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 1806d71ae5a4SJacob Faibussowitsch { 18077937d9ceSMichael Lange MPI_Comm comm; 18087937d9ceSMichael Lange PetscSection rootSection; 18097937d9ceSMichael Lange PetscSF sfLabel; 18107937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 18117937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 18127937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 18137937d9ceSMichael Lange PetscInt *rootStrata; 1814d67d17b1SMatthew G. Knepley const char *lname; 18157937d9ceSMichael Lange char *name; 18167937d9ceSMichael Lange PetscInt nameSize; 18177937d9ceSMichael Lange size_t len = 0; 18189852e123SBarry Smith PetscMPIInt rank, size; 18197937d9ceSMichael Lange 18207937d9ceSMichael Lange PetscFunctionBegin; 1821d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1822d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 18239566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 18249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 18259566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 18267937d9ceSMichael Lange /* Bcast name */ 1827dd400576SPatrick Sanan if (rank == 0) { 18289566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 18299566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1830d67d17b1SMatthew G. Knepley } 18317937d9ceSMichael Lange nameSize = len; 18329566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 18339566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 18349566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 18359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 18369566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 18379566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 18387937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 18397937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 18407937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 18419566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 18429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1843dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 18447937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 18458212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 18468212dd46SStefano Zampini 18478212dd46SStefano Zampini leafPoints[ilp].index = ilp; 18488212dd46SStefano Zampini leafPoints[ilp].rank = rank; 18497937d9ceSMichael Lange } 18509566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 18519566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 18527937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 18539566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 18549566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 18559566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 18569566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 18579566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 18587937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 18599566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 18607937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 18617937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 18627937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 18639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 18649566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 18659566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 18667937d9ceSMichael Lange } 18677937d9ceSMichael Lange idx += rootDegree[p]; 18687937d9ceSMichael Lange } 18699566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 18709566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 18719566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 18729566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 18737937d9ceSMichael Lange PetscFunctionReturn(0); 18747937d9ceSMichael Lange } 18757937d9ceSMichael Lange 1876d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1877d71ae5a4SJacob Faibussowitsch { 1878d42890abSMatthew G. Knepley const PetscInt *degree; 1879d42890abSMatthew G. Knepley const PetscInt *points; 1880d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1881d42890abSMatthew G. Knepley 1882d42890abSMatthew G. Knepley PetscFunctionBegin; 1883d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1884d42890abSMatthew G. Knepley /* Add in leaves */ 1885d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1886d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1887d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 1888d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 1889d42890abSMatthew G. Knepley } 1890d42890abSMatthew G. Knepley /* Add in shared roots */ 1891d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1892d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1893d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1894d42890abSMatthew G. Knepley if (degree[r]) { 1895d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1896d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 1897d42890abSMatthew G. Knepley } 1898d42890abSMatthew G. Knepley } 1899d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1900d42890abSMatthew G. Knepley } 1901d42890abSMatthew G. Knepley 1902d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 1903d71ae5a4SJacob Faibussowitsch { 1904d42890abSMatthew G. Knepley const PetscInt *degree; 1905d42890abSMatthew G. Knepley const PetscInt *points; 1906d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1907d42890abSMatthew G. Knepley 1908d42890abSMatthew G. Knepley PetscFunctionBegin; 1909d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1910d42890abSMatthew G. Knepley /* Read out leaves */ 1911d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1912d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1913d42890abSMatthew G. Knepley const PetscInt p = points[l]; 1914d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 1915d42890abSMatthew G. Knepley 1916d42890abSMatthew G. Knepley if (cval != defVal) { 1917d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 1918d42890abSMatthew G. Knepley if (val == defVal) { 1919d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 192048a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 1921d42890abSMatthew G. Knepley } 1922d42890abSMatthew G. Knepley } 1923d42890abSMatthew G. Knepley } 1924d42890abSMatthew G. Knepley /* Read out shared roots */ 1925d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1926d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1927d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1928d42890abSMatthew G. Knepley if (degree[r]) { 1929d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 1930d42890abSMatthew G. Knepley 1931d42890abSMatthew G. Knepley if (cval != defVal) { 1932d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1933d42890abSMatthew G. Knepley if (val == defVal) { 1934d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 193548a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 1936d42890abSMatthew G. Knepley } 1937d42890abSMatthew G. Knepley } 1938d42890abSMatthew G. Knepley } 1939d42890abSMatthew G. Knepley } 1940d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1941d42890abSMatthew G. Knepley } 1942d42890abSMatthew G. Knepley 1943d42890abSMatthew G. Knepley /*@ 1944d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 1945d42890abSMatthew G. Knepley 1946d42890abSMatthew G. Knepley Collective on sf 1947d42890abSMatthew G. Knepley 1948d42890abSMatthew G. Knepley Input Parameters: 1949d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1950d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1951d42890abSMatthew G. Knepley 1952d42890abSMatthew G. Knepley Level: intermediate 1953d42890abSMatthew G. Knepley 1954db781477SPatrick Sanan .seealso: `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 1955d42890abSMatthew G. Knepley @*/ 1956d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 1957d71ae5a4SJacob Faibussowitsch { 1958d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 1959d42890abSMatthew G. Knepley PetscMPIInt size; 1960d42890abSMatthew G. Knepley 1961d42890abSMatthew G. Knepley PetscFunctionBegin; 1962d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 1963d42890abSMatthew G. Knepley if (size > 1) { 1964d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1965d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 1966d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 1967d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 1968d42890abSMatthew G. Knepley } 1969d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1970d42890abSMatthew G. Knepley } 1971d42890abSMatthew G. Knepley 1972d42890abSMatthew G. Knepley /*@ 1973d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 1974d42890abSMatthew G. Knepley 1975d42890abSMatthew G. Knepley Collective on sf 1976d42890abSMatthew G. Knepley 1977d42890abSMatthew G. Knepley Input Parameters: 1978d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1979d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1980d42890abSMatthew G. Knepley 1981d42890abSMatthew G. Knepley Level: intermediate 1982d42890abSMatthew G. Knepley 1983db781477SPatrick Sanan .seealso: `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 1984d42890abSMatthew G. Knepley @*/ 1985d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 1986d71ae5a4SJacob Faibussowitsch { 1987d42890abSMatthew G. Knepley PetscFunctionBegin; 1988d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 1989d42890abSMatthew G. Knepley label->propArray = NULL; 1990d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1991d42890abSMatthew G. Knepley } 1992d42890abSMatthew G. Knepley 1993d42890abSMatthew G. Knepley /*@C 1994d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 1995d42890abSMatthew G. Knepley 1996d42890abSMatthew G. Knepley Collective on sf 1997d42890abSMatthew G. Knepley 1998d42890abSMatthew G. Knepley Input Parameters: 1999d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 2000d42890abSMatthew G. Knepley . sf - The SF describing parallel layout of the label points 2001ef1023bdSBarry Smith . markPoint - An optional callback that is called when a point is marked, or NULL 2002d42890abSMatthew G. Knepley - ctx - An optional user context for the callback, or NULL 2003d42890abSMatthew G. Knepley 2004d42890abSMatthew G. Knepley Calling sequence of markPoint: 2005d42890abSMatthew G. Knepley $ markPoint(DMLabel label, PetscInt p, PetscInt val, void *ctx); 2006d42890abSMatthew G. Knepley 2007d42890abSMatthew G. Knepley + label - The DMLabel 2008d42890abSMatthew G. Knepley . p - The point being marked 2009d42890abSMatthew G. Knepley . val - The label value for p 2010d42890abSMatthew G. Knepley - ctx - An optional user context 2011d42890abSMatthew G. Knepley 2012d42890abSMatthew G. Knepley Level: intermediate 2013d42890abSMatthew G. Knepley 2014db781477SPatrick Sanan .seealso: `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2015d42890abSMatthew G. Knepley @*/ 2016d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 2017d71ae5a4SJacob Faibussowitsch { 2018c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2019d42890abSMatthew G. Knepley PetscMPIInt size; 2020d42890abSMatthew G. Knepley 2021d42890abSMatthew G. Knepley PetscFunctionBegin; 2022d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 2023c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2024c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2025d42890abSMatthew G. Knepley /* Communicate marked edges 2026d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2027d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2028d42890abSMatthew G. Knepley 2029d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2030d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2031d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2032d42890abSMatthew G. Knepley 2033d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2034d42890abSMatthew 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 2035d42890abSMatthew G. Knepley edge to the queue. 2036d42890abSMatthew G. Knepley */ 2037d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2038d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2039d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2040d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2041d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 2042d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2043d42890abSMatthew G. Knepley } 2044d42890abSMatthew G. Knepley PetscFunctionReturn(0); 2045d42890abSMatthew G. Knepley } 2046d42890abSMatthew G. Knepley 204784f0b6dfSMatthew G. Knepley /*@ 204884f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 204984f0b6dfSMatthew G. Knepley 20505b5e7992SMatthew G. Knepley Not collective 20515b5e7992SMatthew G. Knepley 205284f0b6dfSMatthew G. Knepley Input Parameter: 205384f0b6dfSMatthew G. Knepley . label - the DMLabel 205484f0b6dfSMatthew G. Knepley 205584f0b6dfSMatthew G. Knepley Output Parameters: 205684f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 205784f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 205884f0b6dfSMatthew G. Knepley 205984f0b6dfSMatthew G. Knepley Level: developer 206084f0b6dfSMatthew G. Knepley 2061db781477SPatrick Sanan .seealso: `DMLabelDistribute()` 206284f0b6dfSMatthew G. Knepley @*/ 2063d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2064d71ae5a4SJacob Faibussowitsch { 2065c58f1c22SToby Isaac IS vIS; 2066c58f1c22SToby Isaac const PetscInt *values; 2067c58f1c22SToby Isaac PetscInt *points; 2068c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2069c58f1c22SToby Isaac 2070c58f1c22SToby Isaac PetscFunctionBegin; 2071d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 20729566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 20739566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 20749566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 20759371c9d4SSatish Balay if (nV) { 20769371c9d4SSatish Balay vS = values[0]; 20779371c9d4SSatish Balay vE = values[0] + 1; 20789371c9d4SSatish Balay } 2079c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2080c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2081c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2082c58f1c22SToby Isaac } 20839566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 20849566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2085c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2086c58f1c22SToby Isaac PetscInt n; 2087c58f1c22SToby Isaac 20889566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 20899566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2090c58f1c22SToby Isaac } 20919566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 20929566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 20939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2094c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2095c58f1c22SToby Isaac IS is; 2096c58f1c22SToby Isaac const PetscInt *spoints; 2097c58f1c22SToby Isaac PetscInt dof, off, p; 2098c58f1c22SToby Isaac 20999566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 21009566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 21019566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 21029566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2103c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 21049566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 21059566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2106c58f1c22SToby Isaac } 21079566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 21089566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 21099566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 2110c58f1c22SToby Isaac PetscFunctionReturn(0); 2111c58f1c22SToby Isaac } 2112c58f1c22SToby Isaac 211384f0b6dfSMatthew G. Knepley /*@ 2114c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 2115c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 2116c58f1c22SToby Isaac 21175b5e7992SMatthew G. Knepley Collective on sf 21185b5e7992SMatthew G. Knepley 2119c58f1c22SToby Isaac Input Parameters: 2120c58f1c22SToby Isaac + s - The PetscSection for the local field layout 2121c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 2122c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 2123c58f1c22SToby Isaac . label - The label specifying the points 2124c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2125c58f1c22SToby Isaac 2126c58f1c22SToby Isaac Output Parameter: 2127c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 2128c58f1c22SToby Isaac 2129c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 2130c58f1c22SToby Isaac 2131c58f1c22SToby Isaac Level: developer 2132c58f1c22SToby Isaac 2133db781477SPatrick Sanan .seealso: `PetscSectionCreate()` 2134c58f1c22SToby Isaac @*/ 2135d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2136d71ae5a4SJacob Faibussowitsch { 2137c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2138c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2139c58f1c22SToby Isaac 2140c58f1c22SToby Isaac PetscFunctionBegin; 2141d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2142d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2143d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 21449566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 21459566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 21469566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 21479566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2148c58f1c22SToby Isaac if (nroots >= 0) { 214963a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 21509566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2151c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 21529566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2153c58f1c22SToby Isaac } else { 2154c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2155c58f1c22SToby Isaac } 2156c58f1c22SToby Isaac } 2157c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2158c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2159c58f1c22SToby Isaac PetscInt value; 2160c58f1c22SToby Isaac 21619566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2162c58f1c22SToby Isaac if (value != labelValue) continue; 21639566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 21649566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 21659566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 21669566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2167c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2168c58f1c22SToby Isaac } 21699566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2170c58f1c22SToby Isaac if (nroots >= 0) { 21719566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 21729566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2173c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 21749371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 21759371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 21769371c9d4SSatish Balay } 2177c58f1c22SToby Isaac } 2178c58f1c22SToby Isaac } 2179c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 2180c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2181c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2182c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2183c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2184c58f1c22SToby Isaac } 21859566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2186c58f1c22SToby Isaac globalOff -= off; 2187c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2188c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2189c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2190c58f1c22SToby Isaac } 2191c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2192c58f1c22SToby Isaac if (nroots >= 0) { 21939566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 21949566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2195c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 21969371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 21979371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 21989371c9d4SSatish Balay } 2199c58f1c22SToby Isaac } 2200c58f1c22SToby Isaac } 22019566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 22029566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 2203c58f1c22SToby Isaac PetscFunctionReturn(0); 2204c58f1c22SToby Isaac } 2205c58f1c22SToby Isaac 22069371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 22075fdea053SToby Isaac DMLabel label; 22085fdea053SToby Isaac PetscCopyMode *modes; 22095fdea053SToby Isaac PetscInt *sizes; 22105fdea053SToby Isaac const PetscInt ***perms; 22115fdea053SToby Isaac const PetscScalar ***rots; 22125fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 22135fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 22145fdea053SToby Isaac } PetscSectionSym_Label; 22155fdea053SToby Isaac 2216d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 2217d71ae5a4SJacob Faibussowitsch { 22185fdea053SToby Isaac PetscInt i, j; 22195fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 22205fdea053SToby Isaac 22215fdea053SToby Isaac PetscFunctionBegin; 22225fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22235fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 22245fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 22259566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 22269566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 22275fdea053SToby Isaac } 22285fdea053SToby Isaac if (sl->perms[i]) { 22295fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 22305fdea053SToby Isaac 22319566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 22325fdea053SToby Isaac } 22335fdea053SToby Isaac if (sl->rots[i]) { 22345fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 22355fdea053SToby Isaac 22369566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 22375fdea053SToby Isaac } 22385fdea053SToby Isaac } 22395fdea053SToby Isaac } 22409566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 22419566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 22425fdea053SToby Isaac sl->numStrata = 0; 22435fdea053SToby Isaac PetscFunctionReturn(0); 22445fdea053SToby Isaac } 22455fdea053SToby Isaac 2246d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 2247d71ae5a4SJacob Faibussowitsch { 22485fdea053SToby Isaac PetscFunctionBegin; 22499566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 22509566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 22515fdea053SToby Isaac PetscFunctionReturn(0); 22525fdea053SToby Isaac } 22535fdea053SToby Isaac 2254d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 2255d71ae5a4SJacob Faibussowitsch { 22565fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 22575fdea053SToby Isaac PetscBool isAscii; 22585fdea053SToby Isaac DMLabel label = sl->label; 2259d67d17b1SMatthew G. Knepley const char *name; 22605fdea053SToby Isaac 22615fdea053SToby Isaac PetscFunctionBegin; 22629566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 22635fdea053SToby Isaac if (isAscii) { 22645fdea053SToby Isaac PetscInt i, j, k; 22655fdea053SToby Isaac PetscViewerFormat format; 22665fdea053SToby Isaac 22679566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 22685fdea053SToby Isaac if (label) { 22699566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 22705fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22719566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22729566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 22739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22745fdea053SToby Isaac } else { 22759566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 22769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 22775fdea053SToby Isaac } 22785fdea053SToby Isaac } else { 22799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 22805fdea053SToby Isaac } 22819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22825fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22835fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 22845fdea053SToby Isaac 22855fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 228663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 22875fdea053SToby Isaac } else { 228863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 22899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 229063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 22915fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22935fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 22945fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 229563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 22965fdea053SToby Isaac } else { 22975fdea053SToby Isaac PetscInt tab; 22985fdea053SToby Isaac 229963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 23009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 23019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 23025fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 23039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 23049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 230563a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 23069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 23079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 23085fdea053SToby Isaac } 23095fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 23109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 23119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 23125fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 231363a3b9bcSJacob 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]))); 23145fdea053SToby Isaac #else 231563a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 23165fdea053SToby Isaac #endif 23179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 23189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 23195fdea053SToby Isaac } 23209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23215fdea053SToby Isaac } 23225fdea053SToby Isaac } 23239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23245fdea053SToby Isaac } 23259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23265fdea053SToby Isaac } 23275fdea053SToby Isaac } 23289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23295fdea053SToby Isaac } 23305fdea053SToby Isaac PetscFunctionReturn(0); 23315fdea053SToby Isaac } 23325fdea053SToby Isaac 23335fdea053SToby Isaac /*@ 23345fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 23355fdea053SToby Isaac 23365fdea053SToby Isaac Logically collective on sym 23375fdea053SToby Isaac 23385fdea053SToby Isaac Input parameters: 23395fdea053SToby Isaac + sym - the section symmetries 23405fdea053SToby Isaac - label - the DMLabel describing the types of points 23415fdea053SToby Isaac 23425fdea053SToby Isaac Level: developer: 23435fdea053SToby Isaac 2344db781477SPatrick Sanan .seealso: `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 23455fdea053SToby Isaac @*/ 2346d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 2347d71ae5a4SJacob Faibussowitsch { 23485fdea053SToby Isaac PetscSectionSym_Label *sl; 23495fdea053SToby Isaac 23505fdea053SToby Isaac PetscFunctionBegin; 23515fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 23525fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 23539566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 23545fdea053SToby Isaac if (label) { 23555fdea053SToby Isaac sl->label = label; 23569566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 23579566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 23589566063dSJacob 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)); 23599566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 23609566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 23619566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 23629566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 23639566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 23645fdea053SToby Isaac } 23655fdea053SToby Isaac PetscFunctionReturn(0); 23665fdea053SToby Isaac } 23675fdea053SToby Isaac 23685fdea053SToby Isaac /*@C 2369b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2370b004864fSMatthew G. Knepley 2371b004864fSMatthew G. Knepley Logically collective on sym 2372b004864fSMatthew G. Knepley 2373b004864fSMatthew G. Knepley Input Parameters: 2374b004864fSMatthew G. Knepley + sym - the section symmetries 2375b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2376b004864fSMatthew G. Knepley 2377b004864fSMatthew G. Knepley Output Parameters: 2378b004864fSMatthew G. Knepley + size - the number of dofs for points in the stratum of the label 2379b004864fSMatthew G. Knepley . minOrient - the smallest orientation for a point in this stratum 2380b004864fSMatthew G. Knepley . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 2381b004864fSMatthew G. Knepley . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2382b004864fSMatthew G. Knepley - 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 2383b004864fSMatthew G. Knepley 2384b004864fSMatthew G. Knepley Level: developer 2385b004864fSMatthew G. Knepley 2386db781477SPatrick Sanan .seealso: `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2387b004864fSMatthew G. Knepley @*/ 2388d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2389d71ae5a4SJacob Faibussowitsch { 2390b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2391b004864fSMatthew G. Knepley const char *name; 2392b004864fSMatthew G. Knepley PetscInt i; 2393b004864fSMatthew G. Knepley 2394b004864fSMatthew G. Knepley PetscFunctionBegin; 2395b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2396b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2397b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2398b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2399b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2400b004864fSMatthew G. Knepley 2401b004864fSMatthew G. Knepley if (stratum == value) break; 2402b004864fSMatthew G. Knepley } 24039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2404b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 24059371c9d4SSatish Balay if (size) { 24069371c9d4SSatish Balay PetscValidIntPointer(size, 3); 24079371c9d4SSatish Balay *size = sl->sizes[i]; 24089371c9d4SSatish Balay } 24099371c9d4SSatish Balay if (minOrient) { 24109371c9d4SSatish Balay PetscValidIntPointer(minOrient, 4); 24119371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 24129371c9d4SSatish Balay } 24139371c9d4SSatish Balay if (maxOrient) { 24149371c9d4SSatish Balay PetscValidIntPointer(maxOrient, 5); 24159371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 24169371c9d4SSatish Balay } 24179371c9d4SSatish Balay if (perms) { 24189371c9d4SSatish Balay PetscValidPointer(perms, 6); 24199371c9d4SSatish Balay *perms = sl->perms[i] ? &sl->perms[i][sl->minMaxOrients[i][0]] : NULL; 24209371c9d4SSatish Balay } 24219371c9d4SSatish Balay if (rots) { 24229371c9d4SSatish Balay PetscValidPointer(rots, 7); 24239371c9d4SSatish Balay *rots = sl->rots[i] ? &sl->rots[i][sl->minMaxOrients[i][0]] : NULL; 24249371c9d4SSatish Balay } 2425b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2426b004864fSMatthew G. Knepley } 2427b004864fSMatthew G. Knepley 2428b004864fSMatthew G. Knepley /*@C 24295fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 24305fdea053SToby Isaac 24315b5e7992SMatthew G. Knepley Logically collective on sym 24325fdea053SToby Isaac 24335fdea053SToby Isaac InputParameters: 24345b5e7992SMatthew G. Knepley + sym - the section symmetries 24355fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 24365fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 24375fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 24385fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 24395fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 24405fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2441a2b725a8SWilliam Gropp - 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 24425fdea053SToby Isaac 24435fdea053SToby Isaac Level: developer 24445fdea053SToby Isaac 2445db781477SPatrick Sanan .seealso: `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 24465fdea053SToby Isaac @*/ 2447d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 2448d71ae5a4SJacob Faibussowitsch { 24495fdea053SToby Isaac PetscSectionSym_Label *sl; 2450d67d17b1SMatthew G. Knepley const char *name; 2451d67d17b1SMatthew G. Knepley PetscInt i, j, k; 24525fdea053SToby Isaac 24535fdea053SToby Isaac PetscFunctionBegin; 24545fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 24555fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2456b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 24575fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24585fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 24595fdea053SToby Isaac 24605fdea053SToby Isaac if (stratum == value) break; 24615fdea053SToby Isaac } 24629566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 246363a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 24645fdea053SToby Isaac sl->sizes[i] = size; 24655fdea053SToby Isaac sl->modes[i] = mode; 24665fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 24675fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 24685fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 24695fdea053SToby Isaac if (perms) { 24705fdea053SToby Isaac PetscInt **ownPerms; 24715fdea053SToby Isaac 24729566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 24735fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 24745fdea053SToby Isaac if (perms[j]) { 24759566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2476ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 24775fdea053SToby Isaac } 24785fdea053SToby Isaac } 24795fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 24805fdea053SToby Isaac } 24815fdea053SToby Isaac if (rots) { 24825fdea053SToby Isaac PetscScalar **ownRots; 24835fdea053SToby Isaac 24849566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 24855fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 24865fdea053SToby Isaac if (rots[j]) { 24879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2488ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 24895fdea053SToby Isaac } 24905fdea053SToby Isaac } 24915fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 24925fdea053SToby Isaac } 24935fdea053SToby Isaac } else { 24945fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 24955fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 24965fdea053SToby Isaac } 24975fdea053SToby Isaac PetscFunctionReturn(0); 24985fdea053SToby Isaac } 24995fdea053SToby Isaac 2500d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 2501d71ae5a4SJacob Faibussowitsch { 25025fdea053SToby Isaac PetscInt i, j, numStrata; 25035fdea053SToby Isaac PetscSectionSym_Label *sl; 25045fdea053SToby Isaac DMLabel label; 25055fdea053SToby Isaac 25065fdea053SToby Isaac PetscFunctionBegin; 25075fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 25085fdea053SToby Isaac numStrata = sl->numStrata; 25095fdea053SToby Isaac label = sl->label; 25105fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 25115fdea053SToby Isaac PetscInt point = points[2 * i]; 25125fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 25135fdea053SToby Isaac 25145fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 25155fdea053SToby Isaac if (label->validIS[j]) { 25165fdea053SToby Isaac PetscInt k; 25175fdea053SToby Isaac 25189566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j], point, &k)); 25195fdea053SToby Isaac if (k >= 0) break; 25205fdea053SToby Isaac } else { 25215fdea053SToby Isaac PetscBool has; 25225fdea053SToby Isaac 25239566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 25245fdea053SToby Isaac if (has) break; 25255fdea053SToby Isaac } 25265fdea053SToby Isaac } 25279371c9d4SSatish 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], 25289371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2529ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2530ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 25315fdea053SToby Isaac } 25325fdea053SToby Isaac PetscFunctionReturn(0); 25335fdea053SToby Isaac } 25345fdea053SToby Isaac 2535d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2536d71ae5a4SJacob Faibussowitsch { 2537b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2538b004864fSMatthew G. Knepley IS valIS; 2539b004864fSMatthew G. Knepley const PetscInt *values; 2540b004864fSMatthew G. Knepley PetscInt Nv, v; 2541b004864fSMatthew G. Knepley 2542b004864fSMatthew G. Knepley PetscFunctionBegin; 25439566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 25449566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 25459566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2546b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2547b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2548b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2549b004864fSMatthew G. Knepley const PetscInt **perms; 2550b004864fSMatthew G. Knepley const PetscScalar **rots; 2551b004864fSMatthew G. Knepley 25529566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 25539566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2554b004864fSMatthew G. Knepley } 25559566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 2556b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2557b004864fSMatthew G. Knepley } 2558b004864fSMatthew G. Knepley 2559d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2560d71ae5a4SJacob Faibussowitsch { 2561b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2562b004864fSMatthew G. Knepley DMLabel dlabel; 2563b004864fSMatthew G. Knepley 2564b004864fSMatthew G. Knepley PetscFunctionBegin; 25659566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 25669566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 25679566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 25689566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 2569b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2570b004864fSMatthew G. Knepley } 2571b004864fSMatthew G. Knepley 2572d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 2573d71ae5a4SJacob Faibussowitsch { 25745fdea053SToby Isaac PetscSectionSym_Label *sl; 25755fdea053SToby Isaac 25765fdea053SToby Isaac PetscFunctionBegin; 25774dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 25785fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2579b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2580b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 25815fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 25825fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 25835fdea053SToby Isaac sym->data = (void *)sl; 25845fdea053SToby Isaac PetscFunctionReturn(0); 25855fdea053SToby Isaac } 25865fdea053SToby Isaac 25875fdea053SToby Isaac /*@ 25885fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 25895fdea053SToby Isaac 25905fdea053SToby Isaac Collective 25915fdea053SToby Isaac 25925fdea053SToby Isaac Input Parameters: 25935fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 25945fdea053SToby Isaac - label - the label defining the strata 25955fdea053SToby Isaac 25965fdea053SToby Isaac Output Parameters: 25975fdea053SToby Isaac . sym - the section symmetries 25985fdea053SToby Isaac 25995fdea053SToby Isaac Level: developer 26005fdea053SToby Isaac 2601db781477SPatrick Sanan .seealso: `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 26025fdea053SToby Isaac @*/ 2603d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 2604d71ae5a4SJacob Faibussowitsch { 26055fdea053SToby Isaac PetscFunctionBegin; 26069566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 26079566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 26089566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 26099566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 26105fdea053SToby Isaac PetscFunctionReturn(0); 26115fdea053SToby Isaac } 2612