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 @*/ 279371c9d4SSatish Balay PetscErrorCode DMLabelCreate(MPI_Comm comm, const char name[], DMLabel *label) { 28c58f1c22SToby Isaac PetscFunctionBegin; 29064a246eSJacob Faibussowitsch PetscValidPointer(label, 3); 309566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 31c58f1c22SToby Isaac 329566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(*label, DMLABEL_CLASSID, "DMLabel", "DMLabel", "DM", comm, DMLabelDestroy, DMLabelView)); 33d67d17b1SMatthew G. Knepley 34c58f1c22SToby Isaac (*label)->numStrata = 0; 355aa44df4SToby Isaac (*label)->defaultValue = -1; 36c58f1c22SToby Isaac (*label)->stratumValues = NULL; 37ad8374ffSToby Isaac (*label)->validIS = NULL; 38c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 39c58f1c22SToby Isaac (*label)->points = NULL; 40c58f1c22SToby Isaac (*label)->ht = NULL; 41c58f1c22SToby Isaac (*label)->pStart = -1; 42c58f1c22SToby Isaac (*label)->pEnd = -1; 43c58f1c22SToby Isaac (*label)->bt = NULL; 449566063dSJacob Faibussowitsch PetscCall(PetscHMapICreate(&(*label)->hmap)); 459566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*label, name)); 46c58f1c22SToby Isaac PetscFunctionReturn(0); 47c58f1c22SToby Isaac } 48c58f1c22SToby Isaac 49c58f1c22SToby Isaac /* 50c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 51c58f1c22SToby Isaac 525b5e7992SMatthew G. Knepley Not collective 535b5e7992SMatthew G. Knepley 54c58f1c22SToby Isaac Input parameter: 55c58f1c22SToby Isaac + label - The DMLabel 56c58f1c22SToby Isaac - v - The stratum value 57c58f1c22SToby Isaac 58c58f1c22SToby Isaac Output parameter: 59c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format 60c58f1c22SToby Isaac 61c58f1c22SToby Isaac Level: developer 62c58f1c22SToby Isaac 63db781477SPatrick Sanan .seealso: `DMLabelCreate()` 64c58f1c22SToby Isaac */ 659371c9d4SSatish Balay static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) { 66277ea44aSLisandro Dalcin IS is; 67b9907514SLisandro Dalcin PetscInt off = 0, *pointArray, p; 68c58f1c22SToby Isaac 69b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) return 0; 70c58f1c22SToby Isaac PetscFunctionBegin; 711dca8a05SBarry 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); 729566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v])); 739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->stratumSizes[v], &pointArray)); 749566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(label->ht[v], &off, pointArray)); 759566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 769566063dSJacob Faibussowitsch PetscCall(PetscSortInt(label->stratumSizes[v], pointArray)); 77c58f1c22SToby Isaac if (label->bt) { 78c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 79ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 8063a3b9bcSJacob 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); 819566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 82c58f1c22SToby Isaac } 83c58f1c22SToby Isaac } 84ba2698f1SMatthew G. Knepley if (label->stratumSizes[v] > 0 && pointArray[label->stratumSizes[v] - 1] == pointArray[0] + label->stratumSizes[v] - 1) { 859566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, label->stratumSizes[v], pointArray[0], 1, &is)); 869566063dSJacob Faibussowitsch PetscCall(PetscFree(pointArray)); 87ba2698f1SMatthew G. Knepley } else { 889566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is)); 89ba2698f1SMatthew G. Knepley } 909566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)is, "indices")); 91277ea44aSLisandro Dalcin label->points[v] = is; 92ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 939566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 94c58f1c22SToby Isaac PetscFunctionReturn(0); 95c58f1c22SToby Isaac } 96c58f1c22SToby Isaac 97c58f1c22SToby Isaac /* 98c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 99c58f1c22SToby Isaac 1005b5e7992SMatthew G. Knepley Not collective 1015b5e7992SMatthew G. Knepley 102c58f1c22SToby Isaac Input parameter: 103c58f1c22SToby Isaac . label - The DMLabel 104c58f1c22SToby Isaac 105c58f1c22SToby Isaac Output parameter: 106c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format 107c58f1c22SToby Isaac 108c58f1c22SToby Isaac Level: developer 109c58f1c22SToby Isaac 110db781477SPatrick Sanan .seealso: `DMLabelCreate()` 111c58f1c22SToby Isaac */ 1129371c9d4SSatish Balay static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) { 113c58f1c22SToby Isaac PetscInt v; 114c58f1c22SToby Isaac 115c58f1c22SToby Isaac PetscFunctionBegin; 11648a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeValid_Private(label, v)); 117c58f1c22SToby Isaac PetscFunctionReturn(0); 118c58f1c22SToby Isaac } 119c58f1c22SToby Isaac 120c58f1c22SToby Isaac /* 121c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 122c58f1c22SToby Isaac 1235b5e7992SMatthew G. Knepley Not collective 1245b5e7992SMatthew G. Knepley 125c58f1c22SToby Isaac Input parameter: 126c58f1c22SToby Isaac + label - The DMLabel 127c58f1c22SToby Isaac - v - The stratum value 128c58f1c22SToby Isaac 129c58f1c22SToby Isaac Output parameter: 130c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format 131c58f1c22SToby Isaac 132c58f1c22SToby Isaac Level: developer 133c58f1c22SToby Isaac 134db781477SPatrick Sanan .seealso: `DMLabelCreate()` 135c58f1c22SToby Isaac */ 1369371c9d4SSatish Balay static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) { 137c58f1c22SToby Isaac PetscInt p; 138ad8374ffSToby Isaac const PetscInt *points; 139c58f1c22SToby Isaac 140b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) return 0; 141c58f1c22SToby Isaac PetscFunctionBegin; 1421dca8a05SBarry 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); 143ad8374ffSToby Isaac if (label->points[v]) { 1449566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 14548a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 1469566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1479566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 148ad8374ffSToby Isaac } 149ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 150c58f1c22SToby Isaac PetscFunctionReturn(0); 151c58f1c22SToby Isaac } 152c58f1c22SToby Isaac 1539371c9d4SSatish Balay PetscErrorCode DMLabelMakeAllInvalid_Internal(DMLabel label) { 154695799ffSMatthew G. Knepley PetscInt v; 155695799ffSMatthew G. Knepley 156695799ffSMatthew G. Knepley PetscFunctionBegin; 15748a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; v++) PetscCall(DMLabelMakeInvalid_Private(label, v)); 158695799ffSMatthew G. Knepley PetscFunctionReturn(0); 159695799ffSMatthew G. Knepley } 160695799ffSMatthew G. Knepley 161b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 162b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 163b9907514SLisandro Dalcin #endif 164b9907514SLisandro Dalcin 1659371c9d4SSatish Balay static inline PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) { 1660c3c4a36SLisandro Dalcin PetscInt v; 1670e79e033SBarry Smith 1680c3c4a36SLisandro Dalcin PetscFunctionBegin; 1690e79e033SBarry Smith *index = -1; 170b9907514SLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 171b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 1729371c9d4SSatish Balay if (label->stratumValues[v] == value) { 1739371c9d4SSatish Balay *index = v; 1749371c9d4SSatish Balay break; 1759371c9d4SSatish Balay } 176b9907514SLisandro Dalcin } else { 1779566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index)); 1780e79e033SBarry Smith } 17976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* Check strata hash map consistency */ 18090e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 1819566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len)); 18208401ef6SPierre Jolivet PetscCheck(len == label->numStrata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 18390e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 1849566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc)); 18590e9b2aeSLisandro Dalcin } else { 18690e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 1879371c9d4SSatish Balay if (label->stratumValues[v] == value) { 1889371c9d4SSatish Balay loc = v; 1899371c9d4SSatish Balay break; 1909371c9d4SSatish Balay } 19190e9b2aeSLisandro Dalcin } 19208401ef6SPierre Jolivet PetscCheck(loc == *index, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 19390e9b2aeSLisandro Dalcin } 1940c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 1950c3c4a36SLisandro Dalcin } 1960c3c4a36SLisandro Dalcin 1979371c9d4SSatish Balay static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) { 198b9907514SLisandro Dalcin PetscInt v; 199b9907514SLisandro Dalcin PetscInt *tmpV; 200b9907514SLisandro Dalcin PetscInt *tmpS; 201b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 202b9907514SLisandro Dalcin IS *tmpP, is; 203c58f1c22SToby Isaac PetscBool *tmpB; 204b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 205c58f1c22SToby Isaac 206c58f1c22SToby Isaac PetscFunctionBegin; 207b9907514SLisandro Dalcin v = label->numStrata; 208b9907514SLisandro Dalcin tmpV = label->stratumValues; 209b9907514SLisandro Dalcin tmpS = label->stratumSizes; 210b9907514SLisandro Dalcin tmpH = label->ht; 211b9907514SLisandro Dalcin tmpP = label->points; 212b9907514SLisandro Dalcin tmpB = label->validIS; 2138e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2148e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2158e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2168e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2178e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2188e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2199566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpV), &tmpV)); 2209566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpS), &tmpS)); 2219566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpH), &tmpH)); 2229566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpP), &tmpP)); 2239566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v + 1) * sizeof(*tmpB), &tmpB)); 2249566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v)); 2259566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v)); 2269566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v)); 2279566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v)); 2289566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v)); 2299566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV)); 2309566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS)); 2319566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH)); 2329566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP)); 2339566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB)); 2348e1f8cf0SLisandro Dalcin } 235b9907514SLisandro Dalcin label->numStrata = v + 1; 236c58f1c22SToby Isaac label->stratumValues = tmpV; 237c58f1c22SToby Isaac label->stratumSizes = tmpS; 238c58f1c22SToby Isaac label->ht = tmpH; 239c58f1c22SToby Isaac label->points = tmpP; 240ad8374ffSToby Isaac label->validIS = tmpB; 2419566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 2429566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 2439566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v)); 244b9907514SLisandro Dalcin tmpV[v] = value; 245b9907514SLisandro Dalcin tmpS[v] = 0; 246b9907514SLisandro Dalcin tmpH[v] = ht; 247b9907514SLisandro Dalcin tmpP[v] = is; 248b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 2499566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 2500c3c4a36SLisandro Dalcin *index = v; 2510c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 2520c3c4a36SLisandro Dalcin } 2530c3c4a36SLisandro Dalcin 2549371c9d4SSatish Balay static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) { 255b9907514SLisandro Dalcin PetscFunctionBegin; 2569566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index)); 2579566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index)); 258b9907514SLisandro Dalcin PetscFunctionReturn(0); 259b9907514SLisandro Dalcin } 260b9907514SLisandro Dalcin 2619371c9d4SSatish Balay static inline PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) { 2629e63cc69SVaclav Hapla PetscFunctionBegin; 2639e63cc69SVaclav Hapla *size = 0; 2649e63cc69SVaclav Hapla if (v < 0) PetscFunctionReturn(0); 2659e63cc69SVaclav Hapla if (label->validIS[v]) { 2669e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 2679e63cc69SVaclav Hapla } else { 2689566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size)); 2699e63cc69SVaclav Hapla } 2709e63cc69SVaclav Hapla PetscFunctionReturn(0); 2719e63cc69SVaclav Hapla } 2729e63cc69SVaclav Hapla 273b9907514SLisandro Dalcin /*@ 274b9907514SLisandro Dalcin DMLabelAddStratum - Adds a new stratum value in a DMLabel 275b9907514SLisandro Dalcin 276d8d19677SJose E. Roman Input Parameters: 277b9907514SLisandro Dalcin + label - The DMLabel 278b9907514SLisandro Dalcin - value - The stratum value 279b9907514SLisandro Dalcin 280b9907514SLisandro Dalcin Level: beginner 281b9907514SLisandro Dalcin 282db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 283b9907514SLisandro Dalcin @*/ 2849371c9d4SSatish Balay PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) { 2850c3c4a36SLisandro Dalcin PetscInt v; 2860c3c4a36SLisandro Dalcin 2870c3c4a36SLisandro Dalcin PetscFunctionBegin; 288d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 2899566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 290b9907514SLisandro Dalcin PetscFunctionReturn(0); 291b9907514SLisandro Dalcin } 292b9907514SLisandro Dalcin 293b9907514SLisandro Dalcin /*@ 294b9907514SLisandro Dalcin DMLabelAddStrata - Adds new stratum values in a DMLabel 295b9907514SLisandro Dalcin 2965b5e7992SMatthew G. Knepley Not collective 2975b5e7992SMatthew G. Knepley 298d8d19677SJose E. Roman Input Parameters: 299b9907514SLisandro Dalcin + label - The DMLabel 300b9907514SLisandro Dalcin . numStrata - The number of stratum values 301b9907514SLisandro Dalcin - stratumValues - The stratum values 302b9907514SLisandro Dalcin 303b9907514SLisandro Dalcin Level: beginner 304b9907514SLisandro Dalcin 305db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 306b9907514SLisandro Dalcin @*/ 3079371c9d4SSatish Balay PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) { 308b9907514SLisandro Dalcin PetscInt *values, v; 309b9907514SLisandro Dalcin 310b9907514SLisandro Dalcin PetscFunctionBegin; 311b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 312b9907514SLisandro Dalcin if (numStrata) PetscValidIntPointer(stratumValues, 3); 3139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &values)); 3149566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(values, stratumValues, numStrata)); 3159566063dSJacob Faibussowitsch PetscCall(PetscSortRemoveDupsInt(&numStrata, values)); 316b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 317b9907514SLisandro Dalcin PetscInt *tmpV; 318b9907514SLisandro Dalcin PetscInt *tmpS; 319b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 320b9907514SLisandro Dalcin IS *tmpP, is; 321b9907514SLisandro Dalcin PetscBool *tmpB; 322b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 323b9907514SLisandro Dalcin 3249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpV)); 3259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpS)); 3269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpH)); 3279566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpP)); 3289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(numStrata, &tmpB)); 329b9907514SLisandro Dalcin label->numStrata = numStrata; 330b9907514SLisandro Dalcin label->stratumValues = tmpV; 331b9907514SLisandro Dalcin label->stratumSizes = tmpS; 332b9907514SLisandro Dalcin label->ht = tmpH; 333b9907514SLisandro Dalcin label->points = tmpP; 334b9907514SLisandro Dalcin label->validIS = tmpB; 335b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 3369566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 3379566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &is)); 3389566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, values[v], v)); 339b9907514SLisandro Dalcin tmpV[v] = values[v]; 340b9907514SLisandro Dalcin tmpS[v] = 0; 341b9907514SLisandro Dalcin tmpH[v] = ht; 342b9907514SLisandro Dalcin tmpP[v] = is; 343b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 344b9907514SLisandro Dalcin } 3459566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 346b9907514SLisandro Dalcin } else { 34748a46eb9SPierre Jolivet for (v = 0; v < numStrata; ++v) PetscCall(DMLabelAddStratum(label, values[v])); 348b9907514SLisandro Dalcin } 3499566063dSJacob Faibussowitsch PetscCall(PetscFree(values)); 350b9907514SLisandro Dalcin PetscFunctionReturn(0); 351b9907514SLisandro Dalcin } 352b9907514SLisandro Dalcin 353b9907514SLisandro Dalcin /*@ 354b9907514SLisandro Dalcin DMLabelAddStrataIS - Adds new stratum values in a DMLabel 355b9907514SLisandro Dalcin 3565b5e7992SMatthew G. Knepley Not collective 3575b5e7992SMatthew G. Knepley 358d8d19677SJose E. Roman Input Parameters: 359b9907514SLisandro Dalcin + label - The DMLabel 360b9907514SLisandro Dalcin - valueIS - Index set with stratum values 361b9907514SLisandro Dalcin 362b9907514SLisandro Dalcin Level: beginner 363b9907514SLisandro Dalcin 364db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 365b9907514SLisandro Dalcin @*/ 3669371c9d4SSatish Balay PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) { 367b9907514SLisandro Dalcin PetscInt numStrata; 368b9907514SLisandro Dalcin const PetscInt *stratumValues; 369b9907514SLisandro Dalcin 370b9907514SLisandro Dalcin PetscFunctionBegin; 371b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 372b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 3739566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata)); 3749566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues)); 3759566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues)); 376c58f1c22SToby Isaac PetscFunctionReturn(0); 377c58f1c22SToby Isaac } 378c58f1c22SToby Isaac 3799371c9d4SSatish Balay static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) { 380c58f1c22SToby Isaac PetscInt v; 381c58f1c22SToby Isaac PetscMPIInt rank; 382c58f1c22SToby Isaac 383c58f1c22SToby Isaac PetscFunctionBegin; 3849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 3859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 386c58f1c22SToby Isaac if (label) { 387d67d17b1SMatthew G. Knepley const char *name; 388d67d17b1SMatthew G. Knepley 3899566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 3909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name)); 39163a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd)); 392c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 393c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 394ad8374ffSToby Isaac const PetscInt *points; 395c58f1c22SToby Isaac PetscInt p; 396c58f1c22SToby Isaac 3979566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 39848a46eb9SPierre Jolivet for (p = 0; p < label->stratumSizes[v]; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 3999566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 400c58f1c22SToby Isaac } 401c58f1c22SToby Isaac } 4029566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 4039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 404c58f1c22SToby Isaac PetscFunctionReturn(0); 405c58f1c22SToby Isaac } 406c58f1c22SToby Isaac 407c58f1c22SToby Isaac /*@C 408c58f1c22SToby Isaac DMLabelView - View the label 409c58f1c22SToby Isaac 4105b5e7992SMatthew G. Knepley Collective on viewer 4115b5e7992SMatthew G. Knepley 412c58f1c22SToby Isaac Input Parameters: 413c58f1c22SToby Isaac + label - The DMLabel 414c58f1c22SToby Isaac - viewer - The PetscViewer 415c58f1c22SToby Isaac 416c58f1c22SToby Isaac Level: intermediate 417c58f1c22SToby Isaac 418db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 419c58f1c22SToby Isaac @*/ 4209371c9d4SSatish Balay PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) { 421c58f1c22SToby Isaac PetscBool iascii; 422c58f1c22SToby Isaac 423c58f1c22SToby Isaac PetscFunctionBegin; 424d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 4259566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer)); 426c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4279566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 4289566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 4291baa6e33SBarry Smith if (iascii) PetscCall(DMLabelView_Ascii(label, viewer)); 430c58f1c22SToby Isaac PetscFunctionReturn(0); 431c58f1c22SToby Isaac } 432c58f1c22SToby Isaac 43384f0b6dfSMatthew G. Knepley /*@ 434d67d17b1SMatthew G. Knepley DMLabelReset - Destroys internal data structures in a DMLabel 435d67d17b1SMatthew G. Knepley 4365b5e7992SMatthew G. Knepley Not collective 4375b5e7992SMatthew G. Knepley 438d67d17b1SMatthew G. Knepley Input Parameter: 439d67d17b1SMatthew G. Knepley . label - The DMLabel 440d67d17b1SMatthew G. Knepley 441d67d17b1SMatthew G. Knepley Level: beginner 442d67d17b1SMatthew G. Knepley 443db781477SPatrick Sanan .seealso: `DMLabelDestroy()`, `DMLabelCreate()` 444d67d17b1SMatthew G. Knepley @*/ 4459371c9d4SSatish Balay PetscErrorCode DMLabelReset(DMLabel label) { 446d67d17b1SMatthew G. Knepley PetscInt v; 447d67d17b1SMatthew G. Knepley 448d67d17b1SMatthew G. Knepley PetscFunctionBegin; 449d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 450d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 4519566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&label->ht[v])); 4529566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 453d67d17b1SMatthew G. Knepley } 454b9907514SLisandro Dalcin label->numStrata = 0; 4559566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues)); 4569566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes)); 4579566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht)); 4589566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points)); 4599566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS)); 460f9244615SMatthew G. Knepley label->stratumValues = NULL; 461f9244615SMatthew G. Knepley label->stratumSizes = NULL; 462f9244615SMatthew G. Knepley label->ht = NULL; 463f9244615SMatthew G. Knepley label->points = NULL; 464f9244615SMatthew G. Knepley label->validIS = NULL; 4659566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 466b9907514SLisandro Dalcin label->pStart = -1; 467b9907514SLisandro Dalcin label->pEnd = -1; 4689566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 469d67d17b1SMatthew G. Knepley PetscFunctionReturn(0); 470d67d17b1SMatthew G. Knepley } 471d67d17b1SMatthew G. Knepley 472d67d17b1SMatthew G. Knepley /*@ 47384f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 47484f0b6dfSMatthew G. Knepley 4755b5e7992SMatthew G. Knepley Collective on label 4765b5e7992SMatthew G. Knepley 47784f0b6dfSMatthew G. Knepley Input Parameter: 47884f0b6dfSMatthew G. Knepley . label - The DMLabel 47984f0b6dfSMatthew G. Knepley 48084f0b6dfSMatthew G. Knepley Level: beginner 48184f0b6dfSMatthew G. Knepley 482db781477SPatrick Sanan .seealso: `DMLabelReset()`, `DMLabelCreate()` 48384f0b6dfSMatthew G. Knepley @*/ 4849371c9d4SSatish Balay PetscErrorCode DMLabelDestroy(DMLabel *label) { 485c58f1c22SToby Isaac PetscFunctionBegin; 486d67d17b1SMatthew G. Knepley if (!*label) PetscFunctionReturn(0); 487d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label), DMLABEL_CLASSID, 1); 4889371c9d4SSatish Balay if (--((PetscObject)(*label))->refct > 0) { 4899371c9d4SSatish Balay *label = NULL; 4909371c9d4SSatish Balay PetscFunctionReturn(0); 4919371c9d4SSatish Balay } 4929566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 4939566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 4949566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 495c58f1c22SToby Isaac PetscFunctionReturn(0); 496c58f1c22SToby Isaac } 497c58f1c22SToby Isaac 49884f0b6dfSMatthew G. Knepley /*@ 49984f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 50084f0b6dfSMatthew G. Knepley 5015b5e7992SMatthew G. Knepley Collective on label 5025b5e7992SMatthew G. Knepley 50384f0b6dfSMatthew G. Knepley Input Parameter: 50484f0b6dfSMatthew G. Knepley . label - The DMLabel 50584f0b6dfSMatthew G. Knepley 50684f0b6dfSMatthew G. Knepley Output Parameter: 50784f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 50884f0b6dfSMatthew G. Knepley 50984f0b6dfSMatthew G. Knepley Level: intermediate 51084f0b6dfSMatthew G. Knepley 511db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 51284f0b6dfSMatthew G. Knepley @*/ 5139371c9d4SSatish Balay PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) { 514d67d17b1SMatthew G. Knepley const char *name; 515ad8374ffSToby Isaac PetscInt v; 516c58f1c22SToby Isaac 517c58f1c22SToby Isaac PetscFunctionBegin; 518d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 5199566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 5209566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &name)); 5219566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)label), name, labelnew)); 522c58f1c22SToby Isaac 523c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5245aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 5259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 5269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 5279566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->ht)); 5289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->points)); 5299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 530c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 5319566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 532c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 533c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 5349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)(label->points[v]))); 535ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 536b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 537c58f1c22SToby Isaac } 5389566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5399566063dSJacob Faibussowitsch PetscCall(PetscHMapIDuplicate(label->hmap, &(*labelnew)->hmap)); 540c58f1c22SToby Isaac (*labelnew)->pStart = -1; 541c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 542c58f1c22SToby Isaac (*labelnew)->bt = NULL; 543c58f1c22SToby Isaac PetscFunctionReturn(0); 544c58f1c22SToby Isaac } 545c58f1c22SToby Isaac 546609dae6eSVaclav Hapla /*@C 547609dae6eSVaclav Hapla DMLabelCompare - Compare two DMLabel objects 548609dae6eSVaclav Hapla 5495efe38ccSVaclav Hapla Collective on comm 550609dae6eSVaclav Hapla 551609dae6eSVaclav Hapla Input Parameters: 552f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 553f1a722f8SMatthew G. Knepley . l0 - First DMLabel 554609dae6eSVaclav Hapla - l1 - Second DMLabel 555609dae6eSVaclav Hapla 556609dae6eSVaclav Hapla Output Parameters 5575efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 5585efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 559609dae6eSVaclav Hapla 560609dae6eSVaclav Hapla Level: intermediate 561609dae6eSVaclav Hapla 562609dae6eSVaclav Hapla Notes: 5635efe38ccSVaclav Hapla The output flag equal is the same on all processes. 5645efe38ccSVaclav Hapla If it is passed as NULL and difference is found, an error is thrown on all processes. 5655efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 566609dae6eSVaclav Hapla 5675efe38ccSVaclav Hapla The output message is set independently on each rank. 5685efe38ccSVaclav Hapla It is set to NULL if no difference was found on the current rank. It must be freed by user. 5695efe38ccSVaclav Hapla If message is passed as NULL and difference is found, the difference description is printed to stderr in synchronized manner. 5705efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 571609dae6eSVaclav Hapla 572609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 573609dae6eSVaclav Hapla 5745efe38ccSVaclav Hapla The communicator needs to be specified because currently DMLabel can live on PETSC_COMM_SELF even if the underlying DM is parallel. 5755efe38ccSVaclav Hapla 576609dae6eSVaclav Hapla Fortran Notes: 577609dae6eSVaclav Hapla This function is currently not available from Fortran. 578609dae6eSVaclav Hapla 579db781477SPatrick Sanan .seealso: `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 580609dae6eSVaclav Hapla @*/ 5819371c9d4SSatish Balay PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) { 582609dae6eSVaclav Hapla const char *name0, *name1; 583609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 5845efe38ccSVaclav Hapla PetscBool eq; 5855efe38ccSVaclav Hapla PetscMPIInt rank; 586609dae6eSVaclav Hapla 587609dae6eSVaclav Hapla PetscFunctionBegin; 5885efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 5895efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 5905efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal, 4); 5915efe38ccSVaclav Hapla if (message) PetscValidPointer(message, 5); 5929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5939566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 5949566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 595609dae6eSVaclav Hapla { 596609dae6eSVaclav Hapla PetscInt v0, v1; 597609dae6eSVaclav Hapla 5989566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 5999566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6005efe38ccSVaclav Hapla eq = (PetscBool)(v0 == v1); 60148a46eb9SPierre 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)); 6029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6035efe38ccSVaclav Hapla if (!eq) goto finish; 604609dae6eSVaclav Hapla } 605609dae6eSVaclav Hapla { 606609dae6eSVaclav Hapla IS is0, is1; 607609dae6eSVaclav Hapla 6089566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6099566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6109566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6119566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6129566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 61348a46eb9SPierre Jolivet if (!eq) PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 6149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6155efe38ccSVaclav Hapla if (!eq) goto finish; 616609dae6eSVaclav Hapla } 617609dae6eSVaclav Hapla { 618609dae6eSVaclav Hapla PetscInt i, nValues; 619609dae6eSVaclav Hapla 6209566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 621609dae6eSVaclav Hapla for (i = 0; i < nValues; i++) { 622609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 623609dae6eSVaclav Hapla PetscInt n; 624609dae6eSVaclav Hapla IS is0, is1; 625609dae6eSVaclav Hapla 6269566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 627609dae6eSVaclav Hapla if (!n) continue; 6289566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6299566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6309566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6319566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6329566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6335efe38ccSVaclav Hapla if (!eq) { 63463a3b9bcSJacob 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)); 6355efe38ccSVaclav Hapla break; 636609dae6eSVaclav Hapla } 637609dae6eSVaclav Hapla } 6389566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 639609dae6eSVaclav Hapla } 640609dae6eSVaclav Hapla finish: 6415efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 642609dae6eSVaclav Hapla if (message) { 643609dae6eSVaclav Hapla *message = NULL; 64448a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscStrallocpy(msg, message)); 6455efe38ccSVaclav Hapla } else { 64648a46eb9SPierre Jolivet if (msg[0]) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 6479566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 6485efe38ccSVaclav Hapla } 6495efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 6505efe38ccSVaclav Hapla if (equal) *equal = eq; 65163a3b9bcSJacob Faibussowitsch else PetscCheck(eq, comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal", name0, name1); 652609dae6eSVaclav Hapla PetscFunctionReturn(0); 653609dae6eSVaclav Hapla } 654609dae6eSVaclav Hapla 655c6a43d28SMatthew G. Knepley /*@ 656c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 657c6a43d28SMatthew G. Knepley 6585b5e7992SMatthew G. Knepley Not collective 6595b5e7992SMatthew G. Knepley 660c6a43d28SMatthew G. Knepley Input Parameter: 661c6a43d28SMatthew G. Knepley . label - The DMLabel 662c6a43d28SMatthew G. Knepley 663c6a43d28SMatthew G. Knepley Level: intermediate 664c6a43d28SMatthew G. Knepley 665db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 666c6a43d28SMatthew G. Knepley @*/ 6679371c9d4SSatish Balay PetscErrorCode DMLabelComputeIndex(DMLabel label) { 668c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 669c6a43d28SMatthew G. Knepley 670c6a43d28SMatthew G. Knepley PetscFunctionBegin; 671c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 6729566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 673c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 674c6a43d28SMatthew G. Knepley const PetscInt *points; 675c6a43d28SMatthew G. Knepley PetscInt i; 676c6a43d28SMatthew G. Knepley 6779566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 678c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 679c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 680c6a43d28SMatthew G. Knepley 681c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 682c6a43d28SMatthew G. Knepley pEnd = PetscMax(point + 1, pEnd); 683c6a43d28SMatthew G. Knepley } 6849566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 685c6a43d28SMatthew G. Knepley } 686c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 687c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 6889566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 689c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 690c6a43d28SMatthew G. Knepley } 691c6a43d28SMatthew G. Knepley 692c6a43d28SMatthew G. Knepley /*@ 693c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 694c6a43d28SMatthew G. Knepley 6955b5e7992SMatthew G. Knepley Not collective 6965b5e7992SMatthew G. Knepley 697c6a43d28SMatthew G. Knepley Input Parameters: 698c6a43d28SMatthew G. Knepley + label - The DMLabel 699c6a43d28SMatthew G. Knepley . pStart - The smallest point 700c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 701c6a43d28SMatthew G. Knepley 702c6a43d28SMatthew G. Knepley Level: intermediate 703c6a43d28SMatthew G. Knepley 704db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 705c6a43d28SMatthew G. Knepley @*/ 7069371c9d4SSatish Balay PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) { 707c58f1c22SToby Isaac PetscInt v; 708c58f1c22SToby Isaac 709c58f1c22SToby Isaac PetscFunctionBegin; 710d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7119566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7129566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 713c58f1c22SToby Isaac label->pStart = pStart; 714c58f1c22SToby Isaac label->pEnd = pEnd; 715c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7169566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 717c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 718ad8374ffSToby Isaac const PetscInt *points; 719c58f1c22SToby Isaac PetscInt i; 720c58f1c22SToby Isaac 7219566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 722c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 723ad8374ffSToby Isaac const PetscInt point = points[i]; 724c58f1c22SToby Isaac 72563a3b9bcSJacob 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); 7269566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 727c58f1c22SToby Isaac } 7289566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 729c58f1c22SToby Isaac } 730c58f1c22SToby Isaac PetscFunctionReturn(0); 731c58f1c22SToby Isaac } 732c58f1c22SToby Isaac 733c6a43d28SMatthew G. Knepley /*@ 734c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 735c6a43d28SMatthew G. Knepley 7365b5e7992SMatthew G. Knepley Not collective 7375b5e7992SMatthew G. Knepley 738c6a43d28SMatthew G. Knepley Input Parameter: 739c6a43d28SMatthew G. Knepley . label - the DMLabel 740c6a43d28SMatthew G. Knepley 741c6a43d28SMatthew G. Knepley Level: intermediate 742c6a43d28SMatthew G. Knepley 743db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 744c6a43d28SMatthew G. Knepley @*/ 7459371c9d4SSatish Balay PetscErrorCode DMLabelDestroyIndex(DMLabel label) { 746c58f1c22SToby Isaac PetscFunctionBegin; 747d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 748c58f1c22SToby Isaac label->pStart = -1; 749c58f1c22SToby Isaac label->pEnd = -1; 7509566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 751c58f1c22SToby Isaac PetscFunctionReturn(0); 752c58f1c22SToby Isaac } 753c58f1c22SToby Isaac 754c58f1c22SToby Isaac /*@ 755c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 756c6a43d28SMatthew G. Knepley 7575b5e7992SMatthew G. Knepley Not collective 7585b5e7992SMatthew G. Knepley 759c6a43d28SMatthew G. Knepley Input Parameter: 760c6a43d28SMatthew G. Knepley . label - the DMLabel 761c6a43d28SMatthew G. Knepley 762c6a43d28SMatthew G. Knepley Output Parameters: 763c6a43d28SMatthew G. Knepley + pStart - The smallest point 764c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 765c6a43d28SMatthew G. Knepley 766c6a43d28SMatthew G. Knepley Note: This will compute an index for the label if one does not exist. 767c6a43d28SMatthew G. Knepley 768c6a43d28SMatthew G. Knepley Level: intermediate 769c6a43d28SMatthew G. Knepley 770db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 771c6a43d28SMatthew G. Knepley @*/ 7729371c9d4SSatish Balay PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) { 773c6a43d28SMatthew G. Knepley PetscFunctionBegin; 774c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7759566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 776c6a43d28SMatthew G. Knepley if (pStart) { 777534a8f05SLisandro Dalcin PetscValidIntPointer(pStart, 2); 778c6a43d28SMatthew G. Knepley *pStart = label->pStart; 779c6a43d28SMatthew G. Knepley } 780c6a43d28SMatthew G. Knepley if (pEnd) { 781534a8f05SLisandro Dalcin PetscValidIntPointer(pEnd, 3); 782c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 783c6a43d28SMatthew G. Knepley } 784c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 785c6a43d28SMatthew G. Knepley } 786c6a43d28SMatthew G. Knepley 787c6a43d28SMatthew G. Knepley /*@ 788c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 789c58f1c22SToby Isaac 7905b5e7992SMatthew G. Knepley Not collective 7915b5e7992SMatthew G. Knepley 792c58f1c22SToby Isaac Input Parameters: 793c58f1c22SToby Isaac + label - the DMLabel 794c58f1c22SToby Isaac - value - the value 795c58f1c22SToby Isaac 796c58f1c22SToby Isaac Output Parameter: 797c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 798c58f1c22SToby Isaac 799c58f1c22SToby Isaac Level: developer 800c58f1c22SToby Isaac 801db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 802c58f1c22SToby Isaac @*/ 8039371c9d4SSatish Balay PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) { 804c58f1c22SToby Isaac PetscInt v; 805c58f1c22SToby Isaac 806c58f1c22SToby Isaac PetscFunctionBegin; 807d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 808534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8099566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8100c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 811c58f1c22SToby Isaac PetscFunctionReturn(0); 812c58f1c22SToby Isaac } 813c58f1c22SToby Isaac 814c58f1c22SToby Isaac /*@ 815c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 816c58f1c22SToby Isaac 8175b5e7992SMatthew G. Knepley Not collective 8185b5e7992SMatthew G. Knepley 819c58f1c22SToby Isaac Input Parameters: 820c58f1c22SToby Isaac + label - the DMLabel 821c58f1c22SToby Isaac - point - the point 822c58f1c22SToby Isaac 823c58f1c22SToby Isaac Output Parameter: 824c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 825c58f1c22SToby Isaac 826c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 827c58f1c22SToby Isaac 828c58f1c22SToby Isaac Level: developer 829c58f1c22SToby Isaac 830db781477SPatrick Sanan .seealso: `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 831c58f1c22SToby Isaac @*/ 8329371c9d4SSatish Balay PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) { 833c58f1c22SToby Isaac PetscFunctionBeginHot; 834d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 835534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8369566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 83776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 83828b400f6SJacob Faibussowitsch PetscCheck(label->bt, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 83963a3b9bcSJacob 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); 84076bd3646SJed Brown } 841c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 842c58f1c22SToby Isaac PetscFunctionReturn(0); 843c58f1c22SToby Isaac } 844c58f1c22SToby Isaac 845c58f1c22SToby Isaac /*@ 846c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 847c58f1c22SToby Isaac 8485b5e7992SMatthew G. Knepley Not collective 8495b5e7992SMatthew G. Knepley 850c58f1c22SToby Isaac Input Parameters: 851c58f1c22SToby Isaac + label - the DMLabel 852c58f1c22SToby Isaac . value - the stratum value 853c58f1c22SToby Isaac - point - the point 854c58f1c22SToby Isaac 855c58f1c22SToby Isaac Output Parameter: 856c58f1c22SToby Isaac . contains - true if the stratum contains the point 857c58f1c22SToby Isaac 858c58f1c22SToby Isaac Level: intermediate 859c58f1c22SToby Isaac 860db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 861c58f1c22SToby Isaac @*/ 8629371c9d4SSatish Balay PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) { 8630c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 864d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 865534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 4); 866cffad2c9SToby Isaac if (value == label->defaultValue) { 867cffad2c9SToby Isaac PetscInt pointVal; 8680c3c4a36SLisandro Dalcin 869cffad2c9SToby Isaac PetscCall(DMLabelGetValue(label, point, &pointVal)); 870cffad2c9SToby Isaac *contains = (PetscBool)(pointVal == value); 871cffad2c9SToby Isaac } else { 872cffad2c9SToby Isaac PetscInt v; 873cffad2c9SToby Isaac 874cffad2c9SToby Isaac PetscCall(DMLabelLookupStratum(label, value, &v)); 875cffad2c9SToby Isaac if (v >= 0) { 876ad8374ffSToby Isaac if (label->validIS[v]) { 877c58f1c22SToby Isaac PetscInt i; 878c58f1c22SToby Isaac 8799566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 880cffad2c9SToby Isaac *contains = (PetscBool)(i >= 0); 881c58f1c22SToby Isaac } else { 882cffad2c9SToby Isaac PetscCall(PetscHSetIHas(label->ht[v], point, contains)); 883cffad2c9SToby Isaac } 884cffad2c9SToby Isaac } else { // value is not present 885cffad2c9SToby Isaac *contains = PETSC_FALSE; 886cffad2c9SToby Isaac } 887c58f1c22SToby Isaac } 888c58f1c22SToby Isaac PetscFunctionReturn(0); 889c58f1c22SToby Isaac } 890c58f1c22SToby Isaac 89184f0b6dfSMatthew G. Knepley /*@ 8925aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 8935aa44df4SToby Isaac When a label is created, it is initialized to -1. 8945aa44df4SToby Isaac 8955b5e7992SMatthew G. Knepley Not collective 8965b5e7992SMatthew G. Knepley 8975aa44df4SToby Isaac Input parameter: 8985aa44df4SToby Isaac . label - a DMLabel object 8995aa44df4SToby Isaac 9005aa44df4SToby Isaac Output parameter: 9015aa44df4SToby Isaac . defaultValue - the default value 9025aa44df4SToby Isaac 9035aa44df4SToby Isaac Level: beginner 9045aa44df4SToby Isaac 905db781477SPatrick Sanan .seealso: `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 90684f0b6dfSMatthew G. Knepley @*/ 9079371c9d4SSatish Balay PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) { 9085aa44df4SToby Isaac PetscFunctionBegin; 909d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9105aa44df4SToby Isaac *defaultValue = label->defaultValue; 9115aa44df4SToby Isaac PetscFunctionReturn(0); 9125aa44df4SToby Isaac } 9135aa44df4SToby Isaac 91484f0b6dfSMatthew G. Knepley /*@ 9155aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9165aa44df4SToby Isaac When a label is created, it is initialized to -1. 9175aa44df4SToby Isaac 9185b5e7992SMatthew G. Knepley Not collective 9195b5e7992SMatthew G. Knepley 9205aa44df4SToby Isaac Input parameter: 9215aa44df4SToby Isaac . label - a DMLabel object 9225aa44df4SToby Isaac 9235aa44df4SToby Isaac Output parameter: 9245aa44df4SToby Isaac . defaultValue - the default value 9255aa44df4SToby Isaac 9265aa44df4SToby Isaac Level: beginner 9275aa44df4SToby Isaac 928db781477SPatrick Sanan .seealso: `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 92984f0b6dfSMatthew G. Knepley @*/ 9309371c9d4SSatish Balay PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) { 9315aa44df4SToby Isaac PetscFunctionBegin; 932d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9335aa44df4SToby Isaac label->defaultValue = defaultValue; 9345aa44df4SToby Isaac PetscFunctionReturn(0); 9355aa44df4SToby Isaac } 9365aa44df4SToby Isaac 937c58f1c22SToby Isaac /*@ 9385aa44df4SToby 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()) 939c58f1c22SToby Isaac 9405b5e7992SMatthew G. Knepley Not collective 9415b5e7992SMatthew G. Knepley 942c58f1c22SToby Isaac Input Parameters: 943c58f1c22SToby Isaac + label - the DMLabel 944c58f1c22SToby Isaac - point - the point 945c58f1c22SToby Isaac 946c58f1c22SToby Isaac Output Parameter: 9478e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 948c58f1c22SToby Isaac 949cffad2c9SToby 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. 950cffad2c9SToby Isaac 951c58f1c22SToby Isaac Level: intermediate 952c58f1c22SToby Isaac 953db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 954c58f1c22SToby Isaac @*/ 9559371c9d4SSatish Balay PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) { 956c58f1c22SToby Isaac PetscInt v; 957c58f1c22SToby Isaac 9580c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 959d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 960dadcf809SJacob Faibussowitsch PetscValidIntPointer(value, 3); 9615aa44df4SToby Isaac *value = label->defaultValue; 962c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 963ad8374ffSToby Isaac if (label->validIS[v]) { 964c58f1c22SToby Isaac PetscInt i; 965c58f1c22SToby Isaac 9669566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 967c58f1c22SToby Isaac if (i >= 0) { 968c58f1c22SToby Isaac *value = label->stratumValues[v]; 969c58f1c22SToby Isaac break; 970c58f1c22SToby Isaac } 971c58f1c22SToby Isaac } else { 972c58f1c22SToby Isaac PetscBool has; 973c58f1c22SToby Isaac 9749566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 975c58f1c22SToby Isaac if (has) { 976c58f1c22SToby Isaac *value = label->stratumValues[v]; 977c58f1c22SToby Isaac break; 978c58f1c22SToby Isaac } 979c58f1c22SToby Isaac } 980c58f1c22SToby Isaac } 981c58f1c22SToby Isaac PetscFunctionReturn(0); 982c58f1c22SToby Isaac } 983c58f1c22SToby Isaac 984c58f1c22SToby Isaac /*@ 985367003a6SStefano 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. 986c58f1c22SToby Isaac 9875b5e7992SMatthew G. Knepley Not collective 9885b5e7992SMatthew G. Knepley 989c58f1c22SToby Isaac Input Parameters: 990c58f1c22SToby Isaac + label - the DMLabel 991c58f1c22SToby Isaac . point - the point 992c58f1c22SToby Isaac - value - The point value 993c58f1c22SToby Isaac 994c58f1c22SToby Isaac Level: intermediate 995c58f1c22SToby Isaac 996db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 997c58f1c22SToby Isaac @*/ 9989371c9d4SSatish Balay PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) { 999c58f1c22SToby Isaac PetscInt v; 1000c58f1c22SToby Isaac 1001c58f1c22SToby Isaac PetscFunctionBegin; 1002d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10030c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10045aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 10059566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1006c58f1c22SToby Isaac /* Set key */ 10079566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10089566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 1009c58f1c22SToby Isaac PetscFunctionReturn(0); 1010c58f1c22SToby Isaac } 1011c58f1c22SToby Isaac 1012c58f1c22SToby Isaac /*@ 1013c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 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()`, `DMLabelSetValue()` 1025c58f1c22SToby Isaac @*/ 10269371c9d4SSatish Balay PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) { 1027ad8374ffSToby Isaac PetscInt v; 1028c58f1c22SToby Isaac 1029c58f1c22SToby Isaac PetscFunctionBegin; 1030d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1031c58f1c22SToby Isaac /* Find label value */ 10329566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 10330c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 10340c3c4a36SLisandro Dalcin 1035eeed21e7SToby Isaac if (label->bt) { 103663a3b9bcSJacob 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); 10379566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1038eeed21e7SToby Isaac } 10390c3c4a36SLisandro Dalcin 10400c3c4a36SLisandro Dalcin /* Delete key */ 10419566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10429566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 1043c58f1c22SToby Isaac PetscFunctionReturn(0); 1044c58f1c22SToby Isaac } 1045c58f1c22SToby Isaac 1046c58f1c22SToby Isaac /*@ 1047c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 1048c58f1c22SToby Isaac 10495b5e7992SMatthew G. Knepley Not collective 10505b5e7992SMatthew G. Knepley 1051c58f1c22SToby Isaac Input Parameters: 1052c58f1c22SToby Isaac + label - the DMLabel 1053c58f1c22SToby Isaac . is - the point IS 1054c58f1c22SToby Isaac - value - The point value 1055c58f1c22SToby Isaac 1056c58f1c22SToby Isaac Level: intermediate 1057c58f1c22SToby Isaac 1058db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1059c58f1c22SToby Isaac @*/ 10609371c9d4SSatish Balay PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) { 10610c3c4a36SLisandro Dalcin PetscInt v, n, p; 1062c58f1c22SToby Isaac const PetscInt *points; 1063c58f1c22SToby Isaac 1064c58f1c22SToby Isaac PetscFunctionBegin; 1065d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1066c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 10670c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10680c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 10699566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 10700c3c4a36SLisandro Dalcin /* Set keys */ 10719566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10729566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 10739566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 10749566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 10759566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 1076c58f1c22SToby Isaac PetscFunctionReturn(0); 1077c58f1c22SToby Isaac } 1078c58f1c22SToby Isaac 107984f0b6dfSMatthew G. Knepley /*@ 108084f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 108184f0b6dfSMatthew G. Knepley 10825b5e7992SMatthew G. Knepley Not collective 10835b5e7992SMatthew G. Knepley 108484f0b6dfSMatthew G. Knepley Input Parameter: 108584f0b6dfSMatthew G. Knepley . label - the DMLabel 108684f0b6dfSMatthew G. Knepley 108701d2d390SJose E. Roman Output Parameter: 108884f0b6dfSMatthew G. Knepley . numValues - the number of values 108984f0b6dfSMatthew G. Knepley 109084f0b6dfSMatthew G. Knepley Level: intermediate 109184f0b6dfSMatthew G. Knepley 1092db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 109384f0b6dfSMatthew G. Knepley @*/ 10949371c9d4SSatish Balay PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) { 1095c58f1c22SToby Isaac PetscFunctionBegin; 1096d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1097dadcf809SJacob Faibussowitsch PetscValidIntPointer(numValues, 2); 1098c58f1c22SToby Isaac *numValues = label->numStrata; 1099c58f1c22SToby Isaac PetscFunctionReturn(0); 1100c58f1c22SToby Isaac } 1101c58f1c22SToby Isaac 110284f0b6dfSMatthew G. Knepley /*@ 110384f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 110484f0b6dfSMatthew G. Knepley 11055b5e7992SMatthew G. Knepley Not collective 11065b5e7992SMatthew G. Knepley 110784f0b6dfSMatthew G. Knepley Input Parameter: 110884f0b6dfSMatthew G. Knepley . label - the DMLabel 110984f0b6dfSMatthew G. Knepley 111001d2d390SJose E. Roman Output Parameter: 111184f0b6dfSMatthew G. Knepley . is - the value IS 111284f0b6dfSMatthew G. Knepley 111384f0b6dfSMatthew G. Knepley Level: intermediate 111484f0b6dfSMatthew G. Knepley 11151d04cbbeSVaclav Hapla Notes: 11161d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11171d04cbbeSVaclav Hapla Strata which are allocated but empty [DMLabelGetStratumSize() yields 0] are counted. 11181d04cbbeSVaclav Hapla If you need to count only nonempty strata, use DMLabelGetNonEmptyStratumValuesIS(). 11191d04cbbeSVaclav Hapla 1120db781477SPatrick Sanan .seealso: `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 112184f0b6dfSMatthew G. Knepley @*/ 11229371c9d4SSatish Balay PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) { 1123c58f1c22SToby Isaac PetscFunctionBegin; 1124d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1125c58f1c22SToby Isaac PetscValidPointer(values, 2); 11269566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 1127c58f1c22SToby Isaac PetscFunctionReturn(0); 1128c58f1c22SToby Isaac } 1129c58f1c22SToby Isaac 113084f0b6dfSMatthew G. Knepley /*@ 11311d04cbbeSVaclav Hapla DMLabelGetNonEmptyStratumValuesIS - Get an IS of all values that the DMlabel takes 11321d04cbbeSVaclav Hapla 11331d04cbbeSVaclav Hapla Not collective 11341d04cbbeSVaclav Hapla 11351d04cbbeSVaclav Hapla Input Parameter: 11361d04cbbeSVaclav Hapla . label - the DMLabel 11371d04cbbeSVaclav Hapla 11381d04cbbeSVaclav Hapla Output Paramater: 11391d04cbbeSVaclav Hapla . is - the value IS 11401d04cbbeSVaclav Hapla 11411d04cbbeSVaclav Hapla Level: intermediate 11421d04cbbeSVaclav Hapla 11431d04cbbeSVaclav Hapla Notes: 11441d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11451d04cbbeSVaclav Hapla This is similar to DMLabelGetValueIS() but counts only nonempty strata. 11461d04cbbeSVaclav Hapla 1147db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 11481d04cbbeSVaclav Hapla @*/ 11499371c9d4SSatish Balay PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) { 11501d04cbbeSVaclav Hapla PetscInt i, j; 11511d04cbbeSVaclav Hapla PetscInt *valuesArr; 11521d04cbbeSVaclav Hapla 11531d04cbbeSVaclav Hapla PetscFunctionBegin; 11541d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11551d04cbbeSVaclav Hapla PetscValidPointer(values, 2); 11569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 11571d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 11581d04cbbeSVaclav Hapla PetscInt n; 11591d04cbbeSVaclav Hapla 11609566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 11611d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 11621d04cbbeSVaclav Hapla } 11631d04cbbeSVaclav Hapla if (j == label->numStrata) { 11649566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 11651d04cbbeSVaclav Hapla } else { 11669566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 11671d04cbbeSVaclav Hapla } 11689566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 11691d04cbbeSVaclav Hapla PetscFunctionReturn(0); 11701d04cbbeSVaclav Hapla } 11711d04cbbeSVaclav Hapla 11721d04cbbeSVaclav Hapla /*@ 1173d123abd9SMatthew 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 1174d123abd9SMatthew G. Knepley 1175d123abd9SMatthew G. Knepley Not collective 1176d123abd9SMatthew G. Knepley 1177d123abd9SMatthew G. Knepley Input Parameters: 1178d123abd9SMatthew G. Knepley + label - the DMLabel 117997bb3fdcSJose E. Roman - value - the value 1180d123abd9SMatthew G. Knepley 118101d2d390SJose E. Roman Output Parameter: 1182d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1183d123abd9SMatthew G. Knepley 1184d123abd9SMatthew G. Knepley Level: intermediate 1185d123abd9SMatthew G. Knepley 1186db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1187d123abd9SMatthew G. Knepley @*/ 11889371c9d4SSatish Balay PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) { 1189d123abd9SMatthew G. Knepley PetscInt v; 1190d123abd9SMatthew G. Knepley 1191d123abd9SMatthew G. Knepley PetscFunctionBegin; 1192d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1193dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 3); 1194d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 11959371c9d4SSatish Balay for (v = 0; v < label->numStrata; ++v) 11969371c9d4SSatish Balay if (label->stratumValues[v] == value) break; 1197d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1198d123abd9SMatthew G. Knepley else *index = v; 1199d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1200d123abd9SMatthew G. Knepley } 1201d123abd9SMatthew G. Knepley 1202d123abd9SMatthew G. Knepley /*@ 120384f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 120484f0b6dfSMatthew G. Knepley 12055b5e7992SMatthew G. Knepley Not collective 12065b5e7992SMatthew G. Knepley 120784f0b6dfSMatthew G. Knepley Input Parameters: 120884f0b6dfSMatthew G. Knepley + label - the DMLabel 120984f0b6dfSMatthew G. Knepley - value - the stratum value 121084f0b6dfSMatthew G. Knepley 121101d2d390SJose E. Roman Output Parameter: 121284f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 121384f0b6dfSMatthew G. Knepley 121484f0b6dfSMatthew G. Knepley Level: intermediate 121584f0b6dfSMatthew G. Knepley 1216db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 121784f0b6dfSMatthew G. Knepley @*/ 12189371c9d4SSatish Balay PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) { 1219fada774cSMatthew G. Knepley PetscInt v; 1220fada774cSMatthew G. Knepley 1221fada774cSMatthew G. Knepley PetscFunctionBegin; 1222d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1223dadcf809SJacob Faibussowitsch PetscValidBoolPointer(exists, 3); 12249566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12250c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 1226fada774cSMatthew G. Knepley PetscFunctionReturn(0); 1227fada774cSMatthew G. Knepley } 1228fada774cSMatthew G. Knepley 122984f0b6dfSMatthew G. Knepley /*@ 123084f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 123184f0b6dfSMatthew G. Knepley 12325b5e7992SMatthew G. Knepley Not collective 12335b5e7992SMatthew G. Knepley 123484f0b6dfSMatthew G. Knepley Input Parameters: 123584f0b6dfSMatthew G. Knepley + label - the DMLabel 123684f0b6dfSMatthew G. Knepley - value - the stratum value 123784f0b6dfSMatthew G. Knepley 123801d2d390SJose E. Roman Output Parameter: 123984f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 124084f0b6dfSMatthew G. Knepley 124184f0b6dfSMatthew G. Knepley Level: intermediate 124284f0b6dfSMatthew G. Knepley 1243db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 124484f0b6dfSMatthew G. Knepley @*/ 12459371c9d4SSatish Balay PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) { 1246c58f1c22SToby Isaac PetscInt v; 1247c58f1c22SToby Isaac 1248c58f1c22SToby Isaac PetscFunctionBegin; 1249d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1250dadcf809SJacob Faibussowitsch PetscValidIntPointer(size, 3); 12519566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12529566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 1253c58f1c22SToby Isaac PetscFunctionReturn(0); 1254c58f1c22SToby Isaac } 1255c58f1c22SToby Isaac 125684f0b6dfSMatthew G. Knepley /*@ 125784f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 125884f0b6dfSMatthew G. Knepley 12595b5e7992SMatthew G. Knepley Not collective 12605b5e7992SMatthew G. Knepley 126184f0b6dfSMatthew G. Knepley Input Parameters: 126284f0b6dfSMatthew G. Knepley + label - the DMLabel 126384f0b6dfSMatthew G. Knepley - value - the stratum value 126484f0b6dfSMatthew G. Knepley 126501d2d390SJose E. Roman Output Parameters: 126684f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 126784f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 126884f0b6dfSMatthew G. Knepley 126984f0b6dfSMatthew G. Knepley Level: intermediate 127084f0b6dfSMatthew G. Knepley 1271db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 127284f0b6dfSMatthew G. Knepley @*/ 12739371c9d4SSatish Balay PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) { 12740c3c4a36SLisandro Dalcin PetscInt v, min, max; 1275c58f1c22SToby Isaac 1276c58f1c22SToby Isaac PetscFunctionBegin; 1277d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12789371c9d4SSatish Balay if (start) { 12799371c9d4SSatish Balay PetscValidIntPointer(start, 3); 12809371c9d4SSatish Balay *start = -1; 12819371c9d4SSatish Balay } 12829371c9d4SSatish Balay if (end) { 12839371c9d4SSatish Balay PetscValidIntPointer(end, 4); 12849371c9d4SSatish Balay *end = -1; 12859371c9d4SSatish Balay } 12869566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12870c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 12889566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 12890c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 12909566063dSJacob Faibussowitsch PetscCall(ISGetMinMax(label->points[v], &min, &max)); 1291d6cb179aSToby Isaac if (start) *start = min; 1292d6cb179aSToby Isaac if (end) *end = max + 1; 1293c58f1c22SToby Isaac PetscFunctionReturn(0); 1294c58f1c22SToby Isaac } 1295c58f1c22SToby Isaac 129684f0b6dfSMatthew G. Knepley /*@ 129784f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 129884f0b6dfSMatthew G. Knepley 12995b5e7992SMatthew G. Knepley Not collective 13005b5e7992SMatthew G. Knepley 130184f0b6dfSMatthew G. Knepley Input Parameters: 130284f0b6dfSMatthew G. Knepley + label - the DMLabel 130384f0b6dfSMatthew G. Knepley - value - the stratum value 130484f0b6dfSMatthew G. Knepley 130501d2d390SJose E. Roman Output Parameter: 130684f0b6dfSMatthew G. Knepley . points - The stratum points 130784f0b6dfSMatthew G. Knepley 130884f0b6dfSMatthew G. Knepley Level: intermediate 130984f0b6dfSMatthew G. Knepley 1310593ce467SVaclav Hapla Notes: 1311593ce467SVaclav Hapla The output IS should be destroyed when no longer needed. 1312593ce467SVaclav Hapla Returns NULL if the stratum is empty. 1313593ce467SVaclav Hapla 1314db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 131584f0b6dfSMatthew G. Knepley @*/ 13169371c9d4SSatish Balay PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) { 1317c58f1c22SToby Isaac PetscInt v; 1318c58f1c22SToby Isaac 1319c58f1c22SToby Isaac PetscFunctionBegin; 1320d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1321c58f1c22SToby Isaac PetscValidPointer(points, 3); 1322c58f1c22SToby Isaac *points = NULL; 13239566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13240c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13259566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13269566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label->points[v])); 1327ad8374ffSToby Isaac *points = label->points[v]; 1328c58f1c22SToby Isaac PetscFunctionReturn(0); 1329c58f1c22SToby Isaac } 1330c58f1c22SToby Isaac 133184f0b6dfSMatthew G. Knepley /*@ 133284f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 133384f0b6dfSMatthew G. Knepley 13345b5e7992SMatthew G. Knepley Not collective 13355b5e7992SMatthew G. Knepley 133684f0b6dfSMatthew G. Knepley Input Parameters: 133784f0b6dfSMatthew G. Knepley + label - the DMLabel 133884f0b6dfSMatthew G. Knepley . value - the stratum value 133984f0b6dfSMatthew G. Knepley - points - The stratum points 134084f0b6dfSMatthew G. Knepley 134184f0b6dfSMatthew G. Knepley Level: intermediate 134284f0b6dfSMatthew G. Knepley 1343db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 134484f0b6dfSMatthew G. Knepley @*/ 13459371c9d4SSatish Balay PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) { 13460c3c4a36SLisandro Dalcin PetscInt v; 13474de306b1SToby Isaac 13484de306b1SToby Isaac PetscFunctionBegin; 1349d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1350d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 13519566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 13524de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 13539566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 13549566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &(label->stratumSizes[v]))); 13559566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 13569566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 13570c3c4a36SLisandro Dalcin label->points[v] = is; 13580c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 13599566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 13604de306b1SToby Isaac if (label->bt) { 13614de306b1SToby Isaac const PetscInt *points; 13624de306b1SToby Isaac PetscInt p; 13634de306b1SToby Isaac 13649566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 13654de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 13664de306b1SToby Isaac const PetscInt point = points[p]; 13674de306b1SToby Isaac 136863a3b9bcSJacob 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); 13699566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 13704de306b1SToby Isaac } 13714de306b1SToby Isaac } 13724de306b1SToby Isaac PetscFunctionReturn(0); 13734de306b1SToby Isaac } 13744de306b1SToby Isaac 137584f0b6dfSMatthew G. Knepley /*@ 137684f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 13774de306b1SToby Isaac 13785b5e7992SMatthew G. Knepley Not collective 13795b5e7992SMatthew G. Knepley 138084f0b6dfSMatthew G. Knepley Input Parameters: 138184f0b6dfSMatthew G. Knepley + label - the DMLabel 138284f0b6dfSMatthew G. Knepley - value - the stratum value 138384f0b6dfSMatthew G. Knepley 138484f0b6dfSMatthew G. Knepley Level: intermediate 138584f0b6dfSMatthew G. Knepley 1386db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 138784f0b6dfSMatthew G. Knepley @*/ 13889371c9d4SSatish Balay PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) { 1389c58f1c22SToby Isaac PetscInt v; 1390c58f1c22SToby Isaac 1391c58f1c22SToby Isaac PetscFunctionBegin; 1392d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13939566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13940c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13954de306b1SToby Isaac if (label->validIS[v]) { 13964de306b1SToby Isaac if (label->bt) { 1397c58f1c22SToby Isaac PetscInt i; 1398ad8374ffSToby Isaac const PetscInt *points; 1399c58f1c22SToby Isaac 14009566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1401c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1402ad8374ffSToby Isaac const PetscInt point = points[i]; 1403c58f1c22SToby Isaac 140463a3b9bcSJacob 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); 14059566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1406c58f1c22SToby Isaac } 14079566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1408c58f1c22SToby Isaac } 1409c58f1c22SToby Isaac label->stratumSizes[v] = 0; 14109566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 14119566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 14129566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)label->points[v], "indices")); 14139566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)label)); 1414c58f1c22SToby Isaac } else { 14159566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1416c58f1c22SToby Isaac } 1417c58f1c22SToby Isaac PetscFunctionReturn(0); 1418c58f1c22SToby Isaac } 1419c58f1c22SToby Isaac 142084f0b6dfSMatthew G. Knepley /*@ 1421412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1422412e9a14SMatthew G. Knepley 1423412e9a14SMatthew G. Knepley Not collective 1424412e9a14SMatthew G. Knepley 1425412e9a14SMatthew G. Knepley Input Parameters: 1426412e9a14SMatthew G. Knepley + label - The DMLabel 1427412e9a14SMatthew G. Knepley . value - The label value for all points 1428412e9a14SMatthew G. Knepley . pStart - The first point 1429412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1430412e9a14SMatthew G. Knepley 1431412e9a14SMatthew G. Knepley Note: The marks points are [pStart, pEnd), and only the bounds are stored. 1432412e9a14SMatthew G. Knepley 1433412e9a14SMatthew G. Knepley Level: intermediate 1434412e9a14SMatthew G. Knepley 1435db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1436412e9a14SMatthew G. Knepley @*/ 14379371c9d4SSatish Balay PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) { 1438412e9a14SMatthew G. Knepley IS pIS; 1439412e9a14SMatthew G. Knepley 1440412e9a14SMatthew G. Knepley PetscFunctionBegin; 14419566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 14429566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 14439566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 1444412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1445412e9a14SMatthew G. Knepley } 1446412e9a14SMatthew G. Knepley 1447412e9a14SMatthew G. Knepley /*@ 1448d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1449d123abd9SMatthew G. Knepley 1450d123abd9SMatthew G. Knepley Not collective 1451d123abd9SMatthew G. Knepley 1452d123abd9SMatthew G. Knepley Input Parameters: 1453d123abd9SMatthew G. Knepley + label - The DMLabel 1454d123abd9SMatthew G. Knepley . value - The label value 1455d123abd9SMatthew G. Knepley - p - A point with this value 1456d123abd9SMatthew G. Knepley 1457d123abd9SMatthew G. Knepley Output Parameter: 1458d123abd9SMatthew 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 1459d123abd9SMatthew G. Knepley 1460d123abd9SMatthew G. Knepley Level: intermediate 1461d123abd9SMatthew G. Knepley 1462db781477SPatrick Sanan .seealso: `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1463d123abd9SMatthew G. Knepley @*/ 14649371c9d4SSatish Balay PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) { 1465d123abd9SMatthew G. Knepley const PetscInt *indices; 1466d123abd9SMatthew G. Knepley PetscInt v; 1467d123abd9SMatthew G. Knepley 1468d123abd9SMatthew G. Knepley PetscFunctionBegin; 1469d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1470dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 4); 1471d123abd9SMatthew G. Knepley *index = -1; 14729566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 1473d123abd9SMatthew G. Knepley if (v < 0) PetscFunctionReturn(0); 14749566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 14759566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &indices)); 14769566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 14779566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &indices)); 1478d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1479d123abd9SMatthew G. Knepley } 1480d123abd9SMatthew G. Knepley 1481d123abd9SMatthew G. Knepley /*@ 148284f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 148384f0b6dfSMatthew G. Knepley 14845b5e7992SMatthew G. Knepley Not collective 14855b5e7992SMatthew G. Knepley 148684f0b6dfSMatthew G. Knepley Input Parameters: 148784f0b6dfSMatthew G. Knepley + label - the DMLabel 148822cd2cdaSVaclav Hapla . start - the first point kept 148922cd2cdaSVaclav Hapla - end - one more than the last point kept 149084f0b6dfSMatthew G. Knepley 149184f0b6dfSMatthew G. Knepley Level: intermediate 149284f0b6dfSMatthew G. Knepley 1493db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 149484f0b6dfSMatthew G. Knepley @*/ 14959371c9d4SSatish Balay PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) { 1496c58f1c22SToby Isaac PetscInt v; 1497c58f1c22SToby Isaac 1498c58f1c22SToby Isaac PetscFunctionBegin; 1499d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15009566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 15019566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 150248a46eb9SPierre Jolivet for (v = 0; v < label->numStrata; ++v) PetscCall(ISGeneralFilter(label->points[v], start, end)); 15039566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 1504c58f1c22SToby Isaac PetscFunctionReturn(0); 1505c58f1c22SToby Isaac } 1506c58f1c22SToby Isaac 150784f0b6dfSMatthew G. Knepley /*@ 150884f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 150984f0b6dfSMatthew G. Knepley 15105b5e7992SMatthew G. Knepley Not collective 15115b5e7992SMatthew G. Knepley 151284f0b6dfSMatthew G. Knepley Input Parameters: 151384f0b6dfSMatthew G. Knepley + label - the DMLabel 151484f0b6dfSMatthew G. Knepley - permutation - the point permutation 151584f0b6dfSMatthew G. Knepley 151684f0b6dfSMatthew G. Knepley Output Parameter: 151784f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 151884f0b6dfSMatthew G. Knepley 151984f0b6dfSMatthew G. Knepley Level: intermediate 152084f0b6dfSMatthew G. Knepley 1521db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 152284f0b6dfSMatthew G. Knepley @*/ 15239371c9d4SSatish Balay PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) { 1524c58f1c22SToby Isaac const PetscInt *perm; 1525c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1526c58f1c22SToby Isaac 1527c58f1c22SToby Isaac PetscFunctionBegin; 1528d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1529d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 15309566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 15319566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 15329566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 15339566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 15349566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1535c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1536c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1537ad8374ffSToby Isaac const PetscInt *points; 1538ad8374ffSToby Isaac PetscInt *pointsNew; 1539c58f1c22SToby Isaac 15409566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v], &points)); 15419566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &pointsNew)); 1542c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1543ad8374ffSToby Isaac const PetscInt point = points[q]; 1544c58f1c22SToby Isaac 154563a3b9bcSJacob 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); 1546ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1547c58f1c22SToby Isaac } 15489566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v], &points)); 15499566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 15509566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1551fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 15529566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, size, pointsNew[0], 1, &((*labelNew)->points[v]))); 15539566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1554fa8e8ae5SToby Isaac } else { 15559566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, size, pointsNew, PETSC_OWN_POINTER, &((*labelNew)->points[v]))); 1556fa8e8ae5SToby Isaac } 15579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[v]), "indices")); 1558c58f1c22SToby Isaac } 15599566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1560c58f1c22SToby Isaac if (label->bt) { 15619566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 15629566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1563c58f1c22SToby Isaac } 1564c58f1c22SToby Isaac PetscFunctionReturn(0); 1565c58f1c22SToby Isaac } 1566c58f1c22SToby Isaac 15679371c9d4SSatish Balay PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) { 156826c55118SMichael Lange MPI_Comm comm; 1569eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 157026c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 157126c55118SMichael Lange PetscSection rootSection; 157226c55118SMichael Lange PetscSF labelSF; 157326c55118SMichael Lange 157426c55118SMichael Lange PetscFunctionBegin; 15759566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 15769566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 157726c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 157826c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 15799566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 15809566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 15819566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 158226c55118SMichael Lange if (label) { 158326c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1584ad8374ffSToby Isaac const PetscInt *points; 1585ad8374ffSToby Isaac 15869566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 158748a46eb9SPierre Jolivet for (l = 0; l < label->stratumSizes[s]; l++) PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 15889566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 158926c55118SMichael Lange } 159026c55118SMichael Lange } 15919566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 159226c55118SMichael Lange /* Create a point-wise array of stratum values */ 15939566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 15949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 15959566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 159626c55118SMichael Lange if (label) { 159726c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1598ad8374ffSToby Isaac const PetscInt *points; 1599ad8374ffSToby Isaac 16009566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 160126c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1602ad8374ffSToby Isaac const PetscInt p = points[l]; 16039566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 160426c55118SMichael Lange rootStrata[offset + rootIdx[p]++] = label->stratumValues[s]; 160526c55118SMichael Lange } 16069566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 160726c55118SMichael Lange } 160826c55118SMichael Lange } 160926c55118SMichael Lange /* Build SF that maps label points to remote processes */ 16109566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 16119566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 16129566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 16139566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 161426c55118SMichael Lange /* Send the strata for each point over the derived SF */ 16159566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 16169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 16179566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 16189566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata, MPI_REPLACE)); 161926c55118SMichael Lange /* Clean up */ 16209566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 16219566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 16229566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 16239566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 162426c55118SMichael Lange PetscFunctionReturn(0); 162526c55118SMichael Lange } 162626c55118SMichael Lange 162784f0b6dfSMatthew G. Knepley /*@ 162884f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 162984f0b6dfSMatthew G. Knepley 16305b5e7992SMatthew G. Knepley Collective on sf 16315b5e7992SMatthew G. Knepley 163284f0b6dfSMatthew G. Knepley Input Parameters: 163384f0b6dfSMatthew G. Knepley + label - the DMLabel 163484f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 163584f0b6dfSMatthew G. Knepley 163684f0b6dfSMatthew G. Knepley Output Parameter: 163784f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 163884f0b6dfSMatthew G. Knepley 163984f0b6dfSMatthew G. Knepley Level: intermediate 164084f0b6dfSMatthew G. Knepley 1641db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 164284f0b6dfSMatthew G. Knepley @*/ 16439371c9d4SSatish Balay PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) { 1644c58f1c22SToby Isaac MPI_Comm comm; 164526c55118SMichael Lange PetscSection leafSection; 164626c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 164726c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1648ad8374ffSToby Isaac PetscInt **points; 1649d67d17b1SMatthew G. Knepley const char *lname = NULL; 1650c58f1c22SToby Isaac char *name; 1651c58f1c22SToby Isaac PetscInt nameSize; 1652e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1653c58f1c22SToby Isaac size_t len = 0; 165426c55118SMichael Lange PetscMPIInt rank; 1655c58f1c22SToby Isaac 1656c58f1c22SToby Isaac PetscFunctionBegin; 1657d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1658f018e600SMatthew G. Knepley if (label) { 1659f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16609566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1661f018e600SMatthew G. Knepley } 16629566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 16639566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1664c58f1c22SToby Isaac /* Bcast name */ 1665dd400576SPatrick Sanan if (rank == 0) { 16669566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 16679566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1668d67d17b1SMatthew G. Knepley } 1669c58f1c22SToby Isaac nameSize = len; 16709566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 16719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 16729566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 16739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 16749566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 16759566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 167677d236dfSMichael Lange /* Bcast defaultValue */ 1677dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 16789566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 167926c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 16809566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 16815cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 16829566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 16839566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 16849566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 16859566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 16869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1687ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 16889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 16895cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 16905cbdf6fcSMichael Lange offset = 0; 16919566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 16929566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata, (*labelNew)->stratumValues)); 169348a46eb9SPierre Jolivet for (s = 0; s < (*labelNew)->numStrata; ++s) PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 16945cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1695231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 16969371c9d4SSatish Balay if (leafStrata[p] == (*labelNew)->stratumValues[s]) { 16979371c9d4SSatish Balay leafStrata[p] = s; 16989371c9d4SSatish Balay break; 16999371c9d4SSatish Balay } 17005cbdf6fcSMichael Lange } 17015cbdf6fcSMichael Lange } 1702c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 17039566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->stratumSizes)); 17049566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1705c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 17069566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17079566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1708ad540459SPierre Jolivet for (s = 0; s < dof; s++) (*labelNew)->stratumSizes[leafStrata[offset + s]]++; 1709c58f1c22SToby Isaac } 17109566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &(*labelNew)->ht)); 17119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->points)); 17129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &points)); 1713c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 17149566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 17159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]))); 1716c58f1c22SToby Isaac } 1717c58f1c22SToby Isaac /* Insert points into new strata */ 17189566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 17199566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1720c58f1c22SToby Isaac for (p = pStart; p < pEnd; p++) { 17219566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17229566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1723c58f1c22SToby Isaac for (s = 0; s < dof; s++) { 1724c58f1c22SToby Isaac stratum = leafStrata[offset + s]; 1725ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1726c58f1c22SToby Isaac } 1727c58f1c22SToby Isaac } 1728ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 17299566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (*labelNew)->stratumSizes[s], &(points[s][0]), PETSC_OWN_POINTER, &((*labelNew)->points[s]))); 17309566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]), "indices")); 1731ad8374ffSToby Isaac } 17329566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 17339566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 17349566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 17359566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 17369566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 1737c58f1c22SToby Isaac PetscFunctionReturn(0); 1738c58f1c22SToby Isaac } 1739c58f1c22SToby Isaac 17407937d9ceSMichael Lange /*@ 17417937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 17427937d9ceSMichael Lange 17435b5e7992SMatthew G. Knepley Collective on sf 17445b5e7992SMatthew G. Knepley 17457937d9ceSMichael Lange Input Parameters: 17467937d9ceSMichael Lange + label - the DMLabel 174784f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 17487937d9ceSMichael Lange 174984f0b6dfSMatthew G. Knepley Output Parameters: 175084f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 17517937d9ceSMichael Lange 17527937d9ceSMichael Lange Level: developer 17537937d9ceSMichael Lange 17547937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 17557937d9ceSMichael Lange 1756db781477SPatrick Sanan .seealso: `DMLabelDistribute()` 17577937d9ceSMichael Lange @*/ 17589371c9d4SSatish Balay PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) { 17597937d9ceSMichael Lange MPI_Comm comm; 17607937d9ceSMichael Lange PetscSection rootSection; 17617937d9ceSMichael Lange PetscSF sfLabel; 17627937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 17637937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 17647937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 17657937d9ceSMichael Lange PetscInt *rootStrata; 1766d67d17b1SMatthew G. Knepley const char *lname; 17677937d9ceSMichael Lange char *name; 17687937d9ceSMichael Lange PetscInt nameSize; 17697937d9ceSMichael Lange size_t len = 0; 17709852e123SBarry Smith PetscMPIInt rank, size; 17717937d9ceSMichael Lange 17727937d9ceSMichael Lange PetscFunctionBegin; 1773d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1774d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 17769566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 17779566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 17787937d9ceSMichael Lange /* Bcast name */ 1779dd400576SPatrick Sanan if (rank == 0) { 17809566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)label, &lname)); 17819566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1782d67d17b1SMatthew G. Knepley } 17837937d9ceSMichael Lange nameSize = len; 17849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 17859566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize + 1, &name)); 17869566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize + 1)); 17879566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize + 1, MPI_CHAR, 0, comm)); 17889566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 17899566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 17907937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 17917937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 17927937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 17939566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 17949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1795dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 17967937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 17978212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 17988212dd46SStefano Zampini 17998212dd46SStefano Zampini leafPoints[ilp].index = ilp; 18008212dd46SStefano Zampini leafPoints[ilp].rank = rank; 18017937d9ceSMichael Lange } 18029566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 18039566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 18047937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 18059566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 18069566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 18079566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 18089566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm, &sfLabel)); 18099566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 18107937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 18119566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 18127937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 18137937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 18147937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 18159566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx + d, &dof)); 18169566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx + d, &offset)); 18179566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset + s])); 18187937d9ceSMichael Lange } 18197937d9ceSMichael Lange idx += rootDegree[p]; 18207937d9ceSMichael Lange } 18219566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 18229566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 18239566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 18249566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 18257937d9ceSMichael Lange PetscFunctionReturn(0); 18267937d9ceSMichael Lange } 18277937d9ceSMichael Lange 18289371c9d4SSatish Balay static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) { 1829d42890abSMatthew G. Knepley const PetscInt *degree; 1830d42890abSMatthew G. Knepley const PetscInt *points; 1831d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1832d42890abSMatthew G. Knepley 1833d42890abSMatthew G. Knepley PetscFunctionBegin; 1834d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1835d42890abSMatthew G. Knepley /* Add in leaves */ 1836d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1837d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1838d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 1839d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 1840d42890abSMatthew G. Knepley } 1841d42890abSMatthew G. Knepley /* Add in shared roots */ 1842d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1843d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1844d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1845d42890abSMatthew G. Knepley if (degree[r]) { 1846d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1847d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 1848d42890abSMatthew G. Knepley } 1849d42890abSMatthew G. Knepley } 1850d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1851d42890abSMatthew G. Knepley } 1852d42890abSMatthew G. Knepley 18539371c9d4SSatish Balay static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) { 1854d42890abSMatthew G. Knepley const PetscInt *degree; 1855d42890abSMatthew G. Knepley const PetscInt *points; 1856d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1857d42890abSMatthew G. Knepley 1858d42890abSMatthew G. Knepley PetscFunctionBegin; 1859d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1860d42890abSMatthew G. Knepley /* Read out leaves */ 1861d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1862d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1863d42890abSMatthew G. Knepley const PetscInt p = points[l]; 1864d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 1865d42890abSMatthew G. Knepley 1866d42890abSMatthew G. Knepley if (cval != defVal) { 1867d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 1868d42890abSMatthew G. Knepley if (val == defVal) { 1869d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 187048a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, p, cval, ctx)); 1871d42890abSMatthew G. Knepley } 1872d42890abSMatthew G. Knepley } 1873d42890abSMatthew G. Knepley } 1874d42890abSMatthew G. Knepley /* Read out shared roots */ 1875d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1876d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1877d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1878d42890abSMatthew G. Knepley if (degree[r]) { 1879d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 1880d42890abSMatthew G. Knepley 1881d42890abSMatthew G. Knepley if (cval != defVal) { 1882d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1883d42890abSMatthew G. Knepley if (val == defVal) { 1884d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 188548a46eb9SPierre Jolivet if (markPoint) PetscCall((*markPoint)(label, r, cval, ctx)); 1886d42890abSMatthew G. Knepley } 1887d42890abSMatthew G. Knepley } 1888d42890abSMatthew G. Knepley } 1889d42890abSMatthew G. Knepley } 1890d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1891d42890abSMatthew G. Knepley } 1892d42890abSMatthew G. Knepley 1893d42890abSMatthew G. Knepley /*@ 1894d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 1895d42890abSMatthew G. Knepley 1896d42890abSMatthew G. Knepley Collective on sf 1897d42890abSMatthew G. Knepley 1898d42890abSMatthew G. Knepley Input Parameters: 1899d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1900d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1901d42890abSMatthew G. Knepley 1902d42890abSMatthew G. Knepley Level: intermediate 1903d42890abSMatthew G. Knepley 1904db781477SPatrick Sanan .seealso: `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 1905d42890abSMatthew G. Knepley @*/ 19069371c9d4SSatish Balay PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) { 1907d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 1908d42890abSMatthew G. Knepley PetscMPIInt size; 1909d42890abSMatthew G. Knepley 1910d42890abSMatthew G. Knepley PetscFunctionBegin; 1911d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)sf), &size)); 1912d42890abSMatthew G. Knepley if (size > 1) { 1913d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1914d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 1915d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 1916d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 1917d42890abSMatthew G. Knepley } 1918d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1919d42890abSMatthew G. Knepley } 1920d42890abSMatthew G. Knepley 1921d42890abSMatthew G. Knepley /*@ 1922d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 1923d42890abSMatthew G. Knepley 1924d42890abSMatthew G. Knepley Collective on sf 1925d42890abSMatthew G. Knepley 1926d42890abSMatthew G. Knepley Input Parameters: 1927d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1928d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1929d42890abSMatthew G. Knepley 1930d42890abSMatthew G. Knepley Level: intermediate 1931d42890abSMatthew G. Knepley 1932db781477SPatrick Sanan .seealso: `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 1933d42890abSMatthew G. Knepley @*/ 19349371c9d4SSatish Balay PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) { 1935d42890abSMatthew G. Knepley PetscFunctionBegin; 1936d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 1937d42890abSMatthew G. Knepley label->propArray = NULL; 1938d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1939d42890abSMatthew G. Knepley } 1940d42890abSMatthew G. Knepley 1941d42890abSMatthew G. Knepley /*@C 1942d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 1943d42890abSMatthew G. Knepley 1944d42890abSMatthew G. Knepley Collective on sf 1945d42890abSMatthew G. Knepley 1946d42890abSMatthew G. Knepley Input Parameters: 1947d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1948d42890abSMatthew G. Knepley . sf - The SF describing parallel layout of the label points 1949ef1023bdSBarry Smith . markPoint - An optional callback that is called when a point is marked, or NULL 1950d42890abSMatthew G. Knepley - ctx - An optional user context for the callback, or NULL 1951d42890abSMatthew G. Knepley 1952d42890abSMatthew G. Knepley Calling sequence of markPoint: 1953d42890abSMatthew G. Knepley $ markPoint(DMLabel label, PetscInt p, PetscInt val, void *ctx); 1954d42890abSMatthew G. Knepley 1955d42890abSMatthew G. Knepley + label - The DMLabel 1956d42890abSMatthew G. Knepley . p - The point being marked 1957d42890abSMatthew G. Knepley . val - The label value for p 1958d42890abSMatthew G. Knepley - ctx - An optional user context 1959d42890abSMatthew G. Knepley 1960d42890abSMatthew G. Knepley Level: intermediate 1961d42890abSMatthew G. Knepley 1962db781477SPatrick Sanan .seealso: `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 1963d42890abSMatthew G. Knepley @*/ 19649371c9d4SSatish Balay PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) { 1965c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 1966d42890abSMatthew G. Knepley PetscMPIInt size; 1967d42890abSMatthew G. Knepley 1968d42890abSMatthew G. Knepley PetscFunctionBegin; 1969d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)pointSF), &size)); 1970c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 1971c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 1972d42890abSMatthew G. Knepley /* Communicate marked edges 1973d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 1974d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 1975d42890abSMatthew G. Knepley 1976d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 1977d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 1978d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 1979d42890abSMatthew G. Knepley 1980d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 1981d42890abSMatthew 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 1982d42890abSMatthew G. Knepley edge to the queue. 1983d42890abSMatthew G. Knepley */ 1984d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 1985d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 1986d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 1987d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 1988d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray, MPI_REPLACE)); 1989d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 1990d42890abSMatthew G. Knepley } 1991d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1992d42890abSMatthew G. Knepley } 1993d42890abSMatthew G. Knepley 199484f0b6dfSMatthew G. Knepley /*@ 199584f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 199684f0b6dfSMatthew G. Knepley 19975b5e7992SMatthew G. Knepley Not collective 19985b5e7992SMatthew G. Knepley 199984f0b6dfSMatthew G. Knepley Input Parameter: 200084f0b6dfSMatthew G. Knepley . label - the DMLabel 200184f0b6dfSMatthew G. Knepley 200284f0b6dfSMatthew G. Knepley Output Parameters: 200384f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 200484f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 200584f0b6dfSMatthew G. Knepley 200684f0b6dfSMatthew G. Knepley Level: developer 200784f0b6dfSMatthew G. Knepley 2008db781477SPatrick Sanan .seealso: `DMLabelDistribute()` 200984f0b6dfSMatthew G. Knepley @*/ 20109371c9d4SSatish Balay PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) { 2011c58f1c22SToby Isaac IS vIS; 2012c58f1c22SToby Isaac const PetscInt *values; 2013c58f1c22SToby Isaac PetscInt *points; 2014c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2015c58f1c22SToby Isaac 2016c58f1c22SToby Isaac PetscFunctionBegin; 2017d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 20189566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 20199566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 20209566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 20219371c9d4SSatish Balay if (nV) { 20229371c9d4SSatish Balay vS = values[0]; 20239371c9d4SSatish Balay vE = values[0] + 1; 20249371c9d4SSatish Balay } 2025c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2026c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2027c58f1c22SToby Isaac vE = PetscMax(vE, values[v] + 1); 2028c58f1c22SToby Isaac } 20299566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 20309566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2031c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2032c58f1c22SToby Isaac PetscInt n; 2033c58f1c22SToby Isaac 20349566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 20359566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2036c58f1c22SToby Isaac } 20379566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 20389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 20399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2040c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2041c58f1c22SToby Isaac IS is; 2042c58f1c22SToby Isaac const PetscInt *spoints; 2043c58f1c22SToby Isaac PetscInt dof, off, p; 2044c58f1c22SToby Isaac 20459566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 20469566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 20479566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 20489566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2049c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off + p] = spoints[p]; 20509566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 20519566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2052c58f1c22SToby Isaac } 20539566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 20549566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 20559566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 2056c58f1c22SToby Isaac PetscFunctionReturn(0); 2057c58f1c22SToby Isaac } 2058c58f1c22SToby Isaac 205984f0b6dfSMatthew G. Knepley /*@ 2060c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 2061c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 2062c58f1c22SToby Isaac 20635b5e7992SMatthew G. Knepley Collective on sf 20645b5e7992SMatthew G. Knepley 2065c58f1c22SToby Isaac Input Parameters: 2066c58f1c22SToby Isaac + s - The PetscSection for the local field layout 2067c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 2068c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 2069c58f1c22SToby Isaac . label - The label specifying the points 2070c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2071c58f1c22SToby Isaac 2072c58f1c22SToby Isaac Output Parameter: 2073c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 2074c58f1c22SToby Isaac 2075c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 2076c58f1c22SToby Isaac 2077c58f1c22SToby Isaac Level: developer 2078c58f1c22SToby Isaac 2079db781477SPatrick Sanan .seealso: `PetscSectionCreate()` 2080c58f1c22SToby Isaac @*/ 20819371c9d4SSatish Balay PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) { 2082c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2083c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2084c58f1c22SToby Isaac 2085c58f1c22SToby Isaac PetscFunctionBegin; 2086d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2087d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2088d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 20899566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)s), gsection)); 20909566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 20919566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 20929566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2093c58f1c22SToby Isaac if (nroots >= 0) { 209463a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd - pStart, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd - pStart); 20959566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2096c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 20979566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2098c58f1c22SToby Isaac } else { 2099c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2100c58f1c22SToby Isaac } 2101c58f1c22SToby Isaac } 2102c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2103c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2104c58f1c22SToby Isaac PetscInt value; 2105c58f1c22SToby Isaac 21069566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2107c58f1c22SToby Isaac if (value != labelValue) continue; 21089566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 21099566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 21109566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 21119566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2112c58f1c22SToby Isaac if (neg) neg[p] = -(dof + 1); 2113c58f1c22SToby Isaac } 21149566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2115c58f1c22SToby Isaac if (nroots >= 0) { 21169566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 21179566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2118c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 21199371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 21209371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasDof[p - pStart] = tmpOff[p]; 21219371c9d4SSatish Balay } 2122c58f1c22SToby Isaac } 2123c58f1c22SToby Isaac } 2124c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 2125c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2126c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2127c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2128c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p] - cdof : 0; 2129c58f1c22SToby Isaac } 21309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)s))); 2131c58f1c22SToby Isaac globalOff -= off; 2132c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd - pStart; ++p) { 2133c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2134c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p] + 1); 2135c58f1c22SToby Isaac } 2136c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2137c58f1c22SToby Isaac if (nroots >= 0) { 21389566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 21399566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff, MPI_REPLACE)); 2140c58f1c22SToby Isaac if (nroots > pEnd - pStart) { 21419371c9d4SSatish Balay for (p = pStart; p < pEnd; ++p) { 21429371c9d4SSatish Balay if (tmpOff[p] < 0) (*gsection)->atlasOff[p - pStart] = tmpOff[p]; 21439371c9d4SSatish Balay } 2144c58f1c22SToby Isaac } 2145c58f1c22SToby Isaac } 21469566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd - pStart) PetscCall(PetscFree(tmpOff)); 21479566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 2148c58f1c22SToby Isaac PetscFunctionReturn(0); 2149c58f1c22SToby Isaac } 2150c58f1c22SToby Isaac 21519371c9d4SSatish Balay typedef struct _n_PetscSectionSym_Label { 21525fdea053SToby Isaac DMLabel label; 21535fdea053SToby Isaac PetscCopyMode *modes; 21545fdea053SToby Isaac PetscInt *sizes; 21555fdea053SToby Isaac const PetscInt ***perms; 21565fdea053SToby Isaac const PetscScalar ***rots; 21575fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 21585fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 21595fdea053SToby Isaac } PetscSectionSym_Label; 21605fdea053SToby Isaac 21619371c9d4SSatish Balay static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) { 21625fdea053SToby Isaac PetscInt i, j; 21635fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 21645fdea053SToby Isaac 21655fdea053SToby Isaac PetscFunctionBegin; 21665fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 21675fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 21685fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 21699566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 21709566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 21715fdea053SToby Isaac } 21725fdea053SToby Isaac if (sl->perms[i]) { 21735fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 21745fdea053SToby Isaac 21759566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 21765fdea053SToby Isaac } 21775fdea053SToby Isaac if (sl->rots[i]) { 21785fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 21795fdea053SToby Isaac 21809566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 21815fdea053SToby Isaac } 21825fdea053SToby Isaac } 21835fdea053SToby Isaac } 21849566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes, sl->sizes, sl->perms, sl->rots, sl->minMaxOrients)); 21859566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 21865fdea053SToby Isaac sl->numStrata = 0; 21875fdea053SToby Isaac PetscFunctionReturn(0); 21885fdea053SToby Isaac } 21895fdea053SToby Isaac 21909371c9d4SSatish Balay static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) { 21915fdea053SToby Isaac PetscFunctionBegin; 21929566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 21939566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 21945fdea053SToby Isaac PetscFunctionReturn(0); 21955fdea053SToby Isaac } 21965fdea053SToby Isaac 21979371c9d4SSatish Balay static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) { 21985fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 21995fdea053SToby Isaac PetscBool isAscii; 22005fdea053SToby Isaac DMLabel label = sl->label; 2201d67d17b1SMatthew G. Knepley const char *name; 22025fdea053SToby Isaac 22035fdea053SToby Isaac PetscFunctionBegin; 22049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 22055fdea053SToby Isaac if (isAscii) { 22065fdea053SToby Isaac PetscInt i, j, k; 22075fdea053SToby Isaac PetscViewerFormat format; 22085fdea053SToby Isaac 22099566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 22105fdea053SToby Isaac if (label) { 22119566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 22125fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22149566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 22159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22165fdea053SToby Isaac } else { 22179566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 22189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Label '%s'\n", name)); 22195fdea053SToby Isaac } 22205fdea053SToby Isaac } else { 22219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 22225fdea053SToby Isaac } 22239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22245fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22255fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 22265fdea053SToby Isaac 22275fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 222863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 22295fdea053SToby Isaac } else { 223063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 22319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 223263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 22335fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22349566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22355fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 22365fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 223763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n", j)); 22385fdea053SToby Isaac } else { 22395fdea053SToby Isaac PetscInt tab; 22405fdea053SToby Isaac 224163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n", j)); 22429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tab)); 22445fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 22459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Permutation:")); 22469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 224763a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sl->perms[i][j][k])); 22489566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 22499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 22505fdea053SToby Isaac } 22515fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 22529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Rotations: ")); 22539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, 0)); 22545fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 225563a3b9bcSJacob 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]))); 22565fdea053SToby Isaac #else 225763a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer, " %+g", (double)sl->rots[i][j][k])); 22585fdea053SToby Isaac #endif 22599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 22609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tab)); 22615fdea053SToby Isaac } 22629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22635fdea053SToby Isaac } 22645fdea053SToby Isaac } 22659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22665fdea053SToby Isaac } 22679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22685fdea053SToby Isaac } 22695fdea053SToby Isaac } 22709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22715fdea053SToby Isaac } 22725fdea053SToby Isaac PetscFunctionReturn(0); 22735fdea053SToby Isaac } 22745fdea053SToby Isaac 22755fdea053SToby Isaac /*@ 22765fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 22775fdea053SToby Isaac 22785fdea053SToby Isaac Logically collective on sym 22795fdea053SToby Isaac 22805fdea053SToby Isaac Input parameters: 22815fdea053SToby Isaac + sym - the section symmetries 22825fdea053SToby Isaac - label - the DMLabel describing the types of points 22835fdea053SToby Isaac 22845fdea053SToby Isaac Level: developer: 22855fdea053SToby Isaac 2286db781477SPatrick Sanan .seealso: `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 22875fdea053SToby Isaac @*/ 22889371c9d4SSatish Balay PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) { 22895fdea053SToby Isaac PetscSectionSym_Label *sl; 22905fdea053SToby Isaac 22915fdea053SToby Isaac PetscFunctionBegin; 22925fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 22935fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 22949566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 22955fdea053SToby Isaac if (label) { 22965fdea053SToby Isaac sl->label = label; 22979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)label)); 22989566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &sl->numStrata)); 22999566063dSJacob 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)); 23009566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->modes, (sl->numStrata + 1) * sizeof(PetscCopyMode))); 23019566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->sizes, (sl->numStrata + 1) * sizeof(PetscInt))); 23029566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->perms, (sl->numStrata + 1) * sizeof(const PetscInt **))); 23039566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->rots, (sl->numStrata + 1) * sizeof(const PetscScalar **))); 23049566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *)sl->minMaxOrients, (sl->numStrata + 1) * sizeof(PetscInt[2]))); 23055fdea053SToby Isaac } 23065fdea053SToby Isaac PetscFunctionReturn(0); 23075fdea053SToby Isaac } 23085fdea053SToby Isaac 23095fdea053SToby Isaac /*@C 2310b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2311b004864fSMatthew G. Knepley 2312b004864fSMatthew G. Knepley Logically collective on sym 2313b004864fSMatthew G. Knepley 2314b004864fSMatthew G. Knepley Input Parameters: 2315b004864fSMatthew G. Knepley + sym - the section symmetries 2316b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2317b004864fSMatthew G. Knepley 2318b004864fSMatthew G. Knepley Output Parameters: 2319b004864fSMatthew G. Knepley + size - the number of dofs for points in the stratum of the label 2320b004864fSMatthew G. Knepley . minOrient - the smallest orientation for a point in this stratum 2321b004864fSMatthew G. Knepley . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 2322b004864fSMatthew G. Knepley . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2323b004864fSMatthew 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 2324b004864fSMatthew G. Knepley 2325b004864fSMatthew G. Knepley Level: developer 2326b004864fSMatthew G. Knepley 2327db781477SPatrick Sanan .seealso: `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2328b004864fSMatthew G. Knepley @*/ 23299371c9d4SSatish Balay PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) { 2330b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2331b004864fSMatthew G. Knepley const char *name; 2332b004864fSMatthew G. Knepley PetscInt i; 2333b004864fSMatthew G. Knepley 2334b004864fSMatthew G. Knepley PetscFunctionBegin; 2335b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 2336b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *)sym->data; 2337b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2338b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2339b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2340b004864fSMatthew G. Knepley 2341b004864fSMatthew G. Knepley if (stratum == value) break; 2342b004864fSMatthew G. Knepley } 23439566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 2344b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 23459371c9d4SSatish Balay if (size) { 23469371c9d4SSatish Balay PetscValidIntPointer(size, 3); 23479371c9d4SSatish Balay *size = sl->sizes[i]; 23489371c9d4SSatish Balay } 23499371c9d4SSatish Balay if (minOrient) { 23509371c9d4SSatish Balay PetscValidIntPointer(minOrient, 4); 23519371c9d4SSatish Balay *minOrient = sl->minMaxOrients[i][0]; 23529371c9d4SSatish Balay } 23539371c9d4SSatish Balay if (maxOrient) { 23549371c9d4SSatish Balay PetscValidIntPointer(maxOrient, 5); 23559371c9d4SSatish Balay *maxOrient = sl->minMaxOrients[i][1]; 23569371c9d4SSatish Balay } 23579371c9d4SSatish Balay if (perms) { 23589371c9d4SSatish Balay PetscValidPointer(perms, 6); 23599371c9d4SSatish Balay *perms = sl->perms[i] ? &sl->perms[i][sl->minMaxOrients[i][0]] : NULL; 23609371c9d4SSatish Balay } 23619371c9d4SSatish Balay if (rots) { 23629371c9d4SSatish Balay PetscValidPointer(rots, 7); 23639371c9d4SSatish Balay *rots = sl->rots[i] ? &sl->rots[i][sl->minMaxOrients[i][0]] : NULL; 23649371c9d4SSatish Balay } 2365b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2366b004864fSMatthew G. Knepley } 2367b004864fSMatthew G. Knepley 2368b004864fSMatthew G. Knepley /*@C 23695fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 23705fdea053SToby Isaac 23715b5e7992SMatthew G. Knepley Logically collective on sym 23725fdea053SToby Isaac 23735fdea053SToby Isaac InputParameters: 23745b5e7992SMatthew G. Knepley + sym - the section symmetries 23755fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 23765fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 23775fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 23785fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 23795fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 23805fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2381a2b725a8SWilliam 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 23825fdea053SToby Isaac 23835fdea053SToby Isaac Level: developer 23845fdea053SToby Isaac 2385db781477SPatrick Sanan .seealso: `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 23865fdea053SToby Isaac @*/ 23879371c9d4SSatish Balay PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) { 23885fdea053SToby Isaac PetscSectionSym_Label *sl; 2389d67d17b1SMatthew G. Knepley const char *name; 2390d67d17b1SMatthew G. Knepley PetscInt i, j, k; 23915fdea053SToby Isaac 23925fdea053SToby Isaac PetscFunctionBegin; 23935fdea053SToby Isaac PetscValidHeaderSpecific(sym, PETSC_SECTION_SYM_CLASSID, 1); 23945fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 2395b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 23965fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 23975fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 23985fdea053SToby Isaac 23995fdea053SToby Isaac if (stratum == value) break; 24005fdea053SToby Isaac } 24019566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)sl->label, &name)); 240263a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject)sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 24035fdea053SToby Isaac sl->sizes[i] = size; 24045fdea053SToby Isaac sl->modes[i] = mode; 24055fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 24065fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 24075fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 24085fdea053SToby Isaac if (perms) { 24095fdea053SToby Isaac PetscInt **ownPerms; 24105fdea053SToby Isaac 24119566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownPerms)); 24125fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 24135fdea053SToby Isaac if (perms[j]) { 24149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownPerms[j])); 2415ad540459SPierre Jolivet for (k = 0; k < size; k++) ownPerms[j][k] = perms[j][k]; 24165fdea053SToby Isaac } 24175fdea053SToby Isaac } 24185fdea053SToby Isaac sl->perms[i] = (const PetscInt **)&ownPerms[-minOrient]; 24195fdea053SToby Isaac } 24205fdea053SToby Isaac if (rots) { 24215fdea053SToby Isaac PetscScalar **ownRots; 24225fdea053SToby Isaac 24239566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient, &ownRots)); 24245fdea053SToby Isaac for (j = 0; j < maxOrient - minOrient; j++) { 24255fdea053SToby Isaac if (rots[j]) { 24269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &ownRots[j])); 2427ad540459SPierre Jolivet for (k = 0; k < size; k++) ownRots[j][k] = rots[j][k]; 24285fdea053SToby Isaac } 24295fdea053SToby Isaac } 24305fdea053SToby Isaac sl->rots[i] = (const PetscScalar **)&ownRots[-minOrient]; 24315fdea053SToby Isaac } 24325fdea053SToby Isaac } else { 24335fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 24345fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 24355fdea053SToby Isaac } 24365fdea053SToby Isaac PetscFunctionReturn(0); 24375fdea053SToby Isaac } 24385fdea053SToby Isaac 24399371c9d4SSatish Balay static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) { 24405fdea053SToby Isaac PetscInt i, j, numStrata; 24415fdea053SToby Isaac PetscSectionSym_Label *sl; 24425fdea053SToby Isaac DMLabel label; 24435fdea053SToby Isaac 24445fdea053SToby Isaac PetscFunctionBegin; 24455fdea053SToby Isaac sl = (PetscSectionSym_Label *)sym->data; 24465fdea053SToby Isaac numStrata = sl->numStrata; 24475fdea053SToby Isaac label = sl->label; 24485fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 24495fdea053SToby Isaac PetscInt point = points[2 * i]; 24505fdea053SToby Isaac PetscInt ornt = points[2 * i + 1]; 24515fdea053SToby Isaac 24525fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 24535fdea053SToby Isaac if (label->validIS[j]) { 24545fdea053SToby Isaac PetscInt k; 24555fdea053SToby Isaac 24569566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j], point, &k)); 24575fdea053SToby Isaac if (k >= 0) break; 24585fdea053SToby Isaac } else { 24595fdea053SToby Isaac PetscBool has; 24605fdea053SToby Isaac 24619566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 24625fdea053SToby Isaac if (has) break; 24635fdea053SToby Isaac } 24645fdea053SToby Isaac } 24659371c9d4SSatish 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], 24669371c9d4SSatish Balay j < numStrata ? label->stratumValues[j] : label->defaultValue); 2467ad540459SPierre Jolivet if (perms) perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL; 2468ad540459SPierre Jolivet if (rots) rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL; 24695fdea053SToby Isaac } 24705fdea053SToby Isaac PetscFunctionReturn(0); 24715fdea053SToby Isaac } 24725fdea053SToby Isaac 24739371c9d4SSatish Balay static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) { 2474b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)nsym->data; 2475b004864fSMatthew G. Knepley IS valIS; 2476b004864fSMatthew G. Knepley const PetscInt *values; 2477b004864fSMatthew G. Knepley PetscInt Nv, v; 2478b004864fSMatthew G. Knepley 2479b004864fSMatthew G. Knepley PetscFunctionBegin; 24809566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 24819566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 24829566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2483b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2484b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2485b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2486b004864fSMatthew G. Knepley const PetscInt **perms; 2487b004864fSMatthew G. Knepley const PetscScalar **rots; 2488b004864fSMatthew G. Knepley 24899566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 24909566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2491b004864fSMatthew G. Knepley } 24929566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 2493b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2494b004864fSMatthew G. Knepley } 2495b004864fSMatthew G. Knepley 24969371c9d4SSatish Balay static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) { 2497b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *)sym->data; 2498b004864fSMatthew G. Knepley DMLabel dlabel; 2499b004864fSMatthew G. Knepley 2500b004864fSMatthew G. Knepley PetscFunctionBegin; 25019566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 25029566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject)sym), dlabel, dsym)); 25039566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 25049566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 2505b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2506b004864fSMatthew G. Knepley } 2507b004864fSMatthew G. Knepley 25089371c9d4SSatish Balay PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) { 25095fdea053SToby Isaac PetscSectionSym_Label *sl; 25105fdea053SToby Isaac 25115fdea053SToby Isaac PetscFunctionBegin; 2512*4dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&sl)); 25135fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2514b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2515b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 25165fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 25175fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 25185fdea053SToby Isaac sym->data = (void *)sl; 25195fdea053SToby Isaac PetscFunctionReturn(0); 25205fdea053SToby Isaac } 25215fdea053SToby Isaac 25225fdea053SToby Isaac /*@ 25235fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 25245fdea053SToby Isaac 25255fdea053SToby Isaac Collective 25265fdea053SToby Isaac 25275fdea053SToby Isaac Input Parameters: 25285fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 25295fdea053SToby Isaac - label - the label defining the strata 25305fdea053SToby Isaac 25315fdea053SToby Isaac Output Parameters: 25325fdea053SToby Isaac . sym - the section symmetries 25335fdea053SToby Isaac 25345fdea053SToby Isaac Level: developer 25355fdea053SToby Isaac 2536db781477SPatrick Sanan .seealso: `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 25375fdea053SToby Isaac @*/ 25389371c9d4SSatish Balay PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) { 25395fdea053SToby Isaac PetscFunctionBegin; 25409566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 25419566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm, sym)); 25429566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym, PETSCSECTIONSYMLABEL)); 25439566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym, label)); 25445fdea053SToby Isaac PetscFunctionReturn(0); 25455fdea053SToby Isaac } 2546