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 @*/ 27d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelCreate(MPI_Comm comm, const char name[], DMLabel *label) 28c58f1c22SToby Isaac { 29c58f1c22SToby Isaac PetscFunctionBegin; 30064a246eSJacob Faibussowitsch PetscValidPointer(label,3); 319566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 32c58f1c22SToby Isaac 339566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(*label,DMLABEL_CLASSID,"DMLabel","DMLabel","DM",comm,DMLabelDestroy,DMLabelView)); 34d67d17b1SMatthew G. Knepley 35c58f1c22SToby Isaac (*label)->numStrata = 0; 365aa44df4SToby Isaac (*label)->defaultValue = -1; 37c58f1c22SToby Isaac (*label)->stratumValues = NULL; 38ad8374ffSToby Isaac (*label)->validIS = NULL; 39c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 40c58f1c22SToby Isaac (*label)->points = NULL; 41c58f1c22SToby Isaac (*label)->ht = NULL; 42c58f1c22SToby Isaac (*label)->pStart = -1; 43c58f1c22SToby Isaac (*label)->pEnd = -1; 44c58f1c22SToby Isaac (*label)->bt = NULL; 459566063dSJacob Faibussowitsch PetscCall(PetscHMapICreate(&(*label)->hmap)); 469566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) *label, name)); 47c58f1c22SToby Isaac PetscFunctionReturn(0); 48c58f1c22SToby Isaac } 49c58f1c22SToby Isaac 50c58f1c22SToby Isaac /* 51c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 52c58f1c22SToby Isaac 535b5e7992SMatthew G. Knepley Not collective 545b5e7992SMatthew G. Knepley 55c58f1c22SToby Isaac Input parameter: 56c58f1c22SToby Isaac + label - The DMLabel 57c58f1c22SToby Isaac - v - The stratum value 58c58f1c22SToby Isaac 59c58f1c22SToby Isaac Output parameter: 60c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format 61c58f1c22SToby Isaac 62c58f1c22SToby Isaac Level: developer 63c58f1c22SToby Isaac 64db781477SPatrick Sanan .seealso: `DMLabelCreate()` 65c58f1c22SToby Isaac */ 66c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) 67c58f1c22SToby Isaac { 68277ea44aSLisandro Dalcin IS is; 69b9907514SLisandro Dalcin PetscInt off = 0, *pointArray, p; 70c58f1c22SToby Isaac 71b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) return 0; 72c58f1c22SToby Isaac PetscFunctionBegin; 731dca8a05SBarry Smith PetscCheck(v >= 0 && v < label->numStrata,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %" PetscInt_FMT " in DMLabelMakeValid_Private", v); 749566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v])); 759566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->stratumSizes[v], &pointArray)); 769566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(label->ht[v], &off, pointArray)); 779566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 789566063dSJacob Faibussowitsch PetscCall(PetscSortInt(label->stratumSizes[v], pointArray)); 79c58f1c22SToby Isaac if (label->bt) { 80c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 81ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 8263a3b9bcSJacob Faibussowitsch PetscCheck(!(point < label->pStart) && !(point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %" PetscInt_FMT " is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", point, label->pStart, label->pEnd); 839566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 84c58f1c22SToby Isaac } 85c58f1c22SToby Isaac } 86ba2698f1SMatthew G. Knepley if (label->stratumSizes[v] > 0 && pointArray[label->stratumSizes[v]-1] == pointArray[0] + label->stratumSizes[v]-1) { 879566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, label->stratumSizes[v], pointArray[0], 1, &is)); 889566063dSJacob Faibussowitsch PetscCall(PetscFree(pointArray)); 89ba2698f1SMatthew G. Knepley } else { 909566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is)); 91ba2698f1SMatthew G. Knepley } 929566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) is, "indices")); 93277ea44aSLisandro Dalcin label->points[v] = is; 94ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 959566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject) label)); 96c58f1c22SToby Isaac PetscFunctionReturn(0); 97c58f1c22SToby Isaac } 98c58f1c22SToby Isaac 99c58f1c22SToby Isaac /* 100c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 101c58f1c22SToby Isaac 1025b5e7992SMatthew G. Knepley Not collective 1035b5e7992SMatthew G. Knepley 104c58f1c22SToby Isaac Input parameter: 105c58f1c22SToby Isaac . label - The DMLabel 106c58f1c22SToby Isaac 107c58f1c22SToby Isaac Output parameter: 108c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format 109c58f1c22SToby Isaac 110c58f1c22SToby Isaac Level: developer 111c58f1c22SToby Isaac 112db781477SPatrick Sanan .seealso: `DMLabelCreate()` 113c58f1c22SToby Isaac */ 114c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 115c58f1c22SToby Isaac { 116c58f1c22SToby Isaac PetscInt v; 117c58f1c22SToby Isaac 118c58f1c22SToby Isaac PetscFunctionBegin; 119c58f1c22SToby Isaac for (v = 0; v < label->numStrata; v++) { 1209566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 121c58f1c22SToby Isaac } 122c58f1c22SToby Isaac PetscFunctionReturn(0); 123c58f1c22SToby Isaac } 124c58f1c22SToby Isaac 125c58f1c22SToby Isaac /* 126c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 127c58f1c22SToby Isaac 1285b5e7992SMatthew G. Knepley Not collective 1295b5e7992SMatthew G. Knepley 130c58f1c22SToby Isaac Input parameter: 131c58f1c22SToby Isaac + label - The DMLabel 132c58f1c22SToby Isaac - v - The stratum value 133c58f1c22SToby Isaac 134c58f1c22SToby Isaac Output parameter: 135c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format 136c58f1c22SToby Isaac 137c58f1c22SToby Isaac Level: developer 138c58f1c22SToby Isaac 139db781477SPatrick Sanan .seealso: `DMLabelCreate()` 140c58f1c22SToby Isaac */ 141c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 142c58f1c22SToby Isaac { 143c58f1c22SToby Isaac PetscInt p; 144ad8374ffSToby Isaac const PetscInt *points; 145c58f1c22SToby Isaac 146b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) return 0; 147c58f1c22SToby Isaac PetscFunctionBegin; 1481dca8a05SBarry 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); 149ad8374ffSToby Isaac if (label->points[v]) { 1509566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 151e8f14785SLisandro Dalcin for (p = 0; p < label->stratumSizes[v]; ++p) { 1529566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 153e8f14785SLisandro Dalcin } 1549566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v],&points)); 1559566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 156ad8374ffSToby Isaac } 157ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 158c58f1c22SToby Isaac PetscFunctionReturn(0); 159c58f1c22SToby Isaac } 160c58f1c22SToby Isaac 161b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 162b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 163b9907514SLisandro Dalcin #endif 164b9907514SLisandro Dalcin 1659fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 1660c3c4a36SLisandro Dalcin { 1670c3c4a36SLisandro Dalcin PetscInt v; 1680e79e033SBarry Smith 1690c3c4a36SLisandro Dalcin PetscFunctionBegin; 1700e79e033SBarry Smith *index = -1; 171b9907514SLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 172b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 173b9907514SLisandro Dalcin if (label->stratumValues[v] == value) {*index = v; break;} 174b9907514SLisandro Dalcin } else { 1759566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, index)); 1760e79e033SBarry Smith } 17776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* Check strata hash map consistency */ 17890e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 1799566063dSJacob Faibussowitsch PetscCall(PetscHMapIGetSize(label->hmap, &len)); 18008401ef6SPierre Jolivet PetscCheck(len == label->numStrata,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 18190e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 1829566063dSJacob Faibussowitsch PetscCall(PetscHMapIGet(label->hmap, value, &loc)); 18390e9b2aeSLisandro Dalcin } else { 18490e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 18590e9b2aeSLisandro Dalcin if (label->stratumValues[v] == value) {loc = v; break;} 18690e9b2aeSLisandro Dalcin } 18708401ef6SPierre Jolivet PetscCheck(loc == *index,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 18890e9b2aeSLisandro Dalcin } 1890c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 1900c3c4a36SLisandro Dalcin } 1910c3c4a36SLisandro Dalcin 1929fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 193c58f1c22SToby Isaac { 194b9907514SLisandro Dalcin PetscInt v; 195b9907514SLisandro Dalcin PetscInt *tmpV; 196b9907514SLisandro Dalcin PetscInt *tmpS; 197b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 198b9907514SLisandro Dalcin IS *tmpP, is; 199c58f1c22SToby Isaac PetscBool *tmpB; 200b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 201c58f1c22SToby Isaac 202c58f1c22SToby Isaac PetscFunctionBegin; 203b9907514SLisandro Dalcin v = label->numStrata; 204b9907514SLisandro Dalcin tmpV = label->stratumValues; 205b9907514SLisandro Dalcin tmpS = label->stratumSizes; 206b9907514SLisandro Dalcin tmpH = label->ht; 207b9907514SLisandro Dalcin tmpP = label->points; 208b9907514SLisandro Dalcin tmpB = label->validIS; 2098e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2108e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2118e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2128e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2138e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2148e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2159566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v+1)*sizeof(*tmpV), &tmpV)); 2169566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v+1)*sizeof(*tmpS), &tmpS)); 2179566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v+1)*sizeof(*tmpH), &tmpH)); 2189566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v+1)*sizeof(*tmpP), &tmpP)); 2199566063dSJacob Faibussowitsch PetscCall(PetscMalloc((v+1)*sizeof(*tmpB), &tmpB)); 2209566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpV, oldV, v)); 2219566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpS, oldS, v)); 2229566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpH, oldH, v)); 2239566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpP, oldP, v)); 2249566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmpB, oldB, v)); 2259566063dSJacob Faibussowitsch PetscCall(PetscFree(oldV)); 2269566063dSJacob Faibussowitsch PetscCall(PetscFree(oldS)); 2279566063dSJacob Faibussowitsch PetscCall(PetscFree(oldH)); 2289566063dSJacob Faibussowitsch PetscCall(PetscFree(oldP)); 2299566063dSJacob Faibussowitsch PetscCall(PetscFree(oldB)); 2308e1f8cf0SLisandro Dalcin } 231b9907514SLisandro Dalcin label->numStrata = v+1; 232c58f1c22SToby Isaac label->stratumValues = tmpV; 233c58f1c22SToby Isaac label->stratumSizes = tmpS; 234c58f1c22SToby Isaac label->ht = tmpH; 235c58f1c22SToby Isaac label->points = tmpP; 236ad8374ffSToby Isaac label->validIS = tmpB; 2379566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&ht)); 2389566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF,0,0,1,&is)); 2399566063dSJacob Faibussowitsch PetscCall(PetscHMapISet(hmap, value, v)); 240b9907514SLisandro Dalcin tmpV[v] = value; 241b9907514SLisandro Dalcin tmpS[v] = 0; 242b9907514SLisandro Dalcin tmpH[v] = ht; 243b9907514SLisandro Dalcin tmpP[v] = is; 244b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 2459566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject) label)); 2460c3c4a36SLisandro Dalcin *index = v; 2470c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 2480c3c4a36SLisandro Dalcin } 2490c3c4a36SLisandro Dalcin 2509fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 251b9907514SLisandro Dalcin { 252b9907514SLisandro Dalcin PetscFunctionBegin; 2539566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, index)); 2549566063dSJacob Faibussowitsch if (*index < 0) PetscCall(DMLabelNewStratum(label, value, index)); 255b9907514SLisandro Dalcin PetscFunctionReturn(0); 256b9907514SLisandro Dalcin } 257b9907514SLisandro Dalcin 2589fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) 2599e63cc69SVaclav Hapla { 2609e63cc69SVaclav Hapla PetscFunctionBegin; 2619e63cc69SVaclav Hapla *size = 0; 2629e63cc69SVaclav Hapla if (v < 0) PetscFunctionReturn(0); 2639e63cc69SVaclav Hapla if (label->validIS[v]) { 2649e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 2659e63cc69SVaclav Hapla } else { 2669566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(label->ht[v], size)); 2679e63cc69SVaclav Hapla } 2689e63cc69SVaclav Hapla PetscFunctionReturn(0); 2699e63cc69SVaclav Hapla } 2709e63cc69SVaclav Hapla 271b9907514SLisandro Dalcin /*@ 272b9907514SLisandro Dalcin DMLabelAddStratum - Adds a new stratum value in a DMLabel 273b9907514SLisandro Dalcin 274d8d19677SJose E. Roman Input Parameters: 275b9907514SLisandro Dalcin + label - The DMLabel 276b9907514SLisandro Dalcin - value - The stratum value 277b9907514SLisandro Dalcin 278b9907514SLisandro Dalcin Level: beginner 279b9907514SLisandro Dalcin 280db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 281b9907514SLisandro Dalcin @*/ 2820c3c4a36SLisandro Dalcin PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 2830c3c4a36SLisandro Dalcin { 2840c3c4a36SLisandro Dalcin PetscInt v; 2850c3c4a36SLisandro Dalcin 2860c3c4a36SLisandro Dalcin PetscFunctionBegin; 287d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 2889566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 289b9907514SLisandro Dalcin PetscFunctionReturn(0); 290b9907514SLisandro Dalcin } 291b9907514SLisandro Dalcin 292b9907514SLisandro Dalcin /*@ 293b9907514SLisandro Dalcin DMLabelAddStrata - Adds new stratum values in a DMLabel 294b9907514SLisandro Dalcin 2955b5e7992SMatthew G. Knepley Not collective 2965b5e7992SMatthew G. Knepley 297d8d19677SJose E. Roman Input Parameters: 298b9907514SLisandro Dalcin + label - The DMLabel 299b9907514SLisandro Dalcin . numStrata - The number of stratum values 300b9907514SLisandro Dalcin - stratumValues - The stratum values 301b9907514SLisandro Dalcin 302b9907514SLisandro Dalcin Level: beginner 303b9907514SLisandro Dalcin 304db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 305b9907514SLisandro Dalcin @*/ 306b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 307b9907514SLisandro Dalcin { 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 { 347b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 3489566063dSJacob Faibussowitsch PetscCall(DMLabelAddStratum(label, values[v])); 349b9907514SLisandro Dalcin } 350b9907514SLisandro Dalcin } 3519566063dSJacob Faibussowitsch PetscCall(PetscFree(values)); 352b9907514SLisandro Dalcin PetscFunctionReturn(0); 353b9907514SLisandro Dalcin } 354b9907514SLisandro Dalcin 355b9907514SLisandro Dalcin /*@ 356b9907514SLisandro Dalcin DMLabelAddStrataIS - Adds new stratum values in a DMLabel 357b9907514SLisandro Dalcin 3585b5e7992SMatthew G. Knepley Not collective 3595b5e7992SMatthew G. Knepley 360d8d19677SJose E. Roman Input Parameters: 361b9907514SLisandro Dalcin + label - The DMLabel 362b9907514SLisandro Dalcin - valueIS - Index set with stratum values 363b9907514SLisandro Dalcin 364b9907514SLisandro Dalcin Level: beginner 365b9907514SLisandro Dalcin 366db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 367b9907514SLisandro Dalcin @*/ 368b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 369b9907514SLisandro Dalcin { 370b9907514SLisandro Dalcin PetscInt numStrata; 371b9907514SLisandro Dalcin const PetscInt *stratumValues; 372b9907514SLisandro Dalcin 373b9907514SLisandro Dalcin PetscFunctionBegin; 374b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 375b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 3769566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(valueIS, &numStrata)); 3779566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valueIS, &stratumValues)); 3789566063dSJacob Faibussowitsch PetscCall(DMLabelAddStrata(label, numStrata, stratumValues)); 379c58f1c22SToby Isaac PetscFunctionReturn(0); 380c58f1c22SToby Isaac } 381c58f1c22SToby Isaac 382c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) 383c58f1c22SToby Isaac { 384c58f1c22SToby Isaac PetscInt v; 385c58f1c22SToby Isaac PetscMPIInt rank; 386c58f1c22SToby Isaac 387c58f1c22SToby Isaac PetscFunctionBegin; 3889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 3899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 390c58f1c22SToby Isaac if (label) { 391d67d17b1SMatthew G. Knepley const char *name; 392d67d17b1SMatthew G. Knepley 3939566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &name)); 3949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name)); 39563a3b9bcSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", label->pStart, label->pEnd)); 396c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 397c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 398ad8374ffSToby Isaac const PetscInt *points; 399c58f1c22SToby Isaac PetscInt p; 400c58f1c22SToby Isaac 4019566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 402c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 40363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %" PetscInt_FMT " (%" PetscInt_FMT ")\n", rank, points[p], value)); 404c58f1c22SToby Isaac } 4059566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v],&points)); 406c58f1c22SToby Isaac } 407c58f1c22SToby Isaac } 4089566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 4099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 410c58f1c22SToby Isaac PetscFunctionReturn(0); 411c58f1c22SToby Isaac } 412c58f1c22SToby Isaac 413c58f1c22SToby Isaac /*@C 414c58f1c22SToby Isaac DMLabelView - View the label 415c58f1c22SToby Isaac 4165b5e7992SMatthew G. Knepley Collective on viewer 4175b5e7992SMatthew G. Knepley 418c58f1c22SToby Isaac Input Parameters: 419c58f1c22SToby Isaac + label - The DMLabel 420c58f1c22SToby Isaac - viewer - The PetscViewer 421c58f1c22SToby Isaac 422c58f1c22SToby Isaac Level: intermediate 423c58f1c22SToby Isaac 424db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 425c58f1c22SToby Isaac @*/ 426c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 427c58f1c22SToby Isaac { 428c58f1c22SToby Isaac PetscBool iascii; 429c58f1c22SToby Isaac 430c58f1c22SToby Isaac PetscFunctionBegin; 431d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 4329566063dSJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer)); 433c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 4349566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 4359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii)); 436*1baa6e33SBarry Smith if (iascii) PetscCall(DMLabelView_Ascii(label, viewer)); 437c58f1c22SToby Isaac PetscFunctionReturn(0); 438c58f1c22SToby Isaac } 439c58f1c22SToby Isaac 44084f0b6dfSMatthew G. Knepley /*@ 441d67d17b1SMatthew G. Knepley DMLabelReset - Destroys internal data structures in a DMLabel 442d67d17b1SMatthew G. Knepley 4435b5e7992SMatthew G. Knepley Not collective 4445b5e7992SMatthew G. Knepley 445d67d17b1SMatthew G. Knepley Input Parameter: 446d67d17b1SMatthew G. Knepley . label - The DMLabel 447d67d17b1SMatthew G. Knepley 448d67d17b1SMatthew G. Knepley Level: beginner 449d67d17b1SMatthew G. Knepley 450db781477SPatrick Sanan .seealso: `DMLabelDestroy()`, `DMLabelCreate()` 451d67d17b1SMatthew G. Knepley @*/ 452d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelReset(DMLabel label) 453d67d17b1SMatthew G. Knepley { 454d67d17b1SMatthew G. Knepley PetscInt v; 455d67d17b1SMatthew G. Knepley 456d67d17b1SMatthew G. Knepley PetscFunctionBegin; 457d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 458d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 4599566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&label->ht[v])); 4609566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 461d67d17b1SMatthew G. Knepley } 462b9907514SLisandro Dalcin label->numStrata = 0; 4639566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues)); 4649566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes)); 4659566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht)); 4669566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points)); 4679566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS)); 468f9244615SMatthew G. Knepley label->stratumValues = NULL; 469f9244615SMatthew G. Knepley label->stratumSizes = NULL; 470f9244615SMatthew G. Knepley label->ht = NULL; 471f9244615SMatthew G. Knepley label->points = NULL; 472f9244615SMatthew G. Knepley label->validIS = NULL; 4739566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 474b9907514SLisandro Dalcin label->pStart = -1; 475b9907514SLisandro Dalcin label->pEnd = -1; 4769566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 477d67d17b1SMatthew G. Knepley PetscFunctionReturn(0); 478d67d17b1SMatthew G. Knepley } 479d67d17b1SMatthew G. Knepley 480d67d17b1SMatthew G. Knepley /*@ 48184f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 48284f0b6dfSMatthew G. Knepley 4835b5e7992SMatthew G. Knepley Collective on label 4845b5e7992SMatthew G. Knepley 48584f0b6dfSMatthew G. Knepley Input Parameter: 48684f0b6dfSMatthew G. Knepley . label - The DMLabel 48784f0b6dfSMatthew G. Knepley 48884f0b6dfSMatthew G. Knepley Level: beginner 48984f0b6dfSMatthew G. Knepley 490db781477SPatrick Sanan .seealso: `DMLabelReset()`, `DMLabelCreate()` 49184f0b6dfSMatthew G. Knepley @*/ 492c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label) 493c58f1c22SToby Isaac { 494c58f1c22SToby Isaac PetscFunctionBegin; 495d67d17b1SMatthew G. Knepley if (!*label) PetscFunctionReturn(0); 496d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label),DMLABEL_CLASSID,1); 497b9907514SLisandro Dalcin if (--((PetscObject)(*label))->refct > 0) {*label = NULL; PetscFunctionReturn(0);} 4989566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 4999566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 5009566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 501c58f1c22SToby Isaac PetscFunctionReturn(0); 502c58f1c22SToby Isaac } 503c58f1c22SToby Isaac 50484f0b6dfSMatthew G. Knepley /*@ 50584f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 50684f0b6dfSMatthew G. Knepley 5075b5e7992SMatthew G. Knepley Collective on label 5085b5e7992SMatthew G. Knepley 50984f0b6dfSMatthew G. Knepley Input Parameter: 51084f0b6dfSMatthew G. Knepley . label - The DMLabel 51184f0b6dfSMatthew G. Knepley 51284f0b6dfSMatthew G. Knepley Output Parameter: 51384f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 51484f0b6dfSMatthew G. Knepley 51584f0b6dfSMatthew G. Knepley Level: intermediate 51684f0b6dfSMatthew G. Knepley 517db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelDestroy()` 51884f0b6dfSMatthew G. Knepley @*/ 519c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 520c58f1c22SToby Isaac { 521d67d17b1SMatthew G. Knepley const char *name; 522ad8374ffSToby Isaac PetscInt v; 523c58f1c22SToby Isaac 524c58f1c22SToby Isaac PetscFunctionBegin; 525d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 5269566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 5279566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &name)); 5289566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject) label), name, labelnew)); 529c58f1c22SToby Isaac 530c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5315aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 5329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 5339566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 5349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->ht)); 5359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->points)); 5369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 537c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 5389566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 539c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 540c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 5419566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) (label->points[v]))); 542ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 543b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 544c58f1c22SToby Isaac } 5459566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5469566063dSJacob Faibussowitsch PetscCall(PetscHMapIDuplicate(label->hmap,&(*labelnew)->hmap)); 547c58f1c22SToby Isaac (*labelnew)->pStart = -1; 548c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 549c58f1c22SToby Isaac (*labelnew)->bt = NULL; 550c58f1c22SToby Isaac PetscFunctionReturn(0); 551c58f1c22SToby Isaac } 552c58f1c22SToby Isaac 553609dae6eSVaclav Hapla /*@C 554609dae6eSVaclav Hapla DMLabelCompare - Compare two DMLabel objects 555609dae6eSVaclav Hapla 5565efe38ccSVaclav Hapla Collective on comm 557609dae6eSVaclav Hapla 558609dae6eSVaclav Hapla Input Parameters: 559f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 560f1a722f8SMatthew G. Knepley . l0 - First DMLabel 561609dae6eSVaclav Hapla - l1 - Second DMLabel 562609dae6eSVaclav Hapla 563609dae6eSVaclav Hapla Output Parameters 5645efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 5655efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 566609dae6eSVaclav Hapla 567609dae6eSVaclav Hapla Level: intermediate 568609dae6eSVaclav Hapla 569609dae6eSVaclav Hapla Notes: 5705efe38ccSVaclav Hapla The output flag equal is the same on all processes. 5715efe38ccSVaclav Hapla If it is passed as NULL and difference is found, an error is thrown on all processes. 5725efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 573609dae6eSVaclav Hapla 5745efe38ccSVaclav Hapla The output message is set independently on each rank. 5755efe38ccSVaclav Hapla It is set to NULL if no difference was found on the current rank. It must be freed by user. 5765efe38ccSVaclav Hapla If message is passed as NULL and difference is found, the difference description is printed to stderr in synchronized manner. 5775efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 578609dae6eSVaclav Hapla 579609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 580609dae6eSVaclav Hapla 5815efe38ccSVaclav Hapla The communicator needs to be specified because currently DMLabel can live on PETSC_COMM_SELF even if the underlying DM is parallel. 5825efe38ccSVaclav Hapla 583609dae6eSVaclav Hapla Fortran Notes: 584609dae6eSVaclav Hapla This function is currently not available from Fortran. 585609dae6eSVaclav Hapla 586db781477SPatrick Sanan .seealso: `DMCompareLabels()`, `DMLabelGetNumValues()`, `DMLabelGetDefaultValue()`, `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelGetStratumIS()` 587609dae6eSVaclav Hapla @*/ 5885efe38ccSVaclav Hapla PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 589609dae6eSVaclav Hapla { 590609dae6eSVaclav Hapla const char *name0, *name1; 591609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 5925efe38ccSVaclav Hapla PetscBool eq; 5935efe38ccSVaclav Hapla PetscMPIInt rank; 594609dae6eSVaclav Hapla 595609dae6eSVaclav Hapla PetscFunctionBegin; 5965efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 5975efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 5985efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal, 4); 5995efe38ccSVaclav Hapla if (message) PetscValidPointer(message, 5); 6009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6019566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6029566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 603609dae6eSVaclav Hapla { 604609dae6eSVaclav Hapla PetscInt v0, v1; 605609dae6eSVaclav Hapla 6069566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6079566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6085efe38ccSVaclav Hapla eq = (PetscBool) (v0 == v1); 6095efe38ccSVaclav Hapla if (!eq) { 61063a3b9bcSJacob Faibussowitsch 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)); 611609dae6eSVaclav Hapla } 6129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6135efe38ccSVaclav Hapla if (!eq) goto finish; 614609dae6eSVaclav Hapla } 615609dae6eSVaclav Hapla { 616609dae6eSVaclav Hapla IS is0, is1; 617609dae6eSVaclav Hapla 6189566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6199566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6209566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6219566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6229566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6235efe38ccSVaclav Hapla if (!eq) { 6249566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 625609dae6eSVaclav Hapla } 6269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6275efe38ccSVaclav Hapla if (!eq) goto finish; 628609dae6eSVaclav Hapla } 629609dae6eSVaclav Hapla { 630609dae6eSVaclav Hapla PetscInt i, nValues; 631609dae6eSVaclav Hapla 6329566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 633609dae6eSVaclav Hapla for (i=0; i<nValues; i++) { 634609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 635609dae6eSVaclav Hapla PetscInt n; 636609dae6eSVaclav Hapla IS is0, is1; 637609dae6eSVaclav Hapla 6389566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 639609dae6eSVaclav Hapla if (!n) continue; 6409566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6419566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6429566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6439566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6449566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6455efe38ccSVaclav Hapla if (!eq) { 64663a3b9bcSJacob 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)); 6475efe38ccSVaclav Hapla break; 648609dae6eSVaclav Hapla } 649609dae6eSVaclav Hapla } 6509566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 651609dae6eSVaclav Hapla } 652609dae6eSVaclav Hapla finish: 6535efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 654609dae6eSVaclav Hapla if (message) { 655609dae6eSVaclav Hapla *message = NULL; 656609dae6eSVaclav Hapla if (msg[0]) { 6579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(msg, message)); 658609dae6eSVaclav Hapla } 6595efe38ccSVaclav Hapla } else { 6605efe38ccSVaclav Hapla if (msg[0]) { 6619566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 662609dae6eSVaclav Hapla } 6639566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 6645efe38ccSVaclav Hapla } 6655efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 6665efe38ccSVaclav Hapla if (equal) *equal = eq; 66763a3b9bcSJacob Faibussowitsch else PetscCheck(eq,comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal",name0,name1); 668609dae6eSVaclav Hapla PetscFunctionReturn(0); 669609dae6eSVaclav Hapla } 670609dae6eSVaclav Hapla 671c6a43d28SMatthew G. Knepley /*@ 672c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 673c6a43d28SMatthew G. Knepley 6745b5e7992SMatthew G. Knepley Not collective 6755b5e7992SMatthew G. Knepley 676c6a43d28SMatthew G. Knepley Input Parameter: 677c6a43d28SMatthew G. Knepley . label - The DMLabel 678c6a43d28SMatthew G. Knepley 679c6a43d28SMatthew G. Knepley Level: intermediate 680c6a43d28SMatthew G. Knepley 681db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 682c6a43d28SMatthew G. Knepley @*/ 683c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelComputeIndex(DMLabel label) 684c6a43d28SMatthew G. Knepley { 685c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 686c6a43d28SMatthew G. Knepley 687c6a43d28SMatthew G. Knepley PetscFunctionBegin; 688c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 6899566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 690c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 691c6a43d28SMatthew G. Knepley const PetscInt *points; 692c6a43d28SMatthew G. Knepley PetscInt i; 693c6a43d28SMatthew G. Knepley 6949566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 695c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 696c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 697c6a43d28SMatthew G. Knepley 698c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 699c6a43d28SMatthew G. Knepley pEnd = PetscMax(point+1, pEnd); 700c6a43d28SMatthew G. Knepley } 7019566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 702c6a43d28SMatthew G. Knepley } 703c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 704c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7059566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 706c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 707c6a43d28SMatthew G. Knepley } 708c6a43d28SMatthew G. Knepley 709c6a43d28SMatthew G. Knepley /*@ 710c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 711c6a43d28SMatthew G. Knepley 7125b5e7992SMatthew G. Knepley Not collective 7135b5e7992SMatthew G. Knepley 714c6a43d28SMatthew G. Knepley Input Parameters: 715c6a43d28SMatthew G. Knepley + label - The DMLabel 716c6a43d28SMatthew G. Knepley . pStart - The smallest point 717c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 718c6a43d28SMatthew G. Knepley 719c6a43d28SMatthew G. Knepley Level: intermediate 720c6a43d28SMatthew G. Knepley 721db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelComputeIndex()`, `DMLabelDestroyIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 722c6a43d28SMatthew G. Knepley @*/ 723c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 724c58f1c22SToby Isaac { 725c58f1c22SToby Isaac PetscInt v; 726c58f1c22SToby Isaac 727c58f1c22SToby Isaac PetscFunctionBegin; 728d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7299566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7309566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 731c58f1c22SToby Isaac label->pStart = pStart; 732c58f1c22SToby Isaac label->pEnd = pEnd; 733c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7349566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 735c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 736ad8374ffSToby Isaac const PetscInt *points; 737c58f1c22SToby Isaac PetscInt i; 738c58f1c22SToby Isaac 7399566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 740c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 741ad8374ffSToby Isaac const PetscInt point = points[i]; 742c58f1c22SToby Isaac 74363a3b9bcSJacob 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); 7449566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 745c58f1c22SToby Isaac } 7469566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 747c58f1c22SToby Isaac } 748c58f1c22SToby Isaac PetscFunctionReturn(0); 749c58f1c22SToby Isaac } 750c58f1c22SToby Isaac 751c6a43d28SMatthew G. Knepley /*@ 752c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 753c6a43d28SMatthew G. Knepley 7545b5e7992SMatthew G. Knepley Not collective 7555b5e7992SMatthew G. Knepley 756c6a43d28SMatthew G. Knepley Input Parameter: 757c6a43d28SMatthew G. Knepley . label - the DMLabel 758c6a43d28SMatthew G. Knepley 759c6a43d28SMatthew G. Knepley Level: intermediate 760c6a43d28SMatthew G. Knepley 761db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 762c6a43d28SMatthew G. Knepley @*/ 763c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label) 764c58f1c22SToby Isaac { 765c58f1c22SToby Isaac PetscFunctionBegin; 766d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 767c58f1c22SToby Isaac label->pStart = -1; 768c58f1c22SToby Isaac label->pEnd = -1; 7699566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 770c58f1c22SToby Isaac PetscFunctionReturn(0); 771c58f1c22SToby Isaac } 772c58f1c22SToby Isaac 773c58f1c22SToby Isaac /*@ 774c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 775c6a43d28SMatthew G. Knepley 7765b5e7992SMatthew G. Knepley Not collective 7775b5e7992SMatthew G. Knepley 778c6a43d28SMatthew G. Knepley Input Parameter: 779c6a43d28SMatthew G. Knepley . label - the DMLabel 780c6a43d28SMatthew G. Knepley 781c6a43d28SMatthew G. Knepley Output Parameters: 782c6a43d28SMatthew G. Knepley + pStart - The smallest point 783c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 784c6a43d28SMatthew G. Knepley 785c6a43d28SMatthew G. Knepley Note: This will compute an index for the label if one does not exist. 786c6a43d28SMatthew G. Knepley 787c6a43d28SMatthew G. Knepley Level: intermediate 788c6a43d28SMatthew G. Knepley 789db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 790c6a43d28SMatthew G. Knepley @*/ 791c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 792c6a43d28SMatthew G. Knepley { 793c6a43d28SMatthew G. Knepley PetscFunctionBegin; 794c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7959566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 796c6a43d28SMatthew G. Knepley if (pStart) { 797534a8f05SLisandro Dalcin PetscValidIntPointer(pStart, 2); 798c6a43d28SMatthew G. Knepley *pStart = label->pStart; 799c6a43d28SMatthew G. Knepley } 800c6a43d28SMatthew G. Knepley if (pEnd) { 801534a8f05SLisandro Dalcin PetscValidIntPointer(pEnd, 3); 802c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 803c6a43d28SMatthew G. Knepley } 804c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 805c6a43d28SMatthew G. Knepley } 806c6a43d28SMatthew G. Knepley 807c6a43d28SMatthew G. Knepley /*@ 808c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 809c58f1c22SToby Isaac 8105b5e7992SMatthew G. Knepley Not collective 8115b5e7992SMatthew G. Knepley 812c58f1c22SToby Isaac Input Parameters: 813c58f1c22SToby Isaac + label - the DMLabel 814c58f1c22SToby Isaac - value - the value 815c58f1c22SToby Isaac 816c58f1c22SToby Isaac Output Parameter: 817c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 818c58f1c22SToby Isaac 819c58f1c22SToby Isaac Level: developer 820c58f1c22SToby Isaac 821db781477SPatrick Sanan .seealso: `DMLabelHasPoint()`, `DMLabelGetValue()`, `DMLabelSetValue()` 822c58f1c22SToby Isaac @*/ 823c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 824c58f1c22SToby Isaac { 825c58f1c22SToby Isaac PetscInt v; 826c58f1c22SToby Isaac 827c58f1c22SToby Isaac PetscFunctionBegin; 828d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 829534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8309566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8310c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 832c58f1c22SToby Isaac PetscFunctionReturn(0); 833c58f1c22SToby Isaac } 834c58f1c22SToby Isaac 835c58f1c22SToby Isaac /*@ 836c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 837c58f1c22SToby Isaac 8385b5e7992SMatthew G. Knepley Not collective 8395b5e7992SMatthew G. Knepley 840c58f1c22SToby Isaac Input Parameters: 841c58f1c22SToby Isaac + label - the DMLabel 842c58f1c22SToby Isaac - point - the point 843c58f1c22SToby Isaac 844c58f1c22SToby Isaac Output Parameter: 845c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 846c58f1c22SToby Isaac 847c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 848c58f1c22SToby Isaac 849c58f1c22SToby Isaac Level: developer 850c58f1c22SToby Isaac 851db781477SPatrick Sanan .seealso: `DMLabelCreateIndex()`, `DMLabelGetValue()`, `DMLabelSetValue()` 852c58f1c22SToby Isaac @*/ 853c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 854c58f1c22SToby Isaac { 855c58f1c22SToby Isaac PetscFunctionBeginHot; 856d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 857534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8589566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 85976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 86028b400f6SJacob Faibussowitsch PetscCheck(label->bt,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 86163a3b9bcSJacob 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); 86276bd3646SJed Brown } 863c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 864c58f1c22SToby Isaac PetscFunctionReturn(0); 865c58f1c22SToby Isaac } 866c58f1c22SToby Isaac 867c58f1c22SToby Isaac /*@ 868c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 869c58f1c22SToby Isaac 8705b5e7992SMatthew G. Knepley Not collective 8715b5e7992SMatthew G. Knepley 872c58f1c22SToby Isaac Input Parameters: 873c58f1c22SToby Isaac + label - the DMLabel 874c58f1c22SToby Isaac . value - the stratum value 875c58f1c22SToby Isaac - point - the point 876c58f1c22SToby Isaac 877c58f1c22SToby Isaac Output Parameter: 878c58f1c22SToby Isaac . contains - true if the stratum contains the point 879c58f1c22SToby Isaac 880c58f1c22SToby Isaac Level: intermediate 881c58f1c22SToby Isaac 882db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()` 883c58f1c22SToby Isaac @*/ 884c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 885c58f1c22SToby Isaac { 886c58f1c22SToby Isaac PetscInt v; 887c58f1c22SToby Isaac 8880c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 889d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 890534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 4); 891c58f1c22SToby Isaac *contains = PETSC_FALSE; 8929566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8930c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 8940c3c4a36SLisandro Dalcin 895ad8374ffSToby Isaac if (label->validIS[v]) { 896c58f1c22SToby Isaac PetscInt i; 897c58f1c22SToby Isaac 8989566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 8990c3c4a36SLisandro Dalcin if (i >= 0) *contains = PETSC_TRUE; 900c58f1c22SToby Isaac } else { 901c58f1c22SToby Isaac PetscBool has; 902c58f1c22SToby Isaac 9039566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 9040c3c4a36SLisandro Dalcin if (has) *contains = PETSC_TRUE; 905c58f1c22SToby Isaac } 906c58f1c22SToby Isaac PetscFunctionReturn(0); 907c58f1c22SToby Isaac } 908c58f1c22SToby Isaac 90984f0b6dfSMatthew G. Knepley /*@ 9105aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9115aa44df4SToby Isaac When a label is created, it is initialized to -1. 9125aa44df4SToby Isaac 9135b5e7992SMatthew G. Knepley Not collective 9145b5e7992SMatthew G. Knepley 9155aa44df4SToby Isaac Input parameter: 9165aa44df4SToby Isaac . label - a DMLabel object 9175aa44df4SToby Isaac 9185aa44df4SToby Isaac Output parameter: 9195aa44df4SToby Isaac . defaultValue - the default value 9205aa44df4SToby Isaac 9215aa44df4SToby Isaac Level: beginner 9225aa44df4SToby Isaac 923db781477SPatrick Sanan .seealso: `DMLabelSetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 92484f0b6dfSMatthew G. Knepley @*/ 9255aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 9265aa44df4SToby Isaac { 9275aa44df4SToby Isaac PetscFunctionBegin; 928d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9295aa44df4SToby Isaac *defaultValue = label->defaultValue; 9305aa44df4SToby Isaac PetscFunctionReturn(0); 9315aa44df4SToby Isaac } 9325aa44df4SToby Isaac 93384f0b6dfSMatthew G. Knepley /*@ 9345aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9355aa44df4SToby Isaac When a label is created, it is initialized to -1. 9365aa44df4SToby Isaac 9375b5e7992SMatthew G. Knepley Not collective 9385b5e7992SMatthew G. Knepley 9395aa44df4SToby Isaac Input parameter: 9405aa44df4SToby Isaac . label - a DMLabel object 9415aa44df4SToby Isaac 9425aa44df4SToby Isaac Output parameter: 9435aa44df4SToby Isaac . defaultValue - the default value 9445aa44df4SToby Isaac 9455aa44df4SToby Isaac Level: beginner 9465aa44df4SToby Isaac 947db781477SPatrick Sanan .seealso: `DMLabelGetDefaultValue()`, `DMLabelGetValue()`, `DMLabelSetValue()` 94884f0b6dfSMatthew G. Knepley @*/ 9495aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 9505aa44df4SToby Isaac { 9515aa44df4SToby Isaac PetscFunctionBegin; 952d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9535aa44df4SToby Isaac label->defaultValue = defaultValue; 9545aa44df4SToby Isaac PetscFunctionReturn(0); 9555aa44df4SToby Isaac } 9565aa44df4SToby Isaac 957c58f1c22SToby Isaac /*@ 9585aa44df4SToby 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()) 959c58f1c22SToby Isaac 9605b5e7992SMatthew G. Knepley Not collective 9615b5e7992SMatthew G. Knepley 962c58f1c22SToby Isaac Input Parameters: 963c58f1c22SToby Isaac + label - the DMLabel 964c58f1c22SToby Isaac - point - the point 965c58f1c22SToby Isaac 966c58f1c22SToby Isaac Output Parameter: 9678e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 968c58f1c22SToby Isaac 969c58f1c22SToby Isaac Level: intermediate 970c58f1c22SToby Isaac 971db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 972c58f1c22SToby Isaac @*/ 973c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 974c58f1c22SToby Isaac { 975c58f1c22SToby Isaac PetscInt v; 976c58f1c22SToby Isaac 9770c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 978d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 979dadcf809SJacob Faibussowitsch PetscValidIntPointer(value, 3); 9805aa44df4SToby Isaac *value = label->defaultValue; 981c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 982ad8374ffSToby Isaac if (label->validIS[v]) { 983c58f1c22SToby Isaac PetscInt i; 984c58f1c22SToby Isaac 9859566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 986c58f1c22SToby Isaac if (i >= 0) { 987c58f1c22SToby Isaac *value = label->stratumValues[v]; 988c58f1c22SToby Isaac break; 989c58f1c22SToby Isaac } 990c58f1c22SToby Isaac } else { 991c58f1c22SToby Isaac PetscBool has; 992c58f1c22SToby Isaac 9939566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 994c58f1c22SToby Isaac if (has) { 995c58f1c22SToby Isaac *value = label->stratumValues[v]; 996c58f1c22SToby Isaac break; 997c58f1c22SToby Isaac } 998c58f1c22SToby Isaac } 999c58f1c22SToby Isaac } 1000c58f1c22SToby Isaac PetscFunctionReturn(0); 1001c58f1c22SToby Isaac } 1002c58f1c22SToby Isaac 1003c58f1c22SToby Isaac /*@ 1004367003a6SStefano 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. 1005c58f1c22SToby Isaac 10065b5e7992SMatthew G. Knepley Not collective 10075b5e7992SMatthew G. Knepley 1008c58f1c22SToby Isaac Input Parameters: 1009c58f1c22SToby Isaac + label - the DMLabel 1010c58f1c22SToby Isaac . point - the point 1011c58f1c22SToby Isaac - value - The point value 1012c58f1c22SToby Isaac 1013c58f1c22SToby Isaac Level: intermediate 1014c58f1c22SToby Isaac 1015db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelClearValue()`, `DMLabelGetDefaultValue()`, `DMLabelSetDefaultValue()` 1016c58f1c22SToby Isaac @*/ 1017c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1018c58f1c22SToby Isaac { 1019c58f1c22SToby Isaac PetscInt v; 1020c58f1c22SToby Isaac 1021c58f1c22SToby Isaac PetscFunctionBegin; 1022d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10230c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10245aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 10259566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1026c58f1c22SToby Isaac /* Set key */ 10279566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10289566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 1029c58f1c22SToby Isaac PetscFunctionReturn(0); 1030c58f1c22SToby Isaac } 1031c58f1c22SToby Isaac 1032c58f1c22SToby Isaac /*@ 1033c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1034c58f1c22SToby Isaac 10355b5e7992SMatthew G. Knepley Not collective 10365b5e7992SMatthew G. Knepley 1037c58f1c22SToby Isaac Input Parameters: 1038c58f1c22SToby Isaac + label - the DMLabel 1039c58f1c22SToby Isaac . point - the point 1040c58f1c22SToby Isaac - value - The point value 1041c58f1c22SToby Isaac 1042c58f1c22SToby Isaac Level: intermediate 1043c58f1c22SToby Isaac 1044db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()` 1045c58f1c22SToby Isaac @*/ 1046c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1047c58f1c22SToby Isaac { 1048ad8374ffSToby Isaac PetscInt v; 1049c58f1c22SToby Isaac 1050c58f1c22SToby Isaac PetscFunctionBegin; 1051d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1052c58f1c22SToby Isaac /* Find label value */ 10539566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 10540c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 10550c3c4a36SLisandro Dalcin 1056eeed21e7SToby Isaac if (label->bt) { 105763a3b9bcSJacob 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); 10589566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1059eeed21e7SToby Isaac } 10600c3c4a36SLisandro Dalcin 10610c3c4a36SLisandro Dalcin /* Delete key */ 10629566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10639566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 1064c58f1c22SToby Isaac PetscFunctionReturn(0); 1065c58f1c22SToby Isaac } 1066c58f1c22SToby Isaac 1067c58f1c22SToby Isaac /*@ 1068c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 1069c58f1c22SToby Isaac 10705b5e7992SMatthew G. Knepley Not collective 10715b5e7992SMatthew G. Knepley 1072c58f1c22SToby Isaac Input Parameters: 1073c58f1c22SToby Isaac + label - the DMLabel 1074c58f1c22SToby Isaac . is - the point IS 1075c58f1c22SToby Isaac - value - The point value 1076c58f1c22SToby Isaac 1077c58f1c22SToby Isaac Level: intermediate 1078c58f1c22SToby Isaac 1079db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1080c58f1c22SToby Isaac @*/ 1081c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1082c58f1c22SToby Isaac { 10830c3c4a36SLisandro Dalcin PetscInt v, n, p; 1084c58f1c22SToby Isaac const PetscInt *points; 1085c58f1c22SToby Isaac 1086c58f1c22SToby Isaac PetscFunctionBegin; 1087d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1088c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 10890c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10900c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 10919566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 10920c3c4a36SLisandro Dalcin /* Set keys */ 10939566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10949566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 10959566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 10969566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 10979566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 1098c58f1c22SToby Isaac PetscFunctionReturn(0); 1099c58f1c22SToby Isaac } 1100c58f1c22SToby Isaac 110184f0b6dfSMatthew G. Knepley /*@ 110284f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 110384f0b6dfSMatthew G. Knepley 11045b5e7992SMatthew G. Knepley Not collective 11055b5e7992SMatthew G. Knepley 110684f0b6dfSMatthew G. Knepley Input Parameter: 110784f0b6dfSMatthew G. Knepley . label - the DMLabel 110884f0b6dfSMatthew G. Knepley 110901d2d390SJose E. Roman Output Parameter: 111084f0b6dfSMatthew G. Knepley . numValues - the number of values 111184f0b6dfSMatthew G. Knepley 111284f0b6dfSMatthew G. Knepley Level: intermediate 111384f0b6dfSMatthew G. Knepley 1114db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 111584f0b6dfSMatthew G. Knepley @*/ 1116c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1117c58f1c22SToby Isaac { 1118c58f1c22SToby Isaac PetscFunctionBegin; 1119d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1120dadcf809SJacob Faibussowitsch PetscValidIntPointer(numValues, 2); 1121c58f1c22SToby Isaac *numValues = label->numStrata; 1122c58f1c22SToby Isaac PetscFunctionReturn(0); 1123c58f1c22SToby Isaac } 1124c58f1c22SToby Isaac 112584f0b6dfSMatthew G. Knepley /*@ 112684f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 112784f0b6dfSMatthew G. Knepley 11285b5e7992SMatthew G. Knepley Not collective 11295b5e7992SMatthew G. Knepley 113084f0b6dfSMatthew G. Knepley Input Parameter: 113184f0b6dfSMatthew G. Knepley . label - the DMLabel 113284f0b6dfSMatthew G. Knepley 113301d2d390SJose E. Roman Output Parameter: 113484f0b6dfSMatthew G. Knepley . is - the value IS 113584f0b6dfSMatthew G. Knepley 113684f0b6dfSMatthew G. Knepley Level: intermediate 113784f0b6dfSMatthew G. Knepley 11381d04cbbeSVaclav Hapla Notes: 11391d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11401d04cbbeSVaclav Hapla Strata which are allocated but empty [DMLabelGetStratumSize() yields 0] are counted. 11411d04cbbeSVaclav Hapla If you need to count only nonempty strata, use DMLabelGetNonEmptyStratumValuesIS(). 11421d04cbbeSVaclav Hapla 1143db781477SPatrick Sanan .seealso: `DMLabelGetNonEmptyStratumValuesIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 114484f0b6dfSMatthew G. Knepley @*/ 1145c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1146c58f1c22SToby Isaac { 1147c58f1c22SToby Isaac PetscFunctionBegin; 1148d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1149c58f1c22SToby Isaac PetscValidPointer(values, 2); 11509566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 1151c58f1c22SToby Isaac PetscFunctionReturn(0); 1152c58f1c22SToby Isaac } 1153c58f1c22SToby Isaac 115484f0b6dfSMatthew G. Knepley /*@ 11551d04cbbeSVaclav Hapla DMLabelGetNonEmptyStratumValuesIS - Get an IS of all values that the DMlabel takes 11561d04cbbeSVaclav Hapla 11571d04cbbeSVaclav Hapla Not collective 11581d04cbbeSVaclav Hapla 11591d04cbbeSVaclav Hapla Input Parameter: 11601d04cbbeSVaclav Hapla . label - the DMLabel 11611d04cbbeSVaclav Hapla 11621d04cbbeSVaclav Hapla Output Paramater: 11631d04cbbeSVaclav Hapla . is - the value IS 11641d04cbbeSVaclav Hapla 11651d04cbbeSVaclav Hapla Level: intermediate 11661d04cbbeSVaclav Hapla 11671d04cbbeSVaclav Hapla Notes: 11681d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11691d04cbbeSVaclav Hapla This is similar to DMLabelGetValueIS() but counts only nonempty strata. 11701d04cbbeSVaclav Hapla 1171db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 11721d04cbbeSVaclav Hapla @*/ 11731d04cbbeSVaclav Hapla PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 11741d04cbbeSVaclav Hapla { 11751d04cbbeSVaclav Hapla PetscInt i, j; 11761d04cbbeSVaclav Hapla PetscInt *valuesArr; 11771d04cbbeSVaclav Hapla 11781d04cbbeSVaclav Hapla PetscFunctionBegin; 11791d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11801d04cbbeSVaclav Hapla PetscValidPointer(values, 2); 11819566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 11821d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 11831d04cbbeSVaclav Hapla PetscInt n; 11841d04cbbeSVaclav Hapla 11859566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 11861d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 11871d04cbbeSVaclav Hapla } 11881d04cbbeSVaclav Hapla if (j == label->numStrata) { 11899566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 11901d04cbbeSVaclav Hapla } else { 11919566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 11921d04cbbeSVaclav Hapla } 11939566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 11941d04cbbeSVaclav Hapla PetscFunctionReturn(0); 11951d04cbbeSVaclav Hapla } 11961d04cbbeSVaclav Hapla 11971d04cbbeSVaclav Hapla /*@ 1198d123abd9SMatthew 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 1199d123abd9SMatthew G. Knepley 1200d123abd9SMatthew G. Knepley Not collective 1201d123abd9SMatthew G. Knepley 1202d123abd9SMatthew G. Knepley Input Parameters: 1203d123abd9SMatthew G. Knepley + label - the DMLabel 120497bb3fdcSJose E. Roman - value - the value 1205d123abd9SMatthew G. Knepley 120601d2d390SJose E. Roman Output Parameter: 1207d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1208d123abd9SMatthew G. Knepley 1209d123abd9SMatthew G. Knepley Level: intermediate 1210d123abd9SMatthew G. Knepley 1211db781477SPatrick Sanan .seealso: `DMLabelGetValueIS()`, `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 1212d123abd9SMatthew G. Knepley @*/ 1213d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1214d123abd9SMatthew G. Knepley { 1215d123abd9SMatthew G. Knepley PetscInt v; 1216d123abd9SMatthew G. Knepley 1217d123abd9SMatthew G. Knepley PetscFunctionBegin; 1218d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1219dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 3); 1220d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 1221d123abd9SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) if (label->stratumValues[v] == value) break; 1222d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1223d123abd9SMatthew G. Knepley else *index = v; 1224d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1225d123abd9SMatthew G. Knepley } 1226d123abd9SMatthew G. Knepley 1227d123abd9SMatthew G. Knepley /*@ 122884f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 122984f0b6dfSMatthew G. Knepley 12305b5e7992SMatthew G. Knepley Not collective 12315b5e7992SMatthew G. Knepley 123284f0b6dfSMatthew G. Knepley Input Parameters: 123384f0b6dfSMatthew G. Knepley + label - the DMLabel 123484f0b6dfSMatthew G. Knepley - value - the stratum value 123584f0b6dfSMatthew G. Knepley 123601d2d390SJose E. Roman Output Parameter: 123784f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 123884f0b6dfSMatthew G. Knepley 123984f0b6dfSMatthew G. Knepley Level: intermediate 124084f0b6dfSMatthew G. Knepley 1241db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 124284f0b6dfSMatthew G. Knepley @*/ 1243fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1244fada774cSMatthew G. Knepley { 1245fada774cSMatthew G. Knepley PetscInt v; 1246fada774cSMatthew G. Knepley 1247fada774cSMatthew G. Knepley PetscFunctionBegin; 1248d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1249dadcf809SJacob Faibussowitsch PetscValidBoolPointer(exists, 3); 12509566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12510c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 1252fada774cSMatthew G. Knepley PetscFunctionReturn(0); 1253fada774cSMatthew G. Knepley } 1254fada774cSMatthew G. Knepley 125584f0b6dfSMatthew G. Knepley /*@ 125684f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 125784f0b6dfSMatthew G. Knepley 12585b5e7992SMatthew G. Knepley Not collective 12595b5e7992SMatthew G. Knepley 126084f0b6dfSMatthew G. Knepley Input Parameters: 126184f0b6dfSMatthew G. Knepley + label - the DMLabel 126284f0b6dfSMatthew G. Knepley - value - the stratum value 126384f0b6dfSMatthew G. Knepley 126401d2d390SJose E. Roman Output Parameter: 126584f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 126684f0b6dfSMatthew G. Knepley 126784f0b6dfSMatthew G. Knepley Level: intermediate 126884f0b6dfSMatthew G. Knepley 1269db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 127084f0b6dfSMatthew G. Knepley @*/ 1271c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1272c58f1c22SToby Isaac { 1273c58f1c22SToby Isaac PetscInt v; 1274c58f1c22SToby Isaac 1275c58f1c22SToby Isaac PetscFunctionBegin; 1276d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1277dadcf809SJacob Faibussowitsch PetscValidIntPointer(size, 3); 12789566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12799566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 1280c58f1c22SToby Isaac PetscFunctionReturn(0); 1281c58f1c22SToby Isaac } 1282c58f1c22SToby Isaac 128384f0b6dfSMatthew G. Knepley /*@ 128484f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 128584f0b6dfSMatthew G. Knepley 12865b5e7992SMatthew G. Knepley Not collective 12875b5e7992SMatthew G. Knepley 128884f0b6dfSMatthew G. Knepley Input Parameters: 128984f0b6dfSMatthew G. Knepley + label - the DMLabel 129084f0b6dfSMatthew G. Knepley - value - the stratum value 129184f0b6dfSMatthew G. Knepley 129201d2d390SJose E. Roman Output Parameters: 129384f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 129484f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 129584f0b6dfSMatthew G. Knepley 129684f0b6dfSMatthew G. Knepley Level: intermediate 129784f0b6dfSMatthew G. Knepley 1298db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 129984f0b6dfSMatthew G. Knepley @*/ 1300c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1301c58f1c22SToby Isaac { 13020c3c4a36SLisandro Dalcin PetscInt v, min, max; 1303c58f1c22SToby Isaac 1304c58f1c22SToby Isaac PetscFunctionBegin; 1305d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1306dadcf809SJacob Faibussowitsch if (start) {PetscValidIntPointer(start, 3); *start = -1;} 1307dadcf809SJacob Faibussowitsch if (end) {PetscValidIntPointer(end, 4); *end = -1;} 13089566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13090c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13109566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13110c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 13129566063dSJacob Faibussowitsch PetscCall(ISGetMinMax(label->points[v], &min, &max)); 1313d6cb179aSToby Isaac if (start) *start = min; 1314d6cb179aSToby Isaac if (end) *end = max+1; 1315c58f1c22SToby Isaac PetscFunctionReturn(0); 1316c58f1c22SToby Isaac } 1317c58f1c22SToby Isaac 131884f0b6dfSMatthew G. Knepley /*@ 131984f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 132084f0b6dfSMatthew G. Knepley 13215b5e7992SMatthew G. Knepley Not collective 13225b5e7992SMatthew G. Knepley 132384f0b6dfSMatthew G. Knepley Input Parameters: 132484f0b6dfSMatthew G. Knepley + label - the DMLabel 132584f0b6dfSMatthew G. Knepley - value - the stratum value 132684f0b6dfSMatthew G. Knepley 132701d2d390SJose E. Roman Output Parameter: 132884f0b6dfSMatthew G. Knepley . points - The stratum points 132984f0b6dfSMatthew G. Knepley 133084f0b6dfSMatthew G. Knepley Level: intermediate 133184f0b6dfSMatthew G. Knepley 1332593ce467SVaclav Hapla Notes: 1333593ce467SVaclav Hapla The output IS should be destroyed when no longer needed. 1334593ce467SVaclav Hapla Returns NULL if the stratum is empty. 1335593ce467SVaclav Hapla 1336db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 133784f0b6dfSMatthew G. Knepley @*/ 1338c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1339c58f1c22SToby Isaac { 1340c58f1c22SToby Isaac PetscInt v; 1341c58f1c22SToby Isaac 1342c58f1c22SToby Isaac PetscFunctionBegin; 1343d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1344c58f1c22SToby Isaac PetscValidPointer(points, 3); 1345c58f1c22SToby Isaac *points = NULL; 13469566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13470c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13489566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label->points[v])); 1350ad8374ffSToby Isaac *points = label->points[v]; 1351c58f1c22SToby Isaac PetscFunctionReturn(0); 1352c58f1c22SToby Isaac } 1353c58f1c22SToby Isaac 135484f0b6dfSMatthew G. Knepley /*@ 135584f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 135684f0b6dfSMatthew G. Knepley 13575b5e7992SMatthew G. Knepley Not collective 13585b5e7992SMatthew G. Knepley 135984f0b6dfSMatthew G. Knepley Input Parameters: 136084f0b6dfSMatthew G. Knepley + label - the DMLabel 136184f0b6dfSMatthew G. Knepley . value - the stratum value 136284f0b6dfSMatthew G. Knepley - points - The stratum points 136384f0b6dfSMatthew G. Knepley 136484f0b6dfSMatthew G. Knepley Level: intermediate 136584f0b6dfSMatthew G. Knepley 1366db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 136784f0b6dfSMatthew G. Knepley @*/ 13684de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 13694de306b1SToby Isaac { 13700c3c4a36SLisandro Dalcin PetscInt v; 13714de306b1SToby Isaac 13724de306b1SToby Isaac PetscFunctionBegin; 1373d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1374d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 13759566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 13764de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 13779566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 13789566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &(label->stratumSizes[v]))); 13799566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 13809566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 13810c3c4a36SLisandro Dalcin label->points[v] = is; 13820c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 13839566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject) label)); 13844de306b1SToby Isaac if (label->bt) { 13854de306b1SToby Isaac const PetscInt *points; 13864de306b1SToby Isaac PetscInt p; 13874de306b1SToby Isaac 13889566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is,&points)); 13894de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 13904de306b1SToby Isaac const PetscInt point = points[p]; 13914de306b1SToby Isaac 139263a3b9bcSJacob 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); 13939566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 13944de306b1SToby Isaac } 13954de306b1SToby Isaac } 13964de306b1SToby Isaac PetscFunctionReturn(0); 13974de306b1SToby Isaac } 13984de306b1SToby Isaac 139984f0b6dfSMatthew G. Knepley /*@ 140084f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 14014de306b1SToby Isaac 14025b5e7992SMatthew G. Knepley Not collective 14035b5e7992SMatthew G. Knepley 140484f0b6dfSMatthew G. Knepley Input Parameters: 140584f0b6dfSMatthew G. Knepley + label - the DMLabel 140684f0b6dfSMatthew G. Knepley - value - the stratum value 140784f0b6dfSMatthew G. Knepley 140884f0b6dfSMatthew G. Knepley Level: intermediate 140984f0b6dfSMatthew G. Knepley 1410db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 141184f0b6dfSMatthew G. Knepley @*/ 1412c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1413c58f1c22SToby Isaac { 1414c58f1c22SToby Isaac PetscInt v; 1415c58f1c22SToby Isaac 1416c58f1c22SToby Isaac PetscFunctionBegin; 1417d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14189566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14190c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 14204de306b1SToby Isaac if (label->validIS[v]) { 14214de306b1SToby Isaac if (label->bt) { 1422c58f1c22SToby Isaac PetscInt i; 1423ad8374ffSToby Isaac const PetscInt *points; 1424c58f1c22SToby Isaac 14259566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1426c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1427ad8374ffSToby Isaac const PetscInt point = points[i]; 1428c58f1c22SToby Isaac 142963a3b9bcSJacob 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); 14309566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1431c58f1c22SToby Isaac } 14329566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1433c58f1c22SToby Isaac } 1434c58f1c22SToby Isaac label->stratumSizes[v] = 0; 14359566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 14369566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 14379566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) label->points[v], "indices")); 14389566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject) label)); 1439c58f1c22SToby Isaac } else { 14409566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1441c58f1c22SToby Isaac } 1442c58f1c22SToby Isaac PetscFunctionReturn(0); 1443c58f1c22SToby Isaac } 1444c58f1c22SToby Isaac 144584f0b6dfSMatthew G. Knepley /*@ 1446412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1447412e9a14SMatthew G. Knepley 1448412e9a14SMatthew G. Knepley Not collective 1449412e9a14SMatthew G. Knepley 1450412e9a14SMatthew G. Knepley Input Parameters: 1451412e9a14SMatthew G. Knepley + label - The DMLabel 1452412e9a14SMatthew G. Knepley . value - The label value for all points 1453412e9a14SMatthew G. Knepley . pStart - The first point 1454412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1455412e9a14SMatthew G. Knepley 1456412e9a14SMatthew G. Knepley Note: The marks points are [pStart, pEnd), and only the bounds are stored. 1457412e9a14SMatthew G. Knepley 1458412e9a14SMatthew G. Knepley Level: intermediate 1459412e9a14SMatthew G. Knepley 1460db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelSetStratumIS()`, `DMLabelGetStratumIS()` 1461412e9a14SMatthew G. Knepley @*/ 1462412e9a14SMatthew G. Knepley PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1463412e9a14SMatthew G. Knepley { 1464412e9a14SMatthew G. Knepley IS pIS; 1465412e9a14SMatthew G. Knepley 1466412e9a14SMatthew G. Knepley PetscFunctionBegin; 14679566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 14689566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 14699566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 1470412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1471412e9a14SMatthew G. Knepley } 1472412e9a14SMatthew G. Knepley 1473412e9a14SMatthew G. Knepley /*@ 1474d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1475d123abd9SMatthew G. Knepley 1476d123abd9SMatthew G. Knepley Not collective 1477d123abd9SMatthew G. Knepley 1478d123abd9SMatthew G. Knepley Input Parameters: 1479d123abd9SMatthew G. Knepley + label - The DMLabel 1480d123abd9SMatthew G. Knepley . value - The label value 1481d123abd9SMatthew G. Knepley - p - A point with this value 1482d123abd9SMatthew G. Knepley 1483d123abd9SMatthew G. Knepley Output Parameter: 1484d123abd9SMatthew 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 1485d123abd9SMatthew G. Knepley 1486d123abd9SMatthew G. Knepley Level: intermediate 1487d123abd9SMatthew G. Knepley 1488db781477SPatrick Sanan .seealso: `DMLabelGetValueIndex()`, `DMLabelGetStratumIS()`, `DMLabelCreate()` 1489d123abd9SMatthew G. Knepley @*/ 1490d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1491d123abd9SMatthew G. Knepley { 1492d123abd9SMatthew G. Knepley const PetscInt *indices; 1493d123abd9SMatthew G. Knepley PetscInt v; 1494d123abd9SMatthew G. Knepley 1495d123abd9SMatthew G. Knepley PetscFunctionBegin; 1496d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1497dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 4); 1498d123abd9SMatthew G. Knepley *index = -1; 14999566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 1500d123abd9SMatthew G. Knepley if (v < 0) PetscFunctionReturn(0); 15019566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 15029566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &indices)); 15039566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 15049566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &indices)); 1505d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1506d123abd9SMatthew G. Knepley } 1507d123abd9SMatthew G. Knepley 1508d123abd9SMatthew G. Knepley /*@ 150984f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 151084f0b6dfSMatthew G. Knepley 15115b5e7992SMatthew G. Knepley Not collective 15125b5e7992SMatthew G. Knepley 151384f0b6dfSMatthew G. Knepley Input Parameters: 151484f0b6dfSMatthew G. Knepley + label - the DMLabel 151522cd2cdaSVaclav Hapla . start - the first point kept 151622cd2cdaSVaclav Hapla - end - one more than the last point kept 151784f0b6dfSMatthew G. Knepley 151884f0b6dfSMatthew G. Knepley Level: intermediate 151984f0b6dfSMatthew G. Knepley 1520db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 152184f0b6dfSMatthew G. Knepley @*/ 1522c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1523c58f1c22SToby Isaac { 1524c58f1c22SToby Isaac PetscInt v; 1525c58f1c22SToby Isaac 1526c58f1c22SToby Isaac PetscFunctionBegin; 1527d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15289566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 15299566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1530c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 15319566063dSJacob Faibussowitsch PetscCall(ISGeneralFilter(label->points[v], start, end)); 1532c58f1c22SToby Isaac } 15339566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 1534c58f1c22SToby Isaac PetscFunctionReturn(0); 1535c58f1c22SToby Isaac } 1536c58f1c22SToby Isaac 153784f0b6dfSMatthew G. Knepley /*@ 153884f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 153984f0b6dfSMatthew G. Knepley 15405b5e7992SMatthew G. Knepley Not collective 15415b5e7992SMatthew G. Knepley 154284f0b6dfSMatthew G. Knepley Input Parameters: 154384f0b6dfSMatthew G. Knepley + label - the DMLabel 154484f0b6dfSMatthew G. Knepley - permutation - the point permutation 154584f0b6dfSMatthew G. Knepley 154684f0b6dfSMatthew G. Knepley Output Parameter: 154784f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 154884f0b6dfSMatthew G. Knepley 154984f0b6dfSMatthew G. Knepley Level: intermediate 155084f0b6dfSMatthew G. Knepley 1551db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 155284f0b6dfSMatthew G. Knepley @*/ 1553c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1554c58f1c22SToby Isaac { 1555c58f1c22SToby Isaac const PetscInt *perm; 1556c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1557c58f1c22SToby Isaac 1558c58f1c22SToby Isaac PetscFunctionBegin; 1559d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1560d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 15619566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 15629566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 15639566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 15649566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 15659566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1566c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1567c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1568ad8374ffSToby Isaac const PetscInt *points; 1569ad8374ffSToby Isaac PetscInt *pointsNew; 1570c58f1c22SToby Isaac 15719566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v],&points)); 15729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&pointsNew)); 1573c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1574ad8374ffSToby Isaac const PetscInt point = points[q]; 1575c58f1c22SToby Isaac 157663a3b9bcSJacob 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); 1577ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1578c58f1c22SToby Isaac } 15799566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v],&points)); 15809566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 15819566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1582fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 15839566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]))); 15849566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1585fa8e8ae5SToby Isaac } else { 15869566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]))); 1587fa8e8ae5SToby Isaac } 15889566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices")); 1589c58f1c22SToby Isaac } 15909566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1591c58f1c22SToby Isaac if (label->bt) { 15929566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 15939566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1594c58f1c22SToby Isaac } 1595c58f1c22SToby Isaac PetscFunctionReturn(0); 1596c58f1c22SToby Isaac } 1597c58f1c22SToby Isaac 159826c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 159926c55118SMichael Lange { 160026c55118SMichael Lange MPI_Comm comm; 1601eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 160226c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 160326c55118SMichael Lange PetscSection rootSection; 160426c55118SMichael Lange PetscSF labelSF; 160526c55118SMichael Lange 160626c55118SMichael Lange PetscFunctionBegin; 16079566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 16089566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 160926c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 161026c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 16119566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 16129566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 16139566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 161426c55118SMichael Lange if (label) { 161526c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1616ad8374ffSToby Isaac const PetscInt *points; 1617ad8374ffSToby Isaac 16189566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 161926c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1620eb30be1eSVaclav Hapla PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 162126c55118SMichael Lange } 16229566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 162326c55118SMichael Lange } 162426c55118SMichael Lange } 16259566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 162626c55118SMichael Lange /* Create a point-wise array of stratum values */ 16279566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 16289566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 16299566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 163026c55118SMichael Lange if (label) { 163126c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1632ad8374ffSToby Isaac const PetscInt *points; 1633ad8374ffSToby Isaac 16349566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 163526c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1636ad8374ffSToby Isaac const PetscInt p = points[l]; 16379566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 163826c55118SMichael Lange rootStrata[offset+rootIdx[p]++] = label->stratumValues[s]; 163926c55118SMichael Lange } 16409566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 164126c55118SMichael Lange } 164226c55118SMichael Lange } 164326c55118SMichael Lange /* Build SF that maps label points to remote processes */ 16449566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 16459566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 16469566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 16479566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 164826c55118SMichael Lange /* Send the strata for each point over the derived SF */ 16499566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 16509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 16519566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE)); 16529566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE)); 165326c55118SMichael Lange /* Clean up */ 16549566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 16559566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 16569566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 16579566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 165826c55118SMichael Lange PetscFunctionReturn(0); 165926c55118SMichael Lange } 166026c55118SMichael Lange 166184f0b6dfSMatthew G. Knepley /*@ 166284f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 166384f0b6dfSMatthew G. Knepley 16645b5e7992SMatthew G. Knepley Collective on sf 16655b5e7992SMatthew G. Knepley 166684f0b6dfSMatthew G. Knepley Input Parameters: 166784f0b6dfSMatthew G. Knepley + label - the DMLabel 166884f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 166984f0b6dfSMatthew G. Knepley 167084f0b6dfSMatthew G. Knepley Output Parameter: 167184f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 167284f0b6dfSMatthew G. Knepley 167384f0b6dfSMatthew G. Knepley Level: intermediate 167484f0b6dfSMatthew G. Knepley 1675db781477SPatrick Sanan .seealso: `DMLabelCreate()`, `DMLabelGetValue()`, `DMLabelSetValue()`, `DMLabelClearValue()` 167684f0b6dfSMatthew G. Knepley @*/ 1677c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1678c58f1c22SToby Isaac { 1679c58f1c22SToby Isaac MPI_Comm comm; 168026c55118SMichael Lange PetscSection leafSection; 168126c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 168226c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1683ad8374ffSToby Isaac PetscInt **points; 1684d67d17b1SMatthew G. Knepley const char *lname = NULL; 1685c58f1c22SToby Isaac char *name; 1686c58f1c22SToby Isaac PetscInt nameSize; 1687e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1688c58f1c22SToby Isaac size_t len = 0; 168926c55118SMichael Lange PetscMPIInt rank; 1690c58f1c22SToby Isaac 1691c58f1c22SToby Isaac PetscFunctionBegin; 1692d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1693f018e600SMatthew G. Knepley if (label) { 1694f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16959566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1696f018e600SMatthew G. Knepley } 16979566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 16989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1699c58f1c22SToby Isaac /* Bcast name */ 1700dd400576SPatrick Sanan if (rank == 0) { 17019566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &lname)); 17029566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1703d67d17b1SMatthew G. Knepley } 1704c58f1c22SToby Isaac nameSize = len; 17059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 17069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize+1, &name)); 17079566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize+1)); 17089566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm)); 17099566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 17109566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 171177d236dfSMichael Lange /* Bcast defaultValue */ 1712dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 17139566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 171426c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 17159566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 17165cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 17179566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 17189566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 17199566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 17209566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 17219566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1722ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 17239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 17245cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 17255cbdf6fcSMichael Lange offset = 0; 17269566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 17279566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues)); 172890e9b2aeSLisandro Dalcin for (s = 0; s < (*labelNew)->numStrata; ++s) { 17299566063dSJacob Faibussowitsch PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 173090e9b2aeSLisandro Dalcin } 17315cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1732231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 1733231b9e6fSMatthew G. Knepley if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;} 17345cbdf6fcSMichael Lange } 17355cbdf6fcSMichael Lange } 1736c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 17379566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes)); 17389566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1739c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 17409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17419566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1742c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1743c58f1c22SToby Isaac (*labelNew)->stratumSizes[leafStrata[offset+s]]++; 1744c58f1c22SToby Isaac } 1745c58f1c22SToby Isaac } 17469566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht)); 17479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points)); 17489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata,&points)); 1749c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 17509566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 17519566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]))); 1752c58f1c22SToby Isaac } 1753c58f1c22SToby Isaac /* Insert points into new strata */ 17549566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 17559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1756c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 17579566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17589566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1759c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1760c58f1c22SToby Isaac stratum = leafStrata[offset+s]; 1761ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1762c58f1c22SToby Isaac } 1763c58f1c22SToby Isaac } 1764ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 17659566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]))); 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices")); 1767ad8374ffSToby Isaac } 17689566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 17699566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 17709566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 17719566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 17729566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 1773c58f1c22SToby Isaac PetscFunctionReturn(0); 1774c58f1c22SToby Isaac } 1775c58f1c22SToby Isaac 17767937d9ceSMichael Lange /*@ 17777937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 17787937d9ceSMichael Lange 17795b5e7992SMatthew G. Knepley Collective on sf 17805b5e7992SMatthew G. Knepley 17817937d9ceSMichael Lange Input Parameters: 17827937d9ceSMichael Lange + label - the DMLabel 178384f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 17847937d9ceSMichael Lange 178584f0b6dfSMatthew G. Knepley Output Parameters: 178684f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 17877937d9ceSMichael Lange 17887937d9ceSMichael Lange Level: developer 17897937d9ceSMichael Lange 17907937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 17917937d9ceSMichael Lange 1792db781477SPatrick Sanan .seealso: `DMLabelDistribute()` 17937937d9ceSMichael Lange @*/ 17947937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 17957937d9ceSMichael Lange { 17967937d9ceSMichael Lange MPI_Comm comm; 17977937d9ceSMichael Lange PetscSection rootSection; 17987937d9ceSMichael Lange PetscSF sfLabel; 17997937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 18007937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 18017937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 18027937d9ceSMichael Lange PetscInt *rootStrata; 1803d67d17b1SMatthew G. Knepley const char *lname; 18047937d9ceSMichael Lange char *name; 18057937d9ceSMichael Lange PetscInt nameSize; 18067937d9ceSMichael Lange size_t len = 0; 18079852e123SBarry Smith PetscMPIInt rank, size; 18087937d9ceSMichael Lange 18097937d9ceSMichael Lange PetscFunctionBegin; 1810d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1811d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 18129566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 18139566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 18149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 18157937d9ceSMichael Lange /* Bcast name */ 1816dd400576SPatrick Sanan if (rank == 0) { 18179566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &lname)); 18189566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1819d67d17b1SMatthew G. Knepley } 18207937d9ceSMichael Lange nameSize = len; 18219566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 18229566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize+1, &name)); 18239566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize+1)); 18249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm)); 18259566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 18269566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 18277937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 18287937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 18297937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 18309566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 18319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1832dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 18337937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 18348212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 18358212dd46SStefano Zampini 18368212dd46SStefano Zampini leafPoints[ilp].index = ilp; 18378212dd46SStefano Zampini leafPoints[ilp].rank = rank; 18387937d9ceSMichael Lange } 18399566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 18409566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 18417937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 18429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 18439566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 18449566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 18459566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm,& sfLabel)); 18469566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 18477937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 18489566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 18497937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 18507937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 18517937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 18529566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx+d, &dof)); 18539566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx+d, &offset)); 18549566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset+s])); 18557937d9ceSMichael Lange } 18567937d9ceSMichael Lange idx += rootDegree[p]; 18577937d9ceSMichael Lange } 18589566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 18599566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 18609566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 18619566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 18627937d9ceSMichael Lange PetscFunctionReturn(0); 18637937d9ceSMichael Lange } 18647937d9ceSMichael Lange 1865d42890abSMatthew G. Knepley static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1866d42890abSMatthew G. Knepley { 1867d42890abSMatthew G. Knepley const PetscInt *degree; 1868d42890abSMatthew G. Knepley const PetscInt *points; 1869d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1870d42890abSMatthew G. Knepley 1871d42890abSMatthew G. Knepley PetscFunctionBegin; 1872d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1873d42890abSMatthew G. Knepley /* Add in leaves */ 1874d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1875d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1876d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 1877d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 1878d42890abSMatthew G. Knepley } 1879d42890abSMatthew G. Knepley /* Add in shared roots */ 1880d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1881d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1882d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1883d42890abSMatthew G. Knepley if (degree[r]) { 1884d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1885d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 1886d42890abSMatthew G. Knepley } 1887d42890abSMatthew G. Knepley } 1888d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1889d42890abSMatthew G. Knepley } 1890d42890abSMatthew G. Knepley 1891d42890abSMatthew G. Knepley static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 1892d42890abSMatthew G. Knepley { 1893d42890abSMatthew G. Knepley const PetscInt *degree; 1894d42890abSMatthew G. Knepley const PetscInt *points; 1895d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1896d42890abSMatthew G. Knepley 1897d42890abSMatthew G. Knepley PetscFunctionBegin; 1898d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1899d42890abSMatthew G. Knepley /* Read out leaves */ 1900d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1901d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1902d42890abSMatthew G. Knepley const PetscInt p = points[l]; 1903d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 1904d42890abSMatthew G. Knepley 1905d42890abSMatthew G. Knepley if (cval != defVal) { 1906d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 1907d42890abSMatthew G. Knepley if (val == defVal) { 1908d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 1909d42890abSMatthew G. Knepley if (markPoint) {PetscCall((*markPoint)(label, p, cval, ctx));} 1910d42890abSMatthew G. Knepley } 1911d42890abSMatthew G. Knepley } 1912d42890abSMatthew G. Knepley } 1913d42890abSMatthew G. Knepley /* Read out shared roots */ 1914d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1915d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1916d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1917d42890abSMatthew G. Knepley if (degree[r]) { 1918d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 1919d42890abSMatthew G. Knepley 1920d42890abSMatthew G. Knepley if (cval != defVal) { 1921d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1922d42890abSMatthew G. Knepley if (val == defVal) { 1923d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 1924d42890abSMatthew G. Knepley if (markPoint) {PetscCall((*markPoint)(label, r, cval, ctx));} 1925d42890abSMatthew G. Knepley } 1926d42890abSMatthew G. Knepley } 1927d42890abSMatthew G. Knepley } 1928d42890abSMatthew G. Knepley } 1929d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1930d42890abSMatthew G. Knepley } 1931d42890abSMatthew G. Knepley 1932d42890abSMatthew G. Knepley /*@ 1933d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 1934d42890abSMatthew G. Knepley 1935d42890abSMatthew G. Knepley Collective on sf 1936d42890abSMatthew G. Knepley 1937d42890abSMatthew G. Knepley Input Parameters: 1938d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1939d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1940d42890abSMatthew G. Knepley 1941d42890abSMatthew G. Knepley Level: intermediate 1942d42890abSMatthew G. Knepley 1943db781477SPatrick Sanan .seealso: `DMLabelPropagateEnd()`, `DMLabelPropagatePush()` 1944d42890abSMatthew G. Knepley @*/ 1945d42890abSMatthew G. Knepley PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 1946d42890abSMatthew G. Knepley { 1947d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 1948d42890abSMatthew G. Knepley PetscMPIInt size; 1949d42890abSMatthew G. Knepley 1950d42890abSMatthew G. Knepley PetscFunctionBegin; 1951d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) sf), &size)); 1952d42890abSMatthew G. Knepley if (size > 1) { 1953d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1954d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 1955d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 1956d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 1957d42890abSMatthew G. Knepley } 1958d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1959d42890abSMatthew G. Knepley } 1960d42890abSMatthew G. Knepley 1961d42890abSMatthew G. Knepley /*@ 1962d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 1963d42890abSMatthew G. Knepley 1964d42890abSMatthew G. Knepley Collective on sf 1965d42890abSMatthew G. Knepley 1966d42890abSMatthew G. Knepley Input Parameters: 1967d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1968d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1969d42890abSMatthew G. Knepley 1970d42890abSMatthew G. Knepley Level: intermediate 1971d42890abSMatthew G. Knepley 1972db781477SPatrick Sanan .seealso: `DMLabelPropagateBegin()`, `DMLabelPropagatePush()` 1973d42890abSMatthew G. Knepley @*/ 1974d42890abSMatthew G. Knepley PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 1975d42890abSMatthew G. Knepley { 1976d42890abSMatthew G. Knepley PetscFunctionBegin; 1977d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 1978d42890abSMatthew G. Knepley label->propArray = NULL; 1979d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1980d42890abSMatthew G. Knepley } 1981d42890abSMatthew G. Knepley 1982d42890abSMatthew G. Knepley /*@C 1983d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 1984d42890abSMatthew G. Knepley 1985d42890abSMatthew G. Knepley Collective on sf 1986d42890abSMatthew G. Knepley 1987d42890abSMatthew G. Knepley Input Parameters: 1988d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1989d42890abSMatthew G. Knepley . sf - The SF describing parallel layout of the label points 1990d42890abSMatthew G. Knepley . markPoint - An optional user callback that is called when a point is marked, or NULL 1991d42890abSMatthew G. Knepley - ctx - An optional user context for the callback, or NULL 1992d42890abSMatthew G. Knepley 1993d42890abSMatthew G. Knepley Calling sequence of markPoint: 1994d42890abSMatthew G. Knepley $ markPoint(DMLabel label, PetscInt p, PetscInt val, void *ctx); 1995d42890abSMatthew G. Knepley 1996d42890abSMatthew G. Knepley + label - The DMLabel 1997d42890abSMatthew G. Knepley . p - The point being marked 1998d42890abSMatthew G. Knepley . val - The label value for p 1999d42890abSMatthew G. Knepley - ctx - An optional user context 2000d42890abSMatthew G. Knepley 2001d42890abSMatthew G. Knepley Level: intermediate 2002d42890abSMatthew G. Knepley 2003db781477SPatrick Sanan .seealso: `DMLabelPropagateBegin()`, `DMLabelPropagateEnd()` 2004d42890abSMatthew G. Knepley @*/ 2005d42890abSMatthew G. Knepley PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 2006d42890abSMatthew G. Knepley { 2007c50b2d26SMatthew G. Knepley PetscInt *valArray = label->propArray, Nr; 2008d42890abSMatthew G. Knepley PetscMPIInt size; 2009d42890abSMatthew G. Knepley 2010d42890abSMatthew G. Knepley PetscFunctionBegin; 2011d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) pointSF), &size)); 2012c50b2d26SMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, NULL, NULL, NULL)); 2013c50b2d26SMatthew G. Knepley if (size > 1 && Nr >= 0) { 2014d42890abSMatthew G. Knepley /* Communicate marked edges 2015d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2016d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2017d42890abSMatthew G. Knepley 2018d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2019d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2020d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2021d42890abSMatthew G. Knepley 2022d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2023d42890abSMatthew 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 2024d42890abSMatthew G. Knepley edge to the queue. 2025d42890abSMatthew G. Knepley */ 2026d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2027d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2028d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2029d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray,MPI_REPLACE)); 2030d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray,MPI_REPLACE)); 2031d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2032d42890abSMatthew G. Knepley } 2033d42890abSMatthew G. Knepley PetscFunctionReturn(0); 2034d42890abSMatthew G. Knepley } 2035d42890abSMatthew G. Knepley 203684f0b6dfSMatthew G. Knepley /*@ 203784f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 203884f0b6dfSMatthew G. Knepley 20395b5e7992SMatthew G. Knepley Not collective 20405b5e7992SMatthew G. Knepley 204184f0b6dfSMatthew G. Knepley Input Parameter: 204284f0b6dfSMatthew G. Knepley . label - the DMLabel 204384f0b6dfSMatthew G. Knepley 204484f0b6dfSMatthew G. Knepley Output Parameters: 204584f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 204684f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 204784f0b6dfSMatthew G. Knepley 204884f0b6dfSMatthew G. Knepley Level: developer 204984f0b6dfSMatthew G. Knepley 2050db781477SPatrick Sanan .seealso: `DMLabelDistribute()` 205184f0b6dfSMatthew G. Knepley @*/ 2052c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2053c58f1c22SToby Isaac { 2054c58f1c22SToby Isaac IS vIS; 2055c58f1c22SToby Isaac const PetscInt *values; 2056c58f1c22SToby Isaac PetscInt *points; 2057c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2058c58f1c22SToby Isaac 2059c58f1c22SToby Isaac PetscFunctionBegin; 2060d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 20619566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 20629566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 20639566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 2064c58f1c22SToby Isaac if (nV) {vS = values[0]; vE = values[0]+1;} 2065c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2066c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2067c58f1c22SToby Isaac vE = PetscMax(vE, values[v]+1); 2068c58f1c22SToby Isaac } 20699566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 20709566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2071c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2072c58f1c22SToby Isaac PetscInt n; 2073c58f1c22SToby Isaac 20749566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 20759566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2076c58f1c22SToby Isaac } 20779566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 20789566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 20799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2080c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2081c58f1c22SToby Isaac IS is; 2082c58f1c22SToby Isaac const PetscInt *spoints; 2083c58f1c22SToby Isaac PetscInt dof, off, p; 2084c58f1c22SToby Isaac 20859566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 20869566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 20879566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 20889566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2089c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; 20909566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 20919566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2092c58f1c22SToby Isaac } 20939566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 20949566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 20959566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 2096c58f1c22SToby Isaac PetscFunctionReturn(0); 2097c58f1c22SToby Isaac } 2098c58f1c22SToby Isaac 209984f0b6dfSMatthew G. Knepley /*@ 2100c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 2101c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 2102c58f1c22SToby Isaac 21035b5e7992SMatthew G. Knepley Collective on sf 21045b5e7992SMatthew G. Knepley 2105c58f1c22SToby Isaac Input Parameters: 2106c58f1c22SToby Isaac + s - The PetscSection for the local field layout 2107c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 2108c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 2109c58f1c22SToby Isaac . label - The label specifying the points 2110c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2111c58f1c22SToby Isaac 2112c58f1c22SToby Isaac Output Parameter: 2113c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 2114c58f1c22SToby Isaac 2115c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 2116c58f1c22SToby Isaac 2117c58f1c22SToby Isaac Level: developer 2118c58f1c22SToby Isaac 2119db781477SPatrick Sanan .seealso: `PetscSectionCreate()` 2120c58f1c22SToby Isaac @*/ 2121c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2122c58f1c22SToby Isaac { 2123c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2124c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2125c58f1c22SToby Isaac 2126c58f1c22SToby Isaac PetscFunctionBegin; 2127d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2128d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2129d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 21309566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection)); 21319566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 21329566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 21339566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2134c58f1c22SToby Isaac if (nroots >= 0) { 213563a3b9bcSJacob Faibussowitsch PetscCheck(nroots >= pEnd-pStart,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %" PetscInt_FMT " < %" PetscInt_FMT " section size", nroots, pEnd-pStart); 21369566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2137c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 21389566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2139c58f1c22SToby Isaac } else { 2140c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2141c58f1c22SToby Isaac } 2142c58f1c22SToby Isaac } 2143c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2144c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2145c58f1c22SToby Isaac PetscInt value; 2146c58f1c22SToby Isaac 21479566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2148c58f1c22SToby Isaac if (value != labelValue) continue; 21499566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 21509566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 21519566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 21529566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2153c58f1c22SToby Isaac if (neg) neg[p] = -(dof+1); 2154c58f1c22SToby Isaac } 21559566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2156c58f1c22SToby Isaac if (nroots >= 0) { 21579566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 21589566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 2159c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 2160c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 2161c58f1c22SToby Isaac } 2162c58f1c22SToby Isaac } 2163c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 2164c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 2165c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2166c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2167c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 2168c58f1c22SToby Isaac } 21699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s))); 2170c58f1c22SToby Isaac globalOff -= off; 2171c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 2172c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2173c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 2174c58f1c22SToby Isaac } 2175c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2176c58f1c22SToby Isaac if (nroots >= 0) { 21779566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 21789566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 2179c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 2180c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 2181c58f1c22SToby Isaac } 2182c58f1c22SToby Isaac } 21839566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd-pStart) PetscCall(PetscFree(tmpOff)); 21849566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 2185c58f1c22SToby Isaac PetscFunctionReturn(0); 2186c58f1c22SToby Isaac } 2187c58f1c22SToby Isaac 21885fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label 21895fdea053SToby Isaac { 21905fdea053SToby Isaac DMLabel label; 21915fdea053SToby Isaac PetscCopyMode *modes; 21925fdea053SToby Isaac PetscInt *sizes; 21935fdea053SToby Isaac const PetscInt ***perms; 21945fdea053SToby Isaac const PetscScalar ***rots; 21955fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 21965fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 21975fdea053SToby Isaac } PetscSectionSym_Label; 21985fdea053SToby Isaac 21995fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 22005fdea053SToby Isaac { 22015fdea053SToby Isaac PetscInt i, j; 22025fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 22035fdea053SToby Isaac 22045fdea053SToby Isaac PetscFunctionBegin; 22055fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22065fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 22075fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 22089566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 22099566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 22105fdea053SToby Isaac } 22115fdea053SToby Isaac if (sl->perms[i]) { 22125fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 22135fdea053SToby Isaac 22149566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 22155fdea053SToby Isaac } 22165fdea053SToby Isaac if (sl->rots[i]) { 22175fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 22185fdea053SToby Isaac 22199566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 22205fdea053SToby Isaac } 22215fdea053SToby Isaac } 22225fdea053SToby Isaac } 22239566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients)); 22249566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 22255fdea053SToby Isaac sl->numStrata = 0; 22265fdea053SToby Isaac PetscFunctionReturn(0); 22275fdea053SToby Isaac } 22285fdea053SToby Isaac 22295fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 22305fdea053SToby Isaac { 22315fdea053SToby Isaac PetscFunctionBegin; 22329566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 22339566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 22345fdea053SToby Isaac PetscFunctionReturn(0); 22355fdea053SToby Isaac } 22365fdea053SToby Isaac 22375fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 22385fdea053SToby Isaac { 22395fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 22405fdea053SToby Isaac PetscBool isAscii; 22415fdea053SToby Isaac DMLabel label = sl->label; 2242d67d17b1SMatthew G. Knepley const char *name; 22435fdea053SToby Isaac 22445fdea053SToby Isaac PetscFunctionBegin; 22459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii)); 22465fdea053SToby Isaac if (isAscii) { 22475fdea053SToby Isaac PetscInt i, j, k; 22485fdea053SToby Isaac PetscViewerFormat format; 22495fdea053SToby Isaac 22509566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 22515fdea053SToby Isaac if (label) { 22529566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 22535fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22559566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 22569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22575fdea053SToby Isaac } else { 22589566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sl->label, &name)); 22599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Label '%s'\n",name)); 22605fdea053SToby Isaac } 22615fdea053SToby Isaac } else { 22629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 22635fdea053SToby Isaac } 22649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22655fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22665fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 22675fdea053SToby Isaac 22685fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 226963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point): no symmetries\n", value, sl->sizes[i])); 22705fdea053SToby Isaac } else { 227163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %" PetscInt_FMT " (%" PetscInt_FMT " dofs per point):\n", value, sl->sizes[i])); 22729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 227363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%" PetscInt_FMT ", %" PetscInt_FMT ")\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 22745fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22765fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 22775fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 227863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ": identity\n",j)); 22795fdea053SToby Isaac } else { 22805fdea053SToby Isaac PetscInt tab; 22815fdea053SToby Isaac 228263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %" PetscInt_FMT ":\n",j)); 22839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer,&tab)); 22855fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 22869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Permutation:")); 22879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,0)); 228863a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT,sl->perms[i][j][k])); 22899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 22909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,tab)); 22915fdea053SToby Isaac } 22925fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 22939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Rotations: ")); 22949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,0)); 22955fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 229663a3b9bcSJacob 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]))); 22975fdea053SToby Isaac #else 229863a3b9bcSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer," %+g",(double)sl->rots[i][j][k])); 22995fdea053SToby Isaac #endif 23009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 23019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,tab)); 23025fdea053SToby Isaac } 23039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23045fdea053SToby Isaac } 23055fdea053SToby Isaac } 23069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23075fdea053SToby Isaac } 23089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23095fdea053SToby Isaac } 23105fdea053SToby Isaac } 23119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23125fdea053SToby Isaac } 23135fdea053SToby Isaac PetscFunctionReturn(0); 23145fdea053SToby Isaac } 23155fdea053SToby Isaac 23165fdea053SToby Isaac /*@ 23175fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 23185fdea053SToby Isaac 23195fdea053SToby Isaac Logically collective on sym 23205fdea053SToby Isaac 23215fdea053SToby Isaac Input parameters: 23225fdea053SToby Isaac + sym - the section symmetries 23235fdea053SToby Isaac - label - the DMLabel describing the types of points 23245fdea053SToby Isaac 23255fdea053SToby Isaac Level: developer: 23265fdea053SToby Isaac 2327db781477SPatrick Sanan .seealso: `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreateLabel()`, `PetscSectionGetPointSyms()` 23285fdea053SToby Isaac @*/ 23295fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 23305fdea053SToby Isaac { 23315fdea053SToby Isaac PetscSectionSym_Label *sl; 23325fdea053SToby Isaac 23335fdea053SToby Isaac PetscFunctionBegin; 23345fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 23355fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 23369566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 23375fdea053SToby Isaac if (label) { 23385fdea053SToby Isaac sl->label = label; 23399566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label)); 23409566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label,&sl->numStrata)); 23419566063dSJacob 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)); 23429566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode))); 23439566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt))); 23449566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **))); 23459566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **))); 23469566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]))); 23475fdea053SToby Isaac } 23485fdea053SToby Isaac PetscFunctionReturn(0); 23495fdea053SToby Isaac } 23505fdea053SToby Isaac 23515fdea053SToby Isaac /*@C 2352b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2353b004864fSMatthew G. Knepley 2354b004864fSMatthew G. Knepley Logically collective on sym 2355b004864fSMatthew G. Knepley 2356b004864fSMatthew G. Knepley Input Parameters: 2357b004864fSMatthew G. Knepley + sym - the section symmetries 2358b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2359b004864fSMatthew G. Knepley 2360b004864fSMatthew G. Knepley Output Parameters: 2361b004864fSMatthew G. Knepley + size - the number of dofs for points in the stratum of the label 2362b004864fSMatthew G. Knepley . minOrient - the smallest orientation for a point in this stratum 2363b004864fSMatthew G. Knepley . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 2364b004864fSMatthew G. Knepley . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2365b004864fSMatthew 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 2366b004864fSMatthew G. Knepley 2367b004864fSMatthew G. Knepley Level: developer 2368b004864fSMatthew G. Knepley 2369db781477SPatrick Sanan .seealso: `PetscSectionSymLabelSetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 2370b004864fSMatthew G. Knepley @*/ 2371b004864fSMatthew G. Knepley PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2372b004864fSMatthew G. Knepley { 2373b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2374b004864fSMatthew G. Knepley const char *name; 2375b004864fSMatthew G. Knepley PetscInt i; 2376b004864fSMatthew G. Knepley 2377b004864fSMatthew G. Knepley PetscFunctionBegin; 2378b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 2379b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *) sym->data; 2380b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2381b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2382b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2383b004864fSMatthew G. Knepley 2384b004864fSMatthew G. Knepley if (stratum == value) break; 2385b004864fSMatthew G. Knepley } 23869566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sl->label, &name)); 2387b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 2388b004864fSMatthew G. Knepley if (size) {PetscValidIntPointer(size, 3); *size = sl->sizes[i];} 2389b004864fSMatthew G. Knepley if (minOrient) {PetscValidIntPointer(minOrient, 4); *minOrient = sl->minMaxOrients[i][0];} 2390b004864fSMatthew G. Knepley if (maxOrient) {PetscValidIntPointer(maxOrient, 5); *maxOrient = sl->minMaxOrients[i][1];} 2391b004864fSMatthew G. Knepley if (perms) {PetscValidPointer(perms, 6); *perms = sl->perms[i] ? &sl->perms[i][sl->minMaxOrients[i][0]] : NULL;} 2392b004864fSMatthew G. Knepley if (rots) {PetscValidPointer(rots, 7); *rots = sl->rots[i] ? &sl->rots[i][sl->minMaxOrients[i][0]] : NULL;} 2393b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2394b004864fSMatthew G. Knepley } 2395b004864fSMatthew G. Knepley 2396b004864fSMatthew G. Knepley /*@C 23975fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 23985fdea053SToby Isaac 23995b5e7992SMatthew G. Knepley Logically collective on sym 24005fdea053SToby Isaac 24015fdea053SToby Isaac InputParameters: 24025b5e7992SMatthew G. Knepley + sym - the section symmetries 24035fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 24045fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 24055fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 24065fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 24075fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 24085fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2409a2b725a8SWilliam 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 24105fdea053SToby Isaac 24115fdea053SToby Isaac Level: developer 24125fdea053SToby Isaac 2413db781477SPatrick Sanan .seealso: `PetscSectionSymLabelGetStratum()`, `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetPointSyms()`, `PetscSectionSymCreateLabel()` 24145fdea053SToby Isaac @*/ 24155fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 24165fdea053SToby Isaac { 24175fdea053SToby Isaac PetscSectionSym_Label *sl; 2418d67d17b1SMatthew G. Knepley const char *name; 2419d67d17b1SMatthew G. Knepley PetscInt i, j, k; 24205fdea053SToby Isaac 24215fdea053SToby Isaac PetscFunctionBegin; 24225fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 24235fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 2424b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 24255fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24265fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 24275fdea053SToby Isaac 24285fdea053SToby Isaac if (stratum == value) break; 24295fdea053SToby Isaac } 24309566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sl->label, &name)); 243163a3b9bcSJacob Faibussowitsch PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 24325fdea053SToby Isaac sl->sizes[i] = size; 24335fdea053SToby Isaac sl->modes[i] = mode; 24345fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 24355fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 24365fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 24375fdea053SToby Isaac if (perms) { 24385fdea053SToby Isaac PetscInt **ownPerms; 24395fdea053SToby Isaac 24409566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient,&ownPerms)); 24415fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 24425fdea053SToby Isaac if (perms[j]) { 24439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&ownPerms[j])); 24445fdea053SToby Isaac for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];} 24455fdea053SToby Isaac } 24465fdea053SToby Isaac } 24475fdea053SToby Isaac sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient]; 24485fdea053SToby Isaac } 24495fdea053SToby Isaac if (rots) { 24505fdea053SToby Isaac PetscScalar **ownRots; 24515fdea053SToby Isaac 24529566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient,&ownRots)); 24535fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 24545fdea053SToby Isaac if (rots[j]) { 24559566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&ownRots[j])); 24565fdea053SToby Isaac for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];} 24575fdea053SToby Isaac } 24585fdea053SToby Isaac } 24595fdea053SToby Isaac sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient]; 24605fdea053SToby Isaac } 24615fdea053SToby Isaac } else { 24625fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 24635fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 24645fdea053SToby Isaac } 24655fdea053SToby Isaac PetscFunctionReturn(0); 24665fdea053SToby Isaac } 24675fdea053SToby Isaac 24685fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 24695fdea053SToby Isaac { 24705fdea053SToby Isaac PetscInt i, j, numStrata; 24715fdea053SToby Isaac PetscSectionSym_Label *sl; 24725fdea053SToby Isaac DMLabel label; 24735fdea053SToby Isaac 24745fdea053SToby Isaac PetscFunctionBegin; 24755fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 24765fdea053SToby Isaac numStrata = sl->numStrata; 24775fdea053SToby Isaac label = sl->label; 24785fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 24795fdea053SToby Isaac PetscInt point = points[2*i]; 24805fdea053SToby Isaac PetscInt ornt = points[2*i+1]; 24815fdea053SToby Isaac 24825fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 24835fdea053SToby Isaac if (label->validIS[j]) { 24845fdea053SToby Isaac PetscInt k; 24855fdea053SToby Isaac 24869566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j],point,&k)); 24875fdea053SToby Isaac if (k >= 0) break; 24885fdea053SToby Isaac } else { 24895fdea053SToby Isaac PetscBool has; 24905fdea053SToby Isaac 24919566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 24925fdea053SToby Isaac if (has) break; 24935fdea053SToby Isaac } 24945fdea053SToby Isaac } 249563a3b9bcSJacob Faibussowitsch 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],j < numStrata ? label->stratumValues[j] : label->defaultValue); 24965fdea053SToby Isaac if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;} 24975fdea053SToby Isaac if (rots) {rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL;} 24985fdea053SToby Isaac } 24995fdea053SToby Isaac PetscFunctionReturn(0); 25005fdea053SToby Isaac } 25015fdea053SToby Isaac 2502b004864fSMatthew G. Knepley static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2503b004864fSMatthew G. Knepley { 2504b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *) nsym->data; 2505b004864fSMatthew G. Knepley IS valIS; 2506b004864fSMatthew G. Knepley const PetscInt *values; 2507b004864fSMatthew G. Knepley PetscInt Nv, v; 2508b004864fSMatthew G. Knepley 2509b004864fSMatthew G. Knepley PetscFunctionBegin; 25109566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 25119566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 25129566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2513b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2514b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2515b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2516b004864fSMatthew G. Knepley const PetscInt **perms; 2517b004864fSMatthew G. Knepley const PetscScalar **rots; 2518b004864fSMatthew G. Knepley 25199566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 25209566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2521b004864fSMatthew G. Knepley } 25229566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 2523b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2524b004864fSMatthew G. Knepley } 2525b004864fSMatthew G. Knepley 2526b004864fSMatthew G. Knepley static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2527b004864fSMatthew G. Knepley { 2528b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 2529b004864fSMatthew G. Knepley DMLabel dlabel; 2530b004864fSMatthew G. Knepley 2531b004864fSMatthew G. Knepley PetscFunctionBegin; 25329566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 25339566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject) sym), dlabel, dsym)); 25349566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 25359566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 2536b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2537b004864fSMatthew G. Knepley } 2538b004864fSMatthew G. Knepley 25395fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 25405fdea053SToby Isaac { 25415fdea053SToby Isaac PetscSectionSym_Label *sl; 25425fdea053SToby Isaac 25435fdea053SToby Isaac PetscFunctionBegin; 25449566063dSJacob Faibussowitsch PetscCall(PetscNewLog(sym,&sl)); 25455fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2546b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2547b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 25485fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 25495fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 25505fdea053SToby Isaac sym->data = (void *) sl; 25515fdea053SToby Isaac PetscFunctionReturn(0); 25525fdea053SToby Isaac } 25535fdea053SToby Isaac 25545fdea053SToby Isaac /*@ 25555fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 25565fdea053SToby Isaac 25575fdea053SToby Isaac Collective 25585fdea053SToby Isaac 25595fdea053SToby Isaac Input Parameters: 25605fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 25615fdea053SToby Isaac - label - the label defining the strata 25625fdea053SToby Isaac 25635fdea053SToby Isaac Output Parameters: 25645fdea053SToby Isaac . sym - the section symmetries 25655fdea053SToby Isaac 25665fdea053SToby Isaac Level: developer 25675fdea053SToby Isaac 2568db781477SPatrick Sanan .seealso: `PetscSectionSymCreate()`, `PetscSectionSetSym()`, `PetscSectionGetSym()`, `PetscSectionSymLabelSetStratum()`, `PetscSectionGetPointSyms()` 25695fdea053SToby Isaac @*/ 25705fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 25715fdea053SToby Isaac { 25725fdea053SToby Isaac PetscFunctionBegin; 25739566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 25749566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm,sym)); 25759566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL)); 25769566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym,label)); 25775fdea053SToby Isaac PetscFunctionReturn(0); 25785fdea053SToby Isaac } 2579