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 25c58f1c22SToby Isaac .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 64c58f1c22SToby Isaac .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; 732c71b3e2SJacob Faibussowitsch PetscCheckFalse(v < 0 || v >= label->numStrata,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D 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]; 8208401ef6SPierre Jolivet PetscCheck(!(point < label->pStart) && !(point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", 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 112c58f1c22SToby Isaac .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 139c58f1c22SToby Isaac .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; 1482c71b3e2SJacob Faibussowitsch PetscCheckFalse(v < 0 || v >= label->numStrata,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D 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 280b9907514SLisandro Dalcin .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 304b9907514SLisandro Dalcin .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 366b9907514SLisandro Dalcin .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)); 3959566063dSJacob Faibussowitsch if (label->bt) PetscCall(PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%D, %D)\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) { 4039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\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 424c58f1c22SToby Isaac .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)); 436c58f1c22SToby Isaac if (iascii) { 4379566063dSJacob Faibussowitsch PetscCall(DMLabelView_Ascii(label, viewer)); 438c58f1c22SToby Isaac } 439c58f1c22SToby Isaac PetscFunctionReturn(0); 440c58f1c22SToby Isaac } 441c58f1c22SToby Isaac 44284f0b6dfSMatthew G. Knepley /*@ 443d67d17b1SMatthew G. Knepley DMLabelReset - Destroys internal data structures in a DMLabel 444d67d17b1SMatthew G. Knepley 4455b5e7992SMatthew G. Knepley Not collective 4465b5e7992SMatthew G. Knepley 447d67d17b1SMatthew G. Knepley Input Parameter: 448d67d17b1SMatthew G. Knepley . label - The DMLabel 449d67d17b1SMatthew G. Knepley 450d67d17b1SMatthew G. Knepley Level: beginner 451d67d17b1SMatthew G. Knepley 452d67d17b1SMatthew G. Knepley .seealso: DMLabelDestroy(), DMLabelCreate() 453d67d17b1SMatthew G. Knepley @*/ 454d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelReset(DMLabel label) 455d67d17b1SMatthew G. Knepley { 456d67d17b1SMatthew G. Knepley PetscInt v; 457d67d17b1SMatthew G. Knepley 458d67d17b1SMatthew G. Knepley PetscFunctionBegin; 459d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 460d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 4619566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&label->ht[v])); 4629566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 463d67d17b1SMatthew G. Knepley } 464b9907514SLisandro Dalcin label->numStrata = 0; 4659566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumValues)); 4669566063dSJacob Faibussowitsch PetscCall(PetscFree(label->stratumSizes)); 4679566063dSJacob Faibussowitsch PetscCall(PetscFree(label->ht)); 4689566063dSJacob Faibussowitsch PetscCall(PetscFree(label->points)); 4699566063dSJacob Faibussowitsch PetscCall(PetscFree(label->validIS)); 470f9244615SMatthew G. Knepley label->stratumValues = NULL; 471f9244615SMatthew G. Knepley label->stratumSizes = NULL; 472f9244615SMatthew G. Knepley label->ht = NULL; 473f9244615SMatthew G. Knepley label->points = NULL; 474f9244615SMatthew G. Knepley label->validIS = NULL; 4759566063dSJacob Faibussowitsch PetscCall(PetscHMapIReset(label->hmap)); 476b9907514SLisandro Dalcin label->pStart = -1; 477b9907514SLisandro Dalcin label->pEnd = -1; 4789566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 479d67d17b1SMatthew G. Knepley PetscFunctionReturn(0); 480d67d17b1SMatthew G. Knepley } 481d67d17b1SMatthew G. Knepley 482d67d17b1SMatthew G. Knepley /*@ 48384f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 48484f0b6dfSMatthew G. Knepley 4855b5e7992SMatthew G. Knepley Collective on label 4865b5e7992SMatthew G. Knepley 48784f0b6dfSMatthew G. Knepley Input Parameter: 48884f0b6dfSMatthew G. Knepley . label - The DMLabel 48984f0b6dfSMatthew G. Knepley 49084f0b6dfSMatthew G. Knepley Level: beginner 49184f0b6dfSMatthew G. Knepley 492d67d17b1SMatthew G. Knepley .seealso: DMLabelReset(), DMLabelCreate() 49384f0b6dfSMatthew G. Knepley @*/ 494c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label) 495c58f1c22SToby Isaac { 496c58f1c22SToby Isaac PetscFunctionBegin; 497d67d17b1SMatthew G. Knepley if (!*label) PetscFunctionReturn(0); 498d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label),DMLABEL_CLASSID,1); 499b9907514SLisandro Dalcin if (--((PetscObject)(*label))->refct > 0) {*label = NULL; PetscFunctionReturn(0);} 5009566063dSJacob Faibussowitsch PetscCall(DMLabelReset(*label)); 5019566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*label)->hmap)); 5029566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(label)); 503c58f1c22SToby Isaac PetscFunctionReturn(0); 504c58f1c22SToby Isaac } 505c58f1c22SToby Isaac 50684f0b6dfSMatthew G. Knepley /*@ 50784f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 50884f0b6dfSMatthew G. Knepley 5095b5e7992SMatthew G. Knepley Collective on label 5105b5e7992SMatthew G. Knepley 51184f0b6dfSMatthew G. Knepley Input Parameter: 51284f0b6dfSMatthew G. Knepley . label - The DMLabel 51384f0b6dfSMatthew G. Knepley 51484f0b6dfSMatthew G. Knepley Output Parameter: 51584f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 51684f0b6dfSMatthew G. Knepley 51784f0b6dfSMatthew G. Knepley Level: intermediate 51884f0b6dfSMatthew G. Knepley 51984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelDestroy() 52084f0b6dfSMatthew G. Knepley @*/ 521c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 522c58f1c22SToby Isaac { 523d67d17b1SMatthew G. Knepley const char *name; 524ad8374ffSToby Isaac PetscInt v; 525c58f1c22SToby Isaac 526c58f1c22SToby Isaac PetscFunctionBegin; 527d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 5289566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 5299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &name)); 5309566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject) label), name, labelnew)); 531c58f1c22SToby Isaac 532c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5335aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 5349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues)); 5359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes)); 5369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->ht)); 5379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->points)); 5389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &(*labelnew)->validIS)); 539c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 5409566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelnew)->ht[v])); 541c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 542c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 5439566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) (label->points[v]))); 544ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 545b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 546c58f1c22SToby Isaac } 5479566063dSJacob Faibussowitsch PetscCall(PetscHMapIDestroy(&(*labelnew)->hmap)); 5489566063dSJacob Faibussowitsch PetscCall(PetscHMapIDuplicate(label->hmap,&(*labelnew)->hmap)); 549c58f1c22SToby Isaac (*labelnew)->pStart = -1; 550c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 551c58f1c22SToby Isaac (*labelnew)->bt = NULL; 552c58f1c22SToby Isaac PetscFunctionReturn(0); 553c58f1c22SToby Isaac } 554c58f1c22SToby Isaac 555609dae6eSVaclav Hapla /*@C 556609dae6eSVaclav Hapla DMLabelCompare - Compare two DMLabel objects 557609dae6eSVaclav Hapla 5585efe38ccSVaclav Hapla Collective on comm 559609dae6eSVaclav Hapla 560609dae6eSVaclav Hapla Input Parameters: 561f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels 562f1a722f8SMatthew G. Knepley . l0 - First DMLabel 563609dae6eSVaclav Hapla - l1 - Second DMLabel 564609dae6eSVaclav Hapla 565609dae6eSVaclav Hapla Output Parameters 5665efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 5675efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 568609dae6eSVaclav Hapla 569609dae6eSVaclav Hapla Level: intermediate 570609dae6eSVaclav Hapla 571609dae6eSVaclav Hapla Notes: 5725efe38ccSVaclav Hapla The output flag equal is the same on all processes. 5735efe38ccSVaclav Hapla If it is passed as NULL and difference is found, an error is thrown on all processes. 5745efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 575609dae6eSVaclav Hapla 5765efe38ccSVaclav Hapla The output message is set independently on each rank. 5775efe38ccSVaclav Hapla It is set to NULL if no difference was found on the current rank. It must be freed by user. 5785efe38ccSVaclav Hapla If message is passed as NULL and difference is found, the difference description is printed to stderr in synchronized manner. 5795efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 580609dae6eSVaclav Hapla 581609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 582609dae6eSVaclav Hapla 5835efe38ccSVaclav Hapla The communicator needs to be specified because currently DMLabel can live on PETSC_COMM_SELF even if the underlying DM is parallel. 5845efe38ccSVaclav Hapla 585609dae6eSVaclav Hapla Fortran Notes: 586609dae6eSVaclav Hapla This function is currently not available from Fortran. 587609dae6eSVaclav Hapla 588609dae6eSVaclav Hapla .seealso: DMCompareLabels(), DMLabelGetNumValues(), DMLabelGetDefaultValue(), DMLabelGetNonEmptyStratumValuesIS(), DMLabelGetStratumIS() 589609dae6eSVaclav Hapla @*/ 5905efe38ccSVaclav Hapla PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 591609dae6eSVaclav Hapla { 592609dae6eSVaclav Hapla const char *name0, *name1; 593609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 5945efe38ccSVaclav Hapla PetscBool eq; 5955efe38ccSVaclav Hapla PetscMPIInt rank; 596609dae6eSVaclav Hapla 597609dae6eSVaclav Hapla PetscFunctionBegin; 5985efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 5995efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 6005efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal, 4); 6015efe38ccSVaclav Hapla if (message) PetscValidPointer(message, 5); 6029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l0, &name0)); 6049566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)l1, &name1)); 605609dae6eSVaclav Hapla { 606609dae6eSVaclav Hapla PetscInt v0, v1; 607609dae6eSVaclav Hapla 6089566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l0, &v0)); 6099566063dSJacob Faibussowitsch PetscCall(DMLabelGetDefaultValue(l1, &v1)); 6105efe38ccSVaclav Hapla eq = (PetscBool) (v0 == v1); 6115efe38ccSVaclav Hapla if (!eq) { 6129566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Default value of DMLabel l0 \"%s\" = %D != %D = Default value of DMLabel l1 \"%s\"", name0, v0, v1, name1)); 613609dae6eSVaclav Hapla } 6149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6155efe38ccSVaclav Hapla if (!eq) goto finish; 616609dae6eSVaclav Hapla } 617609dae6eSVaclav Hapla { 618609dae6eSVaclav Hapla IS is0, is1; 619609dae6eSVaclav Hapla 6209566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l0, &is0)); 6219566063dSJacob Faibussowitsch PetscCall(DMLabelGetNonEmptyStratumValuesIS(l1, &is1)); 6229566063dSJacob Faibussowitsch PetscCall(ISEqual(is0, is1, &eq)); 6239566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6249566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6255efe38ccSVaclav Hapla if (!eq) { 6269566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1)); 627609dae6eSVaclav Hapla } 6289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 6295efe38ccSVaclav Hapla if (!eq) goto finish; 630609dae6eSVaclav Hapla } 631609dae6eSVaclav Hapla { 632609dae6eSVaclav Hapla PetscInt i, nValues; 633609dae6eSVaclav Hapla 6349566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(l0, &nValues)); 635609dae6eSVaclav Hapla for (i=0; i<nValues; i++) { 636609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 637609dae6eSVaclav Hapla PetscInt n; 638609dae6eSVaclav Hapla IS is0, is1; 639609dae6eSVaclav Hapla 6409566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(l0, i, &n)); 641609dae6eSVaclav Hapla if (!n) continue; 6429566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l0, v, &is0)); 6439566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l1, v, &is1)); 6449566063dSJacob Faibussowitsch PetscCall(ISEqualUnsorted(is0, is1, &eq)); 6459566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is0)); 6469566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is1)); 6475efe38ccSVaclav Hapla if (!eq) { 6489566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(msg, sizeof(msg), "Stratum #%D with value %D contains different points in DMLabel l0 \"%s\" and DMLabel l1 \"%s\"", i, v, name0, name1)); 6495efe38ccSVaclav Hapla break; 650609dae6eSVaclav Hapla } 651609dae6eSVaclav Hapla } 6529566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm)); 653609dae6eSVaclav Hapla } 654609dae6eSVaclav Hapla finish: 6555efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 656609dae6eSVaclav Hapla if (message) { 657609dae6eSVaclav Hapla *message = NULL; 658609dae6eSVaclav Hapla if (msg[0]) { 6599566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(msg, message)); 660609dae6eSVaclav Hapla } 6615efe38ccSVaclav Hapla } else { 6625efe38ccSVaclav Hapla if (msg[0]) { 6639566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg)); 664609dae6eSVaclav Hapla } 6659566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 6665efe38ccSVaclav Hapla } 6675efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 6685efe38ccSVaclav Hapla if (equal) *equal = eq; 66928b400f6SJacob Faibussowitsch else PetscCheck(eq,comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal"); 670609dae6eSVaclav Hapla PetscFunctionReturn(0); 671609dae6eSVaclav Hapla } 672609dae6eSVaclav Hapla 673c6a43d28SMatthew G. Knepley /*@ 674c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 675c6a43d28SMatthew G. Knepley 6765b5e7992SMatthew G. Knepley Not collective 6775b5e7992SMatthew G. Knepley 678c6a43d28SMatthew G. Knepley Input Parameter: 679c6a43d28SMatthew G. Knepley . label - The DMLabel 680c6a43d28SMatthew G. Knepley 681c6a43d28SMatthew G. Knepley Level: intermediate 682c6a43d28SMatthew G. Knepley 683c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 684c6a43d28SMatthew G. Knepley @*/ 685c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelComputeIndex(DMLabel label) 686c6a43d28SMatthew G. Knepley { 687c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 688c6a43d28SMatthew G. Knepley 689c6a43d28SMatthew G. Knepley PetscFunctionBegin; 690c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 6919566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 692c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 693c6a43d28SMatthew G. Knepley const PetscInt *points; 694c6a43d28SMatthew G. Knepley PetscInt i; 695c6a43d28SMatthew G. Knepley 6969566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 697c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 698c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 699c6a43d28SMatthew G. Knepley 700c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 701c6a43d28SMatthew G. Knepley pEnd = PetscMax(point+1, pEnd); 702c6a43d28SMatthew G. Knepley } 7039566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 704c6a43d28SMatthew G. Knepley } 705c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 706c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 7079566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 708c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 709c6a43d28SMatthew G. Knepley } 710c6a43d28SMatthew G. Knepley 711c6a43d28SMatthew G. Knepley /*@ 712c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 713c6a43d28SMatthew G. Knepley 7145b5e7992SMatthew G. Knepley Not collective 7155b5e7992SMatthew G. Knepley 716c6a43d28SMatthew G. Knepley Input Parameters: 717c6a43d28SMatthew G. Knepley + label - The DMLabel 718c6a43d28SMatthew G. Knepley . pStart - The smallest point 719c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 720c6a43d28SMatthew G. Knepley 721c6a43d28SMatthew G. Knepley Level: intermediate 722c6a43d28SMatthew G. Knepley 723c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelComputeIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 724c6a43d28SMatthew G. Knepley @*/ 725c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 726c58f1c22SToby Isaac { 727c58f1c22SToby Isaac PetscInt v; 728c58f1c22SToby Isaac 729c58f1c22SToby Isaac PetscFunctionBegin; 730d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7319566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 7329566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 733c58f1c22SToby Isaac label->pStart = pStart; 734c58f1c22SToby Isaac label->pEnd = pEnd; 735c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 7369566063dSJacob Faibussowitsch PetscCall(PetscBTCreate(pEnd - pStart, &label->bt)); 737c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 738ad8374ffSToby Isaac const PetscInt *points; 739c58f1c22SToby Isaac PetscInt i; 740c58f1c22SToby Isaac 7419566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 742c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 743ad8374ffSToby Isaac const PetscInt point = points[i]; 744c58f1c22SToby Isaac 74508401ef6SPierre Jolivet PetscCheck(!(point < pStart) && !(point >= pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, pStart, pEnd); 7469566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - pStart)); 747c58f1c22SToby Isaac } 7489566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 749c58f1c22SToby Isaac } 750c58f1c22SToby Isaac PetscFunctionReturn(0); 751c58f1c22SToby Isaac } 752c58f1c22SToby Isaac 753c6a43d28SMatthew G. Knepley /*@ 754c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 755c6a43d28SMatthew G. Knepley 7565b5e7992SMatthew G. Knepley Not collective 7575b5e7992SMatthew G. Knepley 758c6a43d28SMatthew G. Knepley Input Parameter: 759c6a43d28SMatthew G. Knepley . label - the DMLabel 760c6a43d28SMatthew G. Knepley 761c6a43d28SMatthew G. Knepley Level: intermediate 762c6a43d28SMatthew G. Knepley 763c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 764c6a43d28SMatthew G. Knepley @*/ 765c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label) 766c58f1c22SToby Isaac { 767c58f1c22SToby Isaac PetscFunctionBegin; 768d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 769c58f1c22SToby Isaac label->pStart = -1; 770c58f1c22SToby Isaac label->pEnd = -1; 7719566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 772c58f1c22SToby Isaac PetscFunctionReturn(0); 773c58f1c22SToby Isaac } 774c58f1c22SToby Isaac 775c58f1c22SToby Isaac /*@ 776c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 777c6a43d28SMatthew G. Knepley 7785b5e7992SMatthew G. Knepley Not collective 7795b5e7992SMatthew G. Knepley 780c6a43d28SMatthew G. Knepley Input Parameter: 781c6a43d28SMatthew G. Knepley . label - the DMLabel 782c6a43d28SMatthew G. Knepley 783c6a43d28SMatthew G. Knepley Output Parameters: 784c6a43d28SMatthew G. Knepley + pStart - The smallest point 785c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 786c6a43d28SMatthew G. Knepley 787c6a43d28SMatthew G. Knepley Note: This will compute an index for the label if one does not exist. 788c6a43d28SMatthew G. Knepley 789c6a43d28SMatthew G. Knepley Level: intermediate 790c6a43d28SMatthew G. Knepley 791c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 792c6a43d28SMatthew G. Knepley @*/ 793c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 794c6a43d28SMatthew G. Knepley { 795c6a43d28SMatthew G. Knepley PetscFunctionBegin; 796c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7979566063dSJacob Faibussowitsch if ((label->pStart == -1) && (label->pEnd == -1)) PetscCall(DMLabelComputeIndex(label)); 798c6a43d28SMatthew G. Knepley if (pStart) { 799534a8f05SLisandro Dalcin PetscValidIntPointer(pStart, 2); 800c6a43d28SMatthew G. Knepley *pStart = label->pStart; 801c6a43d28SMatthew G. Knepley } 802c6a43d28SMatthew G. Knepley if (pEnd) { 803534a8f05SLisandro Dalcin PetscValidIntPointer(pEnd, 3); 804c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 805c6a43d28SMatthew G. Knepley } 806c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 807c6a43d28SMatthew G. Knepley } 808c6a43d28SMatthew G. Knepley 809c6a43d28SMatthew G. Knepley /*@ 810c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 811c58f1c22SToby Isaac 8125b5e7992SMatthew G. Knepley Not collective 8135b5e7992SMatthew G. Knepley 814c58f1c22SToby Isaac Input Parameters: 815c58f1c22SToby Isaac + label - the DMLabel 816c58f1c22SToby Isaac - value - the value 817c58f1c22SToby Isaac 818c58f1c22SToby Isaac Output Parameter: 819c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 820c58f1c22SToby Isaac 821c58f1c22SToby Isaac Level: developer 822c58f1c22SToby Isaac 823c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue() 824c58f1c22SToby Isaac @*/ 825c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 826c58f1c22SToby Isaac { 827c58f1c22SToby Isaac PetscInt v; 828c58f1c22SToby Isaac 829c58f1c22SToby Isaac PetscFunctionBegin; 830d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 831534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8329566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8330c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 834c58f1c22SToby Isaac PetscFunctionReturn(0); 835c58f1c22SToby Isaac } 836c58f1c22SToby Isaac 837c58f1c22SToby Isaac /*@ 838c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 839c58f1c22SToby Isaac 8405b5e7992SMatthew G. Knepley Not collective 8415b5e7992SMatthew G. Knepley 842c58f1c22SToby Isaac Input Parameters: 843c58f1c22SToby Isaac + label - the DMLabel 844c58f1c22SToby Isaac - point - the point 845c58f1c22SToby Isaac 846c58f1c22SToby Isaac Output Parameter: 847c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 848c58f1c22SToby Isaac 849c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 850c58f1c22SToby Isaac 851c58f1c22SToby Isaac Level: developer 852c58f1c22SToby Isaac 853c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 854c58f1c22SToby Isaac @*/ 855c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 856c58f1c22SToby Isaac { 857c58f1c22SToby Isaac PetscFunctionBeginHot; 858d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 859534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8609566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 86176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 86228b400f6SJacob Faibussowitsch PetscCheck(label->bt,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 86308401ef6SPierre Jolivet PetscCheck(!(point < label->pStart) && !(point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 86476bd3646SJed Brown } 865c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 866c58f1c22SToby Isaac PetscFunctionReturn(0); 867c58f1c22SToby Isaac } 868c58f1c22SToby Isaac 869c58f1c22SToby Isaac /*@ 870c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 871c58f1c22SToby Isaac 8725b5e7992SMatthew G. Knepley Not collective 8735b5e7992SMatthew G. Knepley 874c58f1c22SToby Isaac Input Parameters: 875c58f1c22SToby Isaac + label - the DMLabel 876c58f1c22SToby Isaac . value - the stratum value 877c58f1c22SToby Isaac - point - the point 878c58f1c22SToby Isaac 879c58f1c22SToby Isaac Output Parameter: 880c58f1c22SToby Isaac . contains - true if the stratum contains the point 881c58f1c22SToby Isaac 882c58f1c22SToby Isaac Level: intermediate 883c58f1c22SToby Isaac 884c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue() 885c58f1c22SToby Isaac @*/ 886c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 887c58f1c22SToby Isaac { 888c58f1c22SToby Isaac PetscInt v; 889c58f1c22SToby Isaac 8900c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 891d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 892534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 4); 893c58f1c22SToby Isaac *contains = PETSC_FALSE; 8949566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 8950c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 8960c3c4a36SLisandro Dalcin 897ad8374ffSToby Isaac if (label->validIS[v]) { 898c58f1c22SToby Isaac PetscInt i; 899c58f1c22SToby Isaac 9009566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 9010c3c4a36SLisandro Dalcin if (i >= 0) *contains = PETSC_TRUE; 902c58f1c22SToby Isaac } else { 903c58f1c22SToby Isaac PetscBool has; 904c58f1c22SToby Isaac 9059566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 9060c3c4a36SLisandro Dalcin if (has) *contains = PETSC_TRUE; 907c58f1c22SToby Isaac } 908c58f1c22SToby Isaac PetscFunctionReturn(0); 909c58f1c22SToby Isaac } 910c58f1c22SToby Isaac 91184f0b6dfSMatthew G. Knepley /*@ 9125aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9135aa44df4SToby Isaac When a label is created, it is initialized to -1. 9145aa44df4SToby Isaac 9155b5e7992SMatthew G. Knepley Not collective 9165b5e7992SMatthew G. Knepley 9175aa44df4SToby Isaac Input parameter: 9185aa44df4SToby Isaac . label - a DMLabel object 9195aa44df4SToby Isaac 9205aa44df4SToby Isaac Output parameter: 9215aa44df4SToby Isaac . defaultValue - the default value 9225aa44df4SToby Isaac 9235aa44df4SToby Isaac Level: beginner 9245aa44df4SToby Isaac 9255aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 92684f0b6dfSMatthew G. Knepley @*/ 9275aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 9285aa44df4SToby Isaac { 9295aa44df4SToby Isaac PetscFunctionBegin; 930d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9315aa44df4SToby Isaac *defaultValue = label->defaultValue; 9325aa44df4SToby Isaac PetscFunctionReturn(0); 9335aa44df4SToby Isaac } 9345aa44df4SToby Isaac 93584f0b6dfSMatthew G. Knepley /*@ 9365aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9375aa44df4SToby Isaac When a label is created, it is initialized to -1. 9385aa44df4SToby Isaac 9395b5e7992SMatthew G. Knepley Not collective 9405b5e7992SMatthew G. Knepley 9415aa44df4SToby Isaac Input parameter: 9425aa44df4SToby Isaac . label - a DMLabel object 9435aa44df4SToby Isaac 9445aa44df4SToby Isaac Output parameter: 9455aa44df4SToby Isaac . defaultValue - the default value 9465aa44df4SToby Isaac 9475aa44df4SToby Isaac Level: beginner 9485aa44df4SToby Isaac 9495aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 95084f0b6dfSMatthew G. Knepley @*/ 9515aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 9525aa44df4SToby Isaac { 9535aa44df4SToby Isaac PetscFunctionBegin; 954d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9555aa44df4SToby Isaac label->defaultValue = defaultValue; 9565aa44df4SToby Isaac PetscFunctionReturn(0); 9575aa44df4SToby Isaac } 9585aa44df4SToby Isaac 959c58f1c22SToby Isaac /*@ 9605aa44df4SToby 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()) 961c58f1c22SToby Isaac 9625b5e7992SMatthew G. Knepley Not collective 9635b5e7992SMatthew G. Knepley 964c58f1c22SToby Isaac Input Parameters: 965c58f1c22SToby Isaac + label - the DMLabel 966c58f1c22SToby Isaac - point - the point 967c58f1c22SToby Isaac 968c58f1c22SToby Isaac Output Parameter: 9698e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 970c58f1c22SToby Isaac 971c58f1c22SToby Isaac Level: intermediate 972c58f1c22SToby Isaac 9735aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 974c58f1c22SToby Isaac @*/ 975c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 976c58f1c22SToby Isaac { 977c58f1c22SToby Isaac PetscInt v; 978c58f1c22SToby Isaac 9790c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 980d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 981dadcf809SJacob Faibussowitsch PetscValidIntPointer(value, 3); 9825aa44df4SToby Isaac *value = label->defaultValue; 983c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 984ad8374ffSToby Isaac if (label->validIS[v]) { 985c58f1c22SToby Isaac PetscInt i; 986c58f1c22SToby Isaac 9879566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[v], point, &i)); 988c58f1c22SToby Isaac if (i >= 0) { 989c58f1c22SToby Isaac *value = label->stratumValues[v]; 990c58f1c22SToby Isaac break; 991c58f1c22SToby Isaac } 992c58f1c22SToby Isaac } else { 993c58f1c22SToby Isaac PetscBool has; 994c58f1c22SToby Isaac 9959566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[v], point, &has)); 996c58f1c22SToby Isaac if (has) { 997c58f1c22SToby Isaac *value = label->stratumValues[v]; 998c58f1c22SToby Isaac break; 999c58f1c22SToby Isaac } 1000c58f1c22SToby Isaac } 1001c58f1c22SToby Isaac } 1002c58f1c22SToby Isaac PetscFunctionReturn(0); 1003c58f1c22SToby Isaac } 1004c58f1c22SToby Isaac 1005c58f1c22SToby Isaac /*@ 1006367003a6SStefano 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. 1007c58f1c22SToby Isaac 10085b5e7992SMatthew G. Knepley Not collective 10095b5e7992SMatthew G. Knepley 1010c58f1c22SToby Isaac Input Parameters: 1011c58f1c22SToby Isaac + label - the DMLabel 1012c58f1c22SToby Isaac . point - the point 1013c58f1c22SToby Isaac - value - The point value 1014c58f1c22SToby Isaac 1015c58f1c22SToby Isaac Level: intermediate 1016c58f1c22SToby Isaac 10175aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 1018c58f1c22SToby Isaac @*/ 1019c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1020c58f1c22SToby Isaac { 1021c58f1c22SToby Isaac PetscInt v; 1022c58f1c22SToby Isaac 1023c58f1c22SToby Isaac PetscFunctionBegin; 1024d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10250c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10265aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 10279566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 1028c58f1c22SToby Isaac /* Set key */ 10299566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10309566063dSJacob Faibussowitsch PetscCall(PetscHSetIAdd(label->ht[v], point)); 1031c58f1c22SToby Isaac PetscFunctionReturn(0); 1032c58f1c22SToby Isaac } 1033c58f1c22SToby Isaac 1034c58f1c22SToby Isaac /*@ 1035c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1036c58f1c22SToby Isaac 10375b5e7992SMatthew G. Knepley Not collective 10385b5e7992SMatthew G. Knepley 1039c58f1c22SToby Isaac Input Parameters: 1040c58f1c22SToby Isaac + label - the DMLabel 1041c58f1c22SToby Isaac . point - the point 1042c58f1c22SToby Isaac - value - The point value 1043c58f1c22SToby Isaac 1044c58f1c22SToby Isaac Level: intermediate 1045c58f1c22SToby Isaac 1046c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue() 1047c58f1c22SToby Isaac @*/ 1048c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1049c58f1c22SToby Isaac { 1050ad8374ffSToby Isaac PetscInt v; 1051c58f1c22SToby Isaac 1052c58f1c22SToby Isaac PetscFunctionBegin; 1053d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1054c58f1c22SToby Isaac /* Find label value */ 10559566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 10560c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 10570c3c4a36SLisandro Dalcin 1058eeed21e7SToby Isaac if (label->bt) { 105908401ef6SPierre Jolivet PetscCheck(!(point < label->pStart) && !(point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 10609566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1061eeed21e7SToby Isaac } 10620c3c4a36SLisandro Dalcin 10630c3c4a36SLisandro Dalcin /* Delete key */ 10649566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10659566063dSJacob Faibussowitsch PetscCall(PetscHSetIDel(label->ht[v], point)); 1066c58f1c22SToby Isaac PetscFunctionReturn(0); 1067c58f1c22SToby Isaac } 1068c58f1c22SToby Isaac 1069c58f1c22SToby Isaac /*@ 1070c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 1071c58f1c22SToby Isaac 10725b5e7992SMatthew G. Knepley Not collective 10735b5e7992SMatthew G. Knepley 1074c58f1c22SToby Isaac Input Parameters: 1075c58f1c22SToby Isaac + label - the DMLabel 1076c58f1c22SToby Isaac . is - the point IS 1077c58f1c22SToby Isaac - value - The point value 1078c58f1c22SToby Isaac 1079c58f1c22SToby Isaac Level: intermediate 1080c58f1c22SToby Isaac 1081c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 1082c58f1c22SToby Isaac @*/ 1083c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1084c58f1c22SToby Isaac { 10850c3c4a36SLisandro Dalcin PetscInt v, n, p; 1086c58f1c22SToby Isaac const PetscInt *points; 1087c58f1c22SToby Isaac 1088c58f1c22SToby Isaac PetscFunctionBegin; 1089d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1090c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 10910c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10920c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 10939566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 10940c3c4a36SLisandro Dalcin /* Set keys */ 10959566063dSJacob Faibussowitsch PetscCall(DMLabelMakeInvalid_Private(label, v)); 10969566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 10979566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &points)); 10989566063dSJacob Faibussowitsch for (p = 0; p < n; ++p) PetscCall(PetscHSetIAdd(label->ht[v], points[p])); 10999566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &points)); 1100c58f1c22SToby Isaac PetscFunctionReturn(0); 1101c58f1c22SToby Isaac } 1102c58f1c22SToby Isaac 110384f0b6dfSMatthew G. Knepley /*@ 110484f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 110584f0b6dfSMatthew G. Knepley 11065b5e7992SMatthew G. Knepley Not collective 11075b5e7992SMatthew G. Knepley 110884f0b6dfSMatthew G. Knepley Input Parameter: 110984f0b6dfSMatthew G. Knepley . label - the DMLabel 111084f0b6dfSMatthew G. Knepley 111101d2d390SJose E. Roman Output Parameter: 111284f0b6dfSMatthew G. Knepley . numValues - the number of values 111384f0b6dfSMatthew G. Knepley 111484f0b6dfSMatthew G. Knepley Level: intermediate 111584f0b6dfSMatthew G. Knepley 111684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 111784f0b6dfSMatthew G. Knepley @*/ 1118c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1119c58f1c22SToby Isaac { 1120c58f1c22SToby Isaac PetscFunctionBegin; 1121d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1122dadcf809SJacob Faibussowitsch PetscValidIntPointer(numValues, 2); 1123c58f1c22SToby Isaac *numValues = label->numStrata; 1124c58f1c22SToby Isaac PetscFunctionReturn(0); 1125c58f1c22SToby Isaac } 1126c58f1c22SToby Isaac 112784f0b6dfSMatthew G. Knepley /*@ 112884f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 112984f0b6dfSMatthew G. Knepley 11305b5e7992SMatthew G. Knepley Not collective 11315b5e7992SMatthew G. Knepley 113284f0b6dfSMatthew G. Knepley Input Parameter: 113384f0b6dfSMatthew G. Knepley . label - the DMLabel 113484f0b6dfSMatthew G. Knepley 113501d2d390SJose E. Roman Output Parameter: 113684f0b6dfSMatthew G. Knepley . is - the value IS 113784f0b6dfSMatthew G. Knepley 113884f0b6dfSMatthew G. Knepley Level: intermediate 113984f0b6dfSMatthew G. Knepley 11401d04cbbeSVaclav Hapla Notes: 11411d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11421d04cbbeSVaclav Hapla Strata which are allocated but empty [DMLabelGetStratumSize() yields 0] are counted. 11431d04cbbeSVaclav Hapla If you need to count only nonempty strata, use DMLabelGetNonEmptyStratumValuesIS(). 11441d04cbbeSVaclav Hapla 11451d04cbbeSVaclav Hapla .seealso: DMLabelGetNonEmptyStratumValuesIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 114684f0b6dfSMatthew G. Knepley @*/ 1147c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1148c58f1c22SToby Isaac { 1149c58f1c22SToby Isaac PetscFunctionBegin; 1150d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1151c58f1c22SToby Isaac PetscValidPointer(values, 2); 11529566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 1153c58f1c22SToby Isaac PetscFunctionReturn(0); 1154c58f1c22SToby Isaac } 1155c58f1c22SToby Isaac 115684f0b6dfSMatthew G. Knepley /*@ 11571d04cbbeSVaclav Hapla DMLabelGetNonEmptyStratumValuesIS - Get an IS of all values that the DMlabel takes 11581d04cbbeSVaclav Hapla 11591d04cbbeSVaclav Hapla Not collective 11601d04cbbeSVaclav Hapla 11611d04cbbeSVaclav Hapla Input Parameter: 11621d04cbbeSVaclav Hapla . label - the DMLabel 11631d04cbbeSVaclav Hapla 11641d04cbbeSVaclav Hapla Output Paramater: 11651d04cbbeSVaclav Hapla . is - the value IS 11661d04cbbeSVaclav Hapla 11671d04cbbeSVaclav Hapla Level: intermediate 11681d04cbbeSVaclav Hapla 11691d04cbbeSVaclav Hapla Notes: 11701d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11711d04cbbeSVaclav Hapla This is similar to DMLabelGetValueIS() but counts only nonempty strata. 11721d04cbbeSVaclav Hapla 11731d04cbbeSVaclav Hapla .seealso: DMLabelGetValueIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 11741d04cbbeSVaclav Hapla @*/ 11751d04cbbeSVaclav Hapla PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 11761d04cbbeSVaclav Hapla { 11771d04cbbeSVaclav Hapla PetscInt i, j; 11781d04cbbeSVaclav Hapla PetscInt *valuesArr; 11791d04cbbeSVaclav Hapla 11801d04cbbeSVaclav Hapla PetscFunctionBegin; 11811d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 11821d04cbbeSVaclav Hapla PetscValidPointer(values, 2); 11839566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(label->numStrata, &valuesArr)); 11841d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 11851d04cbbeSVaclav Hapla PetscInt n; 11861d04cbbeSVaclav Hapla 11879566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, i, &n)); 11881d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 11891d04cbbeSVaclav Hapla } 11901d04cbbeSVaclav Hapla if (j == label->numStrata) { 11919566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values)); 11921d04cbbeSVaclav Hapla } else { 11939566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values)); 11941d04cbbeSVaclav Hapla } 11959566063dSJacob Faibussowitsch PetscCall(PetscFree(valuesArr)); 11961d04cbbeSVaclav Hapla PetscFunctionReturn(0); 11971d04cbbeSVaclav Hapla } 11981d04cbbeSVaclav Hapla 11991d04cbbeSVaclav Hapla /*@ 1200d123abd9SMatthew 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 1201d123abd9SMatthew G. Knepley 1202d123abd9SMatthew G. Knepley Not collective 1203d123abd9SMatthew G. Knepley 1204d123abd9SMatthew G. Knepley Input Parameters: 1205d123abd9SMatthew G. Knepley + label - the DMLabel 120697bb3fdcSJose E. Roman - value - the value 1207d123abd9SMatthew G. Knepley 120801d2d390SJose E. Roman Output Parameter: 1209d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1210d123abd9SMatthew G. Knepley 1211d123abd9SMatthew G. Knepley Level: intermediate 1212d123abd9SMatthew G. Knepley 1213d123abd9SMatthew G. Knepley .seealso: DMLabelGetValueIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 1214d123abd9SMatthew G. Knepley @*/ 1215d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1216d123abd9SMatthew G. Knepley { 1217d123abd9SMatthew G. Knepley PetscInt v; 1218d123abd9SMatthew G. Knepley 1219d123abd9SMatthew G. Knepley PetscFunctionBegin; 1220d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1221dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 3); 1222d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 1223d123abd9SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) if (label->stratumValues[v] == value) break; 1224d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1225d123abd9SMatthew G. Knepley else *index = v; 1226d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1227d123abd9SMatthew G. Knepley } 1228d123abd9SMatthew G. Knepley 1229d123abd9SMatthew G. Knepley /*@ 123084f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 123184f0b6dfSMatthew G. Knepley 12325b5e7992SMatthew G. Knepley Not collective 12335b5e7992SMatthew G. Knepley 123484f0b6dfSMatthew G. Knepley Input Parameters: 123584f0b6dfSMatthew G. Knepley + label - the DMLabel 123684f0b6dfSMatthew G. Knepley - value - the stratum value 123784f0b6dfSMatthew G. Knepley 123801d2d390SJose E. Roman Output Parameter: 123984f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 124084f0b6dfSMatthew G. Knepley 124184f0b6dfSMatthew G. Knepley Level: intermediate 124284f0b6dfSMatthew G. Knepley 124384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 124484f0b6dfSMatthew G. Knepley @*/ 1245fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1246fada774cSMatthew G. Knepley { 1247fada774cSMatthew G. Knepley PetscInt v; 1248fada774cSMatthew G. Knepley 1249fada774cSMatthew G. Knepley PetscFunctionBegin; 1250d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1251dadcf809SJacob Faibussowitsch PetscValidBoolPointer(exists, 3); 12529566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12530c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 1254fada774cSMatthew G. Knepley PetscFunctionReturn(0); 1255fada774cSMatthew G. Knepley } 1256fada774cSMatthew G. Knepley 125784f0b6dfSMatthew G. Knepley /*@ 125884f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 125984f0b6dfSMatthew G. Knepley 12605b5e7992SMatthew G. Knepley Not collective 12615b5e7992SMatthew G. Knepley 126284f0b6dfSMatthew G. Knepley Input Parameters: 126384f0b6dfSMatthew G. Knepley + label - the DMLabel 126484f0b6dfSMatthew G. Knepley - value - the stratum value 126584f0b6dfSMatthew G. Knepley 126601d2d390SJose E. Roman Output Parameter: 126784f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 126884f0b6dfSMatthew G. Knepley 126984f0b6dfSMatthew G. Knepley Level: intermediate 127084f0b6dfSMatthew G. Knepley 127184f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 127284f0b6dfSMatthew G. Knepley @*/ 1273c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1274c58f1c22SToby Isaac { 1275c58f1c22SToby Isaac PetscInt v; 1276c58f1c22SToby Isaac 1277c58f1c22SToby Isaac PetscFunctionBegin; 1278d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1279dadcf809SJacob Faibussowitsch PetscValidIntPointer(size, 3); 12809566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 12819566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize_Private(label, v, size)); 1282c58f1c22SToby Isaac PetscFunctionReturn(0); 1283c58f1c22SToby Isaac } 1284c58f1c22SToby Isaac 128584f0b6dfSMatthew G. Knepley /*@ 128684f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 128784f0b6dfSMatthew G. Knepley 12885b5e7992SMatthew G. Knepley Not collective 12895b5e7992SMatthew G. Knepley 129084f0b6dfSMatthew G. Knepley Input Parameters: 129184f0b6dfSMatthew G. Knepley + label - the DMLabel 129284f0b6dfSMatthew G. Knepley - value - the stratum value 129384f0b6dfSMatthew G. Knepley 129401d2d390SJose E. Roman Output Parameters: 129584f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 129684f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 129784f0b6dfSMatthew G. Knepley 129884f0b6dfSMatthew G. Knepley Level: intermediate 129984f0b6dfSMatthew G. Knepley 130084f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 130184f0b6dfSMatthew G. Knepley @*/ 1302c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1303c58f1c22SToby Isaac { 13040c3c4a36SLisandro Dalcin PetscInt v, min, max; 1305c58f1c22SToby Isaac 1306c58f1c22SToby Isaac PetscFunctionBegin; 1307d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1308dadcf809SJacob Faibussowitsch if (start) {PetscValidIntPointer(start, 3); *start = -1;} 1309dadcf809SJacob Faibussowitsch if (end) {PetscValidIntPointer(end, 4); *end = -1;} 13109566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13110c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13129566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13130c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 13149566063dSJacob Faibussowitsch PetscCall(ISGetMinMax(label->points[v], &min, &max)); 1315d6cb179aSToby Isaac if (start) *start = min; 1316d6cb179aSToby Isaac if (end) *end = max+1; 1317c58f1c22SToby Isaac PetscFunctionReturn(0); 1318c58f1c22SToby Isaac } 1319c58f1c22SToby Isaac 132084f0b6dfSMatthew G. Knepley /*@ 132184f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 132284f0b6dfSMatthew G. Knepley 13235b5e7992SMatthew G. Knepley Not collective 13245b5e7992SMatthew G. Knepley 132584f0b6dfSMatthew G. Knepley Input Parameters: 132684f0b6dfSMatthew G. Knepley + label - the DMLabel 132784f0b6dfSMatthew G. Knepley - value - the stratum value 132884f0b6dfSMatthew G. Knepley 132901d2d390SJose E. Roman Output Parameter: 133084f0b6dfSMatthew G. Knepley . points - The stratum points 133184f0b6dfSMatthew G. Knepley 133284f0b6dfSMatthew G. Knepley Level: intermediate 133384f0b6dfSMatthew G. Knepley 1334593ce467SVaclav Hapla Notes: 1335593ce467SVaclav Hapla The output IS should be destroyed when no longer needed. 1336593ce467SVaclav Hapla Returns NULL if the stratum is empty. 1337593ce467SVaclav Hapla 133884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 133984f0b6dfSMatthew G. Knepley @*/ 1340c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1341c58f1c22SToby Isaac { 1342c58f1c22SToby Isaac PetscInt v; 1343c58f1c22SToby Isaac 1344c58f1c22SToby Isaac PetscFunctionBegin; 1345d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1346c58f1c22SToby Isaac PetscValidPointer(points, 3); 1347c58f1c22SToby Isaac *points = NULL; 13489566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 13490c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 13509566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 13519566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label->points[v])); 1352ad8374ffSToby Isaac *points = label->points[v]; 1353c58f1c22SToby Isaac PetscFunctionReturn(0); 1354c58f1c22SToby Isaac } 1355c58f1c22SToby Isaac 135684f0b6dfSMatthew G. Knepley /*@ 135784f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 135884f0b6dfSMatthew G. Knepley 13595b5e7992SMatthew G. Knepley Not collective 13605b5e7992SMatthew G. Knepley 136184f0b6dfSMatthew G. Knepley Input Parameters: 136284f0b6dfSMatthew G. Knepley + label - the DMLabel 136384f0b6dfSMatthew G. Knepley . value - the stratum value 136484f0b6dfSMatthew G. Knepley - points - The stratum points 136584f0b6dfSMatthew G. Knepley 136684f0b6dfSMatthew G. Knepley Level: intermediate 136784f0b6dfSMatthew G. Knepley 136884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 136984f0b6dfSMatthew G. Knepley @*/ 13704de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 13714de306b1SToby Isaac { 13720c3c4a36SLisandro Dalcin PetscInt v; 13734de306b1SToby Isaac 13744de306b1SToby Isaac PetscFunctionBegin; 1375d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1376d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 13779566063dSJacob Faibussowitsch PetscCall(DMLabelLookupAddStratum(label, value, &v)); 13784de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 13799566063dSJacob Faibussowitsch PetscCall(DMLabelClearStratum(label, value)); 13809566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &(label->stratumSizes[v]))); 13819566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is)); 13829566063dSJacob Faibussowitsch PetscCall(ISDestroy(&(label->points[v]))); 13830c3c4a36SLisandro Dalcin label->points[v] = is; 13840c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 13859566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject) label)); 13864de306b1SToby Isaac if (label->bt) { 13874de306b1SToby Isaac const PetscInt *points; 13884de306b1SToby Isaac PetscInt p; 13894de306b1SToby Isaac 13909566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is,&points)); 13914de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 13924de306b1SToby Isaac const PetscInt point = points[p]; 13934de306b1SToby Isaac 139408401ef6SPierre Jolivet PetscCheck(!(point < label->pStart) && !(point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 13959566063dSJacob Faibussowitsch PetscCall(PetscBTSet(label->bt, point - label->pStart)); 13964de306b1SToby Isaac } 13974de306b1SToby Isaac } 13984de306b1SToby Isaac PetscFunctionReturn(0); 13994de306b1SToby Isaac } 14004de306b1SToby Isaac 140184f0b6dfSMatthew G. Knepley /*@ 140284f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 14034de306b1SToby Isaac 14045b5e7992SMatthew G. Knepley Not collective 14055b5e7992SMatthew G. Knepley 140684f0b6dfSMatthew G. Knepley Input Parameters: 140784f0b6dfSMatthew G. Knepley + label - the DMLabel 140884f0b6dfSMatthew G. Knepley - value - the stratum value 140984f0b6dfSMatthew G. Knepley 141084f0b6dfSMatthew G. Knepley Level: intermediate 141184f0b6dfSMatthew G. Knepley 141284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 141384f0b6dfSMatthew G. Knepley @*/ 1414c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1415c58f1c22SToby Isaac { 1416c58f1c22SToby Isaac PetscInt v; 1417c58f1c22SToby Isaac 1418c58f1c22SToby Isaac PetscFunctionBegin; 1419d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14209566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 14210c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 14224de306b1SToby Isaac if (label->validIS[v]) { 14234de306b1SToby Isaac if (label->bt) { 1424c58f1c22SToby Isaac PetscInt i; 1425ad8374ffSToby Isaac const PetscInt *points; 1426c58f1c22SToby Isaac 14279566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &points)); 1428c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1429ad8374ffSToby Isaac const PetscInt point = points[i]; 1430c58f1c22SToby Isaac 143108401ef6SPierre Jolivet PetscCheck(!(point < label->pStart) && !(point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 14329566063dSJacob Faibussowitsch PetscCall(PetscBTClear(label->bt, point - label->pStart)); 1433c58f1c22SToby Isaac } 14349566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &points)); 1435c58f1c22SToby Isaac } 1436c58f1c22SToby Isaac label->stratumSizes[v] = 0; 14379566063dSJacob Faibussowitsch PetscCall(ISDestroy(&label->points[v])); 14389566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v])); 14399566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) label->points[v], "indices")); 14409566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject) label)); 1441c58f1c22SToby Isaac } else { 14429566063dSJacob Faibussowitsch PetscCall(PetscHSetIClear(label->ht[v])); 1443c58f1c22SToby Isaac } 1444c58f1c22SToby Isaac PetscFunctionReturn(0); 1445c58f1c22SToby Isaac } 1446c58f1c22SToby Isaac 144784f0b6dfSMatthew G. Knepley /*@ 1448412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1449412e9a14SMatthew G. Knepley 1450412e9a14SMatthew G. Knepley Not collective 1451412e9a14SMatthew G. Knepley 1452412e9a14SMatthew G. Knepley Input Parameters: 1453412e9a14SMatthew G. Knepley + label - The DMLabel 1454412e9a14SMatthew G. Knepley . value - The label value for all points 1455412e9a14SMatthew G. Knepley . pStart - The first point 1456412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1457412e9a14SMatthew G. Knepley 1458412e9a14SMatthew G. Knepley Note: The marks points are [pStart, pEnd), and only the bounds are stored. 1459412e9a14SMatthew G. Knepley 1460412e9a14SMatthew G. Knepley Level: intermediate 1461412e9a14SMatthew G. Knepley 1462412e9a14SMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelSetStratumIS(), DMLabelGetStratumIS() 1463412e9a14SMatthew G. Knepley @*/ 1464412e9a14SMatthew G. Knepley PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1465412e9a14SMatthew G. Knepley { 1466412e9a14SMatthew G. Knepley IS pIS; 1467412e9a14SMatthew G. Knepley 1468412e9a14SMatthew G. Knepley PetscFunctionBegin; 14699566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS)); 14709566063dSJacob Faibussowitsch PetscCall(DMLabelSetStratumIS(label, value, pIS)); 14719566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pIS)); 1472412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1473412e9a14SMatthew G. Knepley } 1474412e9a14SMatthew G. Knepley 1475412e9a14SMatthew G. Knepley /*@ 1476d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1477d123abd9SMatthew G. Knepley 1478d123abd9SMatthew G. Knepley Not collective 1479d123abd9SMatthew G. Knepley 1480d123abd9SMatthew G. Knepley Input Parameters: 1481d123abd9SMatthew G. Knepley + label - The DMLabel 1482d123abd9SMatthew G. Knepley . value - The label value 1483d123abd9SMatthew G. Knepley - p - A point with this value 1484d123abd9SMatthew G. Knepley 1485d123abd9SMatthew G. Knepley Output Parameter: 1486d123abd9SMatthew 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 1487d123abd9SMatthew G. Knepley 1488d123abd9SMatthew G. Knepley Level: intermediate 1489d123abd9SMatthew G. Knepley 1490d123abd9SMatthew G. Knepley .seealso: DMLabelGetValueIndex(), DMLabelGetStratumIS(), DMLabelCreate() 1491d123abd9SMatthew G. Knepley @*/ 1492d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1493d123abd9SMatthew G. Knepley { 1494d123abd9SMatthew G. Knepley const PetscInt *indices; 1495d123abd9SMatthew G. Knepley PetscInt v; 1496d123abd9SMatthew G. Knepley 1497d123abd9SMatthew G. Knepley PetscFunctionBegin; 1498d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1499dadcf809SJacob Faibussowitsch PetscValidIntPointer(index, 4); 1500d123abd9SMatthew G. Knepley *index = -1; 15019566063dSJacob Faibussowitsch PetscCall(DMLabelLookupStratum(label, value, &v)); 1502d123abd9SMatthew G. Knepley if (v < 0) PetscFunctionReturn(0); 15039566063dSJacob Faibussowitsch PetscCall(DMLabelMakeValid_Private(label, v)); 15049566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[v], &indices)); 15059566063dSJacob Faibussowitsch PetscCall(PetscFindInt(p, label->stratumSizes[v], indices, index)); 15069566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[v], &indices)); 1507d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1508d123abd9SMatthew G. Knepley } 1509d123abd9SMatthew G. Knepley 1510d123abd9SMatthew G. Knepley /*@ 151184f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 151284f0b6dfSMatthew G. Knepley 15135b5e7992SMatthew G. Knepley Not collective 15145b5e7992SMatthew G. Knepley 151584f0b6dfSMatthew G. Knepley Input Parameters: 151684f0b6dfSMatthew G. Knepley + label - the DMLabel 151722cd2cdaSVaclav Hapla . start - the first point kept 151822cd2cdaSVaclav Hapla - end - one more than the last point kept 151984f0b6dfSMatthew G. Knepley 152084f0b6dfSMatthew G. Knepley Level: intermediate 152184f0b6dfSMatthew G. Knepley 152284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 152384f0b6dfSMatthew G. Knepley @*/ 1524c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1525c58f1c22SToby Isaac { 1526c58f1c22SToby Isaac PetscInt v; 1527c58f1c22SToby Isaac 1528c58f1c22SToby Isaac PetscFunctionBegin; 1529d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15309566063dSJacob Faibussowitsch PetscCall(DMLabelDestroyIndex(label)); 15319566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1532c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 15339566063dSJacob Faibussowitsch PetscCall(ISGeneralFilter(label->points[v], start, end)); 1534c58f1c22SToby Isaac } 15359566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, start, end)); 1536c58f1c22SToby Isaac PetscFunctionReturn(0); 1537c58f1c22SToby Isaac } 1538c58f1c22SToby Isaac 153984f0b6dfSMatthew G. Knepley /*@ 154084f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 154184f0b6dfSMatthew G. Knepley 15425b5e7992SMatthew G. Knepley Not collective 15435b5e7992SMatthew G. Knepley 154484f0b6dfSMatthew G. Knepley Input Parameters: 154584f0b6dfSMatthew G. Knepley + label - the DMLabel 154684f0b6dfSMatthew G. Knepley - permutation - the point permutation 154784f0b6dfSMatthew G. Knepley 154884f0b6dfSMatthew G. Knepley Output Parameter: 154984f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 155084f0b6dfSMatthew G. Knepley 155184f0b6dfSMatthew G. Knepley Level: intermediate 155284f0b6dfSMatthew G. Knepley 155384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 155484f0b6dfSMatthew G. Knepley @*/ 1555c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1556c58f1c22SToby Isaac { 1557c58f1c22SToby Isaac const PetscInt *perm; 1558c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1559c58f1c22SToby Isaac 1560c58f1c22SToby Isaac PetscFunctionBegin; 1561d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1562d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 15639566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 15649566063dSJacob Faibussowitsch PetscCall(DMLabelDuplicate(label, labelNew)); 15659566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(*labelNew, &numValues)); 15669566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(permutation, &numPoints)); 15679566063dSJacob Faibussowitsch PetscCall(ISGetIndices(permutation, &perm)); 1568c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1569c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1570ad8374ffSToby Isaac const PetscInt *points; 1571ad8374ffSToby Isaac PetscInt *pointsNew; 1572c58f1c22SToby Isaac 15739566063dSJacob Faibussowitsch PetscCall(ISGetIndices((*labelNew)->points[v],&points)); 15749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&pointsNew)); 1575c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1576ad8374ffSToby Isaac const PetscInt point = points[q]; 1577c58f1c22SToby Isaac 157808401ef6SPierre Jolivet PetscCheck(!(point < 0) && !(point >= numPoints),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [0, %D) for the remapping", point, numPoints); 1579ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1580c58f1c22SToby Isaac } 15819566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices((*labelNew)->points[v],&points)); 15829566063dSJacob Faibussowitsch PetscCall(PetscSortInt(size, pointsNew)); 15839566063dSJacob Faibussowitsch PetscCall(ISDestroy(&((*labelNew)->points[v]))); 1584fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 15859566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]))); 15869566063dSJacob Faibussowitsch PetscCall(PetscFree(pointsNew)); 1587fa8e8ae5SToby Isaac } else { 15889566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]))); 1589fa8e8ae5SToby Isaac } 15909566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices")); 1591c58f1c22SToby Isaac } 15929566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(permutation, &perm)); 1593c58f1c22SToby Isaac if (label->bt) { 15949566063dSJacob Faibussowitsch PetscCall(PetscBTDestroy(&label->bt)); 15959566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, label->pStart, label->pEnd)); 1596c58f1c22SToby Isaac } 1597c58f1c22SToby Isaac PetscFunctionReturn(0); 1598c58f1c22SToby Isaac } 1599c58f1c22SToby Isaac 160026c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 160126c55118SMichael Lange { 160226c55118SMichael Lange MPI_Comm comm; 1603eb30be1eSVaclav Hapla PetscInt s, l, nroots, nleaves, offset, size; 160426c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 160526c55118SMichael Lange PetscSection rootSection; 160626c55118SMichael Lange PetscSF labelSF; 160726c55118SMichael Lange 160826c55118SMichael Lange PetscFunctionBegin; 16099566063dSJacob Faibussowitsch if (label) PetscCall(DMLabelMakeAllValid_Private(label)); 16109566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 161126c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 161226c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 16139566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 16149566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, &rootSection)); 16159566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(rootSection, 0, nroots)); 161626c55118SMichael Lange if (label) { 161726c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1618ad8374ffSToby Isaac const PetscInt *points; 1619ad8374ffSToby Isaac 16209566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 162126c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1622eb30be1eSVaclav Hapla PetscCall(PetscSectionAddDof(rootSection, points[l], 1)); 162326c55118SMichael Lange } 16249566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 162526c55118SMichael Lange } 162626c55118SMichael Lange } 16279566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(rootSection)); 162826c55118SMichael Lange /* Create a point-wise array of stratum values */ 16299566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(rootSection, &size)); 16309566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &rootStrata)); 16319566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &rootIdx)); 163226c55118SMichael Lange if (label) { 163326c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1634ad8374ffSToby Isaac const PetscInt *points; 1635ad8374ffSToby Isaac 16369566063dSJacob Faibussowitsch PetscCall(ISGetIndices(label->points[s], &points)); 163726c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1638ad8374ffSToby Isaac const PetscInt p = points[l]; 16399566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, p, &offset)); 164026c55118SMichael Lange rootStrata[offset+rootIdx[p]++] = label->stratumValues[s]; 164126c55118SMichael Lange } 16429566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(label->points[s], &points)); 164326c55118SMichael Lange } 164426c55118SMichael Lange } 164526c55118SMichael Lange /* Build SF that maps label points to remote processes */ 16469566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(comm, leafSection)); 16479566063dSJacob Faibussowitsch PetscCall(PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection)); 16489566063dSJacob Faibussowitsch PetscCall(PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF)); 16499566063dSJacob Faibussowitsch PetscCall(PetscFree(remoteOffsets)); 165026c55118SMichael Lange /* Send the strata for each point over the derived SF */ 16519566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*leafSection, &size)); 16529566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, leafStrata)); 16539566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE)); 16549566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE)); 165526c55118SMichael Lange /* Clean up */ 16569566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 16579566063dSJacob Faibussowitsch PetscCall(PetscFree(rootIdx)); 16589566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 16599566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&labelSF)); 166026c55118SMichael Lange PetscFunctionReturn(0); 166126c55118SMichael Lange } 166226c55118SMichael Lange 166384f0b6dfSMatthew G. Knepley /*@ 166484f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 166584f0b6dfSMatthew G. Knepley 16665b5e7992SMatthew G. Knepley Collective on sf 16675b5e7992SMatthew G. Knepley 166884f0b6dfSMatthew G. Knepley Input Parameters: 166984f0b6dfSMatthew G. Knepley + label - the DMLabel 167084f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 167184f0b6dfSMatthew G. Knepley 167284f0b6dfSMatthew G. Knepley Output Parameter: 167384f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 167484f0b6dfSMatthew G. Knepley 167584f0b6dfSMatthew G. Knepley Level: intermediate 167684f0b6dfSMatthew G. Knepley 167784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 167884f0b6dfSMatthew G. Knepley @*/ 1679c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1680c58f1c22SToby Isaac { 1681c58f1c22SToby Isaac MPI_Comm comm; 168226c55118SMichael Lange PetscSection leafSection; 168326c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 168426c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1685ad8374ffSToby Isaac PetscInt **points; 1686d67d17b1SMatthew G. Knepley const char *lname = NULL; 1687c58f1c22SToby Isaac char *name; 1688c58f1c22SToby Isaac PetscInt nameSize; 1689e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1690c58f1c22SToby Isaac size_t len = 0; 169126c55118SMichael Lange PetscMPIInt rank; 1692c58f1c22SToby Isaac 1693c58f1c22SToby Isaac PetscFunctionBegin; 1694d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1695f018e600SMatthew G. Knepley if (label) { 1696f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 16979566063dSJacob Faibussowitsch PetscCall(DMLabelMakeAllValid_Private(label)); 1698f018e600SMatthew G. Knepley } 16999566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 17009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1701c58f1c22SToby Isaac /* Bcast name */ 1702dd400576SPatrick Sanan if (rank == 0) { 17039566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &lname)); 17049566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1705d67d17b1SMatthew G. Knepley } 1706c58f1c22SToby Isaac nameSize = len; 17079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 17089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize+1, &name)); 17099566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize+1)); 17109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm)); 17119566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 17129566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 171377d236dfSMichael Lange /* Bcast defaultValue */ 1714dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 17159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm)); 171626c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 17179566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata)); 17185cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 17199566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&stratumHash)); 17209566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(leafSection, &size)); 17219566063dSJacob Faibussowitsch for (p = 0; p < size; ++p) PetscCall(PetscHSetIAdd(stratumHash, leafStrata[p])); 17229566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata)); 17239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS)); 1724ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 17259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues)); 17265cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 17275cbdf6fcSMichael Lange offset = 0; 17289566063dSJacob Faibussowitsch PetscCall(PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues)); 17299566063dSJacob Faibussowitsch PetscCall(PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues)); 173090e9b2aeSLisandro Dalcin for (s = 0; s < (*labelNew)->numStrata; ++s) { 17319566063dSJacob Faibussowitsch PetscCall(PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s)); 173290e9b2aeSLisandro Dalcin } 17335cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1734231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 1735231b9e6fSMatthew G. Knepley if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;} 17365cbdf6fcSMichael Lange } 17375cbdf6fcSMichael Lange } 1738c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 17399566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes)); 17409566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1741c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 17429566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17439566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1744c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1745c58f1c22SToby Isaac (*labelNew)->stratumSizes[leafStrata[offset+s]]++; 1746c58f1c22SToby Isaac } 1747c58f1c22SToby Isaac } 17489566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht)); 17499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points)); 17509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->numStrata,&points)); 1751c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 17529566063dSJacob Faibussowitsch PetscCall(PetscHSetICreate(&(*labelNew)->ht[s])); 17539566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]))); 1754c58f1c22SToby Isaac } 1755c58f1c22SToby Isaac /* Insert points into new strata */ 17569566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((*labelNew)->numStrata, &strataIdx)); 17579566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(leafSection, &pStart, &pEnd)); 1758c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 17599566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(leafSection, p, &dof)); 17609566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(leafSection, p, &offset)); 1761c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1762c58f1c22SToby Isaac stratum = leafStrata[offset+s]; 1763ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1764c58f1c22SToby Isaac } 1765c58f1c22SToby Isaac } 1766ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 17679566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]))); 17689566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices")); 1769ad8374ffSToby Isaac } 17709566063dSJacob Faibussowitsch PetscCall(PetscFree(points)); 17719566063dSJacob Faibussowitsch PetscCall(PetscHSetIDestroy(&stratumHash)); 17729566063dSJacob Faibussowitsch PetscCall(PetscFree(leafStrata)); 17739566063dSJacob Faibussowitsch PetscCall(PetscFree(strataIdx)); 17749566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&leafSection)); 1775c58f1c22SToby Isaac PetscFunctionReturn(0); 1776c58f1c22SToby Isaac } 1777c58f1c22SToby Isaac 17787937d9ceSMichael Lange /*@ 17797937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 17807937d9ceSMichael Lange 17815b5e7992SMatthew G. Knepley Collective on sf 17825b5e7992SMatthew G. Knepley 17837937d9ceSMichael Lange Input Parameters: 17847937d9ceSMichael Lange + label - the DMLabel 178584f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 17867937d9ceSMichael Lange 178784f0b6dfSMatthew G. Knepley Output Parameters: 178884f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 17897937d9ceSMichael Lange 17907937d9ceSMichael Lange Level: developer 17917937d9ceSMichael Lange 17927937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 17937937d9ceSMichael Lange 17947937d9ceSMichael Lange .seealso: DMLabelDistribute() 17957937d9ceSMichael Lange @*/ 17967937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 17977937d9ceSMichael Lange { 17987937d9ceSMichael Lange MPI_Comm comm; 17997937d9ceSMichael Lange PetscSection rootSection; 18007937d9ceSMichael Lange PetscSF sfLabel; 18017937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 18027937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 18037937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 18047937d9ceSMichael Lange PetscInt *rootStrata; 1805d67d17b1SMatthew G. Knepley const char *lname; 18067937d9ceSMichael Lange char *name; 18077937d9ceSMichael Lange PetscInt nameSize; 18087937d9ceSMichael Lange size_t len = 0; 18099852e123SBarry Smith PetscMPIInt rank, size; 18107937d9ceSMichael Lange 18117937d9ceSMichael Lange PetscFunctionBegin; 1812d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1813d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 18149566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 18159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 18169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 18177937d9ceSMichael Lange /* Bcast name */ 1818dd400576SPatrick Sanan if (rank == 0) { 18199566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) label, &lname)); 18209566063dSJacob Faibussowitsch PetscCall(PetscStrlen(lname, &len)); 1821d67d17b1SMatthew G. Knepley } 18227937d9ceSMichael Lange nameSize = len; 18239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm)); 18249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nameSize+1, &name)); 18259566063dSJacob Faibussowitsch if (rank == 0) PetscCall(PetscArraycpy(name, lname, nameSize+1)); 18269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm)); 18279566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, name, labelNew)); 18289566063dSJacob Faibussowitsch PetscCall(PetscFree(name)); 18297937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 18307937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 18317937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 18329566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL)); 18339566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nroots, &leafPoints)); 1834dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 18357937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 18368212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 18378212dd46SStefano Zampini 18388212dd46SStefano Zampini leafPoints[ilp].index = ilp; 18398212dd46SStefano Zampini leafPoints[ilp].rank = rank; 18407937d9ceSMichael Lange } 18419566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeBegin(sf, &rootDegree)); 18429566063dSJacob Faibussowitsch PetscCall(PetscSFComputeDegreeEnd(sf, &rootDegree)); 18437937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 18449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nmultiroots, &rootPoints)); 18459566063dSJacob Faibussowitsch PetscCall(PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints)); 18469566063dSJacob Faibussowitsch PetscCall(PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints)); 18479566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(comm,& sfLabel)); 18489566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER)); 18497937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 18509566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata)); 18517937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 18527937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 18537937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 18549566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(rootSection, idx+d, &dof)); 18559566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(rootSection, idx+d, &offset)); 18569566063dSJacob Faibussowitsch for (s = 0; s < dof; s++) PetscCall(DMLabelSetValue(*labelNew, p, rootStrata[offset+s])); 18577937d9ceSMichael Lange } 18587937d9ceSMichael Lange idx += rootDegree[p]; 18597937d9ceSMichael Lange } 18609566063dSJacob Faibussowitsch PetscCall(PetscFree(leafPoints)); 18619566063dSJacob Faibussowitsch PetscCall(PetscFree(rootStrata)); 18629566063dSJacob Faibussowitsch PetscCall(PetscSectionDestroy(&rootSection)); 18639566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfLabel)); 18647937d9ceSMichael Lange PetscFunctionReturn(0); 18657937d9ceSMichael Lange } 18667937d9ceSMichael Lange 1867*d42890abSMatthew G. Knepley static PetscErrorCode DMLabelPropagateInit_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[]) 1868*d42890abSMatthew G. Knepley { 1869*d42890abSMatthew G. Knepley const PetscInt *degree; 1870*d42890abSMatthew G. Knepley const PetscInt *points; 1871*d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1872*d42890abSMatthew G. Knepley 1873*d42890abSMatthew G. Knepley PetscFunctionBegin; 1874*d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1875*d42890abSMatthew G. Knepley /* Add in leaves */ 1876*d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1877*d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1878*d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, points[l], &val)); 1879*d42890abSMatthew G. Knepley if (val != defVal) valArray[points[l]] = val; 1880*d42890abSMatthew G. Knepley } 1881*d42890abSMatthew G. Knepley /* Add in shared roots */ 1882*d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1883*d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1884*d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1885*d42890abSMatthew G. Knepley if (degree[r]) { 1886*d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1887*d42890abSMatthew G. Knepley if (val != defVal) valArray[r] = val; 1888*d42890abSMatthew G. Knepley } 1889*d42890abSMatthew G. Knepley } 1890*d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1891*d42890abSMatthew G. Knepley } 1892*d42890abSMatthew G. Knepley 1893*d42890abSMatthew G. Knepley static PetscErrorCode DMLabelPropagateFini_Internal(DMLabel label, PetscSF pointSF, PetscInt valArray[], PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 1894*d42890abSMatthew G. Knepley { 1895*d42890abSMatthew G. Knepley const PetscInt *degree; 1896*d42890abSMatthew G. Knepley const PetscInt *points; 1897*d42890abSMatthew G. Knepley PetscInt Nr, r, Nl, l, val, defVal; 1898*d42890abSMatthew G. Knepley 1899*d42890abSMatthew G. Knepley PetscFunctionBegin; 1900*d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1901*d42890abSMatthew G. Knepley /* Read out leaves */ 1902*d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(pointSF, &Nr, &Nl, &points, NULL)); 1903*d42890abSMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1904*d42890abSMatthew G. Knepley const PetscInt p = points[l]; 1905*d42890abSMatthew G. Knepley const PetscInt cval = valArray[p]; 1906*d42890abSMatthew G. Knepley 1907*d42890abSMatthew G. Knepley if (cval != defVal) { 1908*d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, p, &val)); 1909*d42890abSMatthew G. Knepley if (val == defVal) { 1910*d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, p, cval)); 1911*d42890abSMatthew G. Knepley if (markPoint) {PetscCall((*markPoint)(label, p, cval, ctx));} 1912*d42890abSMatthew G. Knepley } 1913*d42890abSMatthew G. Knepley } 1914*d42890abSMatthew G. Knepley } 1915*d42890abSMatthew G. Knepley /* Read out shared roots */ 1916*d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeBegin(pointSF, °ree)); 1917*d42890abSMatthew G. Knepley PetscCall(PetscSFComputeDegreeEnd(pointSF, °ree)); 1918*d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) { 1919*d42890abSMatthew G. Knepley if (degree[r]) { 1920*d42890abSMatthew G. Knepley const PetscInt cval = valArray[r]; 1921*d42890abSMatthew G. Knepley 1922*d42890abSMatthew G. Knepley if (cval != defVal) { 1923*d42890abSMatthew G. Knepley PetscCall(DMLabelGetValue(label, r, &val)); 1924*d42890abSMatthew G. Knepley if (val == defVal) { 1925*d42890abSMatthew G. Knepley PetscCall(DMLabelSetValue(label, r, cval)); 1926*d42890abSMatthew G. Knepley if (markPoint) {PetscCall((*markPoint)(label, r, cval, ctx));} 1927*d42890abSMatthew G. Knepley } 1928*d42890abSMatthew G. Knepley } 1929*d42890abSMatthew G. Knepley } 1930*d42890abSMatthew G. Knepley } 1931*d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1932*d42890abSMatthew G. Knepley } 1933*d42890abSMatthew G. Knepley 1934*d42890abSMatthew G. Knepley /*@ 1935*d42890abSMatthew G. Knepley DMLabelPropagateBegin - Setup a cycle of label propagation 1936*d42890abSMatthew G. Knepley 1937*d42890abSMatthew G. Knepley Collective on sf 1938*d42890abSMatthew G. Knepley 1939*d42890abSMatthew G. Knepley Input Parameters: 1940*d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1941*d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1942*d42890abSMatthew G. Knepley 1943*d42890abSMatthew G. Knepley Level: intermediate 1944*d42890abSMatthew G. Knepley 1945*d42890abSMatthew G. Knepley .seealso: DMLabelPropagateEnd(), DMLabelPropagatePush() 1946*d42890abSMatthew G. Knepley @*/ 1947*d42890abSMatthew G. Knepley PetscErrorCode DMLabelPropagateBegin(DMLabel label, PetscSF sf) 1948*d42890abSMatthew G. Knepley { 1949*d42890abSMatthew G. Knepley PetscInt Nr, r, defVal; 1950*d42890abSMatthew G. Knepley PetscMPIInt size; 1951*d42890abSMatthew G. Knepley 1952*d42890abSMatthew G. Knepley PetscFunctionBegin; 1953*d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) sf), &size)); 1954*d42890abSMatthew G. Knepley if (size > 1) { 1955*d42890abSMatthew G. Knepley PetscCall(DMLabelGetDefaultValue(label, &defVal)); 1956*d42890abSMatthew G. Knepley PetscCall(PetscSFGetGraph(sf, &Nr, NULL, NULL, NULL)); 1957*d42890abSMatthew G. Knepley if (Nr >= 0) PetscCall(PetscMalloc1(Nr, &label->propArray)); 1958*d42890abSMatthew G. Knepley for (r = 0; r < Nr; ++r) label->propArray[r] = defVal; 1959*d42890abSMatthew G. Knepley } 1960*d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1961*d42890abSMatthew G. Knepley } 1962*d42890abSMatthew G. Knepley 1963*d42890abSMatthew G. Knepley /*@ 1964*d42890abSMatthew G. Knepley DMLabelPropagateEnd - Tear down a cycle of label propagation 1965*d42890abSMatthew G. Knepley 1966*d42890abSMatthew G. Knepley Collective on sf 1967*d42890abSMatthew G. Knepley 1968*d42890abSMatthew G. Knepley Input Parameters: 1969*d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1970*d42890abSMatthew G. Knepley - sf - The SF describing parallel layout of the label points 1971*d42890abSMatthew G. Knepley 1972*d42890abSMatthew G. Knepley Level: intermediate 1973*d42890abSMatthew G. Knepley 1974*d42890abSMatthew G. Knepley .seealso: DMLabelPropagateBegin(), DMLabelPropagatePush() 1975*d42890abSMatthew G. Knepley @*/ 1976*d42890abSMatthew G. Knepley PetscErrorCode DMLabelPropagateEnd(DMLabel label, PetscSF pointSF) 1977*d42890abSMatthew G. Knepley { 1978*d42890abSMatthew G. Knepley PetscFunctionBegin; 1979*d42890abSMatthew G. Knepley PetscCall(PetscFree(label->propArray)); 1980*d42890abSMatthew G. Knepley label->propArray = NULL; 1981*d42890abSMatthew G. Knepley PetscFunctionReturn(0); 1982*d42890abSMatthew G. Knepley } 1983*d42890abSMatthew G. Knepley 1984*d42890abSMatthew G. Knepley /*@C 1985*d42890abSMatthew G. Knepley DMLabelPropagatePush - Tear down a cycle of label propagation 1986*d42890abSMatthew G. Knepley 1987*d42890abSMatthew G. Knepley Collective on sf 1988*d42890abSMatthew G. Knepley 1989*d42890abSMatthew G. Knepley Input Parameters: 1990*d42890abSMatthew G. Knepley + label - The DMLabel to propagate across processes 1991*d42890abSMatthew G. Knepley . sf - The SF describing parallel layout of the label points 1992*d42890abSMatthew G. Knepley . markPoint - An optional user callback that is called when a point is marked, or NULL 1993*d42890abSMatthew G. Knepley - ctx - An optional user context for the callback, or NULL 1994*d42890abSMatthew G. Knepley 1995*d42890abSMatthew G. Knepley Calling sequence of markPoint: 1996*d42890abSMatthew G. Knepley $ markPoint(DMLabel label, PetscInt p, PetscInt val, void *ctx); 1997*d42890abSMatthew G. Knepley 1998*d42890abSMatthew G. Knepley + label - The DMLabel 1999*d42890abSMatthew G. Knepley . p - The point being marked 2000*d42890abSMatthew G. Knepley . val - The label value for p 2001*d42890abSMatthew G. Knepley - ctx - An optional user context 2002*d42890abSMatthew G. Knepley 2003*d42890abSMatthew G. Knepley Level: intermediate 2004*d42890abSMatthew G. Knepley 2005*d42890abSMatthew G. Knepley .seealso: DMLabelPropagateBegin(), DMLabelPropagateEnd() 2006*d42890abSMatthew G. Knepley @*/ 2007*d42890abSMatthew G. Knepley PetscErrorCode DMLabelPropagatePush(DMLabel label, PetscSF pointSF, PetscErrorCode (*markPoint)(DMLabel, PetscInt, PetscInt, void *), void *ctx) 2008*d42890abSMatthew G. Knepley { 2009*d42890abSMatthew G. Knepley PetscInt *valArray = label->propArray; 2010*d42890abSMatthew G. Knepley PetscMPIInt size; 2011*d42890abSMatthew G. Knepley 2012*d42890abSMatthew G. Knepley PetscFunctionBegin; 2013*d42890abSMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) pointSF), &size)); 2014*d42890abSMatthew G. Knepley if (size > 1) { 2015*d42890abSMatthew G. Knepley /* Communicate marked edges 2016*d42890abSMatthew G. Knepley The current implementation allocates an array the size of the number of root. We put the label values into the 2017*d42890abSMatthew G. Knepley array, and then call PetscSFReduce()+PetscSFBcast() to make the marks consistent. 2018*d42890abSMatthew G. Knepley 2019*d42890abSMatthew G. Knepley TODO: We could use in-place communication with a different SF 2020*d42890abSMatthew G. Knepley We use MPI_SUM for the Reduce, and check the result against the rootdegree. If sum >= rootdegree+1, then the edge has 2021*d42890abSMatthew G. Knepley already been marked. If not, it might have been handled on the process in this round, but we add it anyway. 2022*d42890abSMatthew G. Knepley 2023*d42890abSMatthew G. Knepley In order to update the queue with the new edges from the label communication, we use BcastAnOp(MPI_SUM), so that new 2024*d42890abSMatthew 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 2025*d42890abSMatthew G. Knepley edge to the queue. 2026*d42890abSMatthew G. Knepley */ 2027*d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateInit_Internal(label, pointSF, valArray)); 2028*d42890abSMatthew G. Knepley PetscCall(PetscSFReduceBegin(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2029*d42890abSMatthew G. Knepley PetscCall(PetscSFReduceEnd(pointSF, MPIU_INT, valArray, valArray, MPI_MAX)); 2030*d42890abSMatthew G. Knepley PetscCall(PetscSFBcastBegin(pointSF, MPIU_INT, valArray, valArray,MPI_REPLACE)); 2031*d42890abSMatthew G. Knepley PetscCall(PetscSFBcastEnd(pointSF, MPIU_INT, valArray, valArray,MPI_REPLACE)); 2032*d42890abSMatthew G. Knepley PetscCall(DMLabelPropagateFini_Internal(label, pointSF, valArray, markPoint, ctx)); 2033*d42890abSMatthew G. Knepley } 2034*d42890abSMatthew G. Knepley PetscFunctionReturn(0); 2035*d42890abSMatthew G. Knepley } 2036*d42890abSMatthew G. Knepley 203784f0b6dfSMatthew G. Knepley /*@ 203884f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 203984f0b6dfSMatthew G. Knepley 20405b5e7992SMatthew G. Knepley Not collective 20415b5e7992SMatthew G. Knepley 204284f0b6dfSMatthew G. Knepley Input Parameter: 204384f0b6dfSMatthew G. Knepley . label - the DMLabel 204484f0b6dfSMatthew G. Knepley 204584f0b6dfSMatthew G. Knepley Output Parameters: 204684f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 204784f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 204884f0b6dfSMatthew G. Knepley 204984f0b6dfSMatthew G. Knepley Level: developer 205084f0b6dfSMatthew G. Knepley 205184f0b6dfSMatthew G. Knepley .seealso: DMLabelDistribute() 205284f0b6dfSMatthew G. Knepley @*/ 2053c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 2054c58f1c22SToby Isaac { 2055c58f1c22SToby Isaac IS vIS; 2056c58f1c22SToby Isaac const PetscInt *values; 2057c58f1c22SToby Isaac PetscInt *points; 2058c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 2059c58f1c22SToby Isaac 2060c58f1c22SToby Isaac PetscFunctionBegin; 2061d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 20629566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label, &nV)); 20639566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(label, &vIS)); 20649566063dSJacob Faibussowitsch PetscCall(ISGetIndices(vIS, &values)); 2065c58f1c22SToby Isaac if (nV) {vS = values[0]; vE = values[0]+1;} 2066c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 2067c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 2068c58f1c22SToby Isaac vE = PetscMax(vE, values[v]+1); 2069c58f1c22SToby Isaac } 20709566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PETSC_COMM_SELF, section)); 20719566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*section, vS, vE)); 2072c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2073c58f1c22SToby Isaac PetscInt n; 2074c58f1c22SToby Isaac 20759566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumSize(label, values[v], &n)); 20769566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*section, values[v], n)); 2077c58f1c22SToby Isaac } 20789566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUp(*section)); 20799566063dSJacob Faibussowitsch PetscCall(PetscSectionGetStorageSize(*section, &N)); 20809566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(N, &points)); 2081c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 2082c58f1c22SToby Isaac IS is; 2083c58f1c22SToby Isaac const PetscInt *spoints; 2084c58f1c22SToby Isaac PetscInt dof, off, p; 2085c58f1c22SToby Isaac 20869566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(*section, values[v], &dof)); 20879566063dSJacob Faibussowitsch PetscCall(PetscSectionGetOffset(*section, values[v], &off)); 20889566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(label, values[v], &is)); 20899566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &spoints)); 2090c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; 20919566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &spoints)); 20929566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 2093c58f1c22SToby Isaac } 20949566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(vIS, &values)); 20959566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vIS)); 20969566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is)); 2097c58f1c22SToby Isaac PetscFunctionReturn(0); 2098c58f1c22SToby Isaac } 2099c58f1c22SToby Isaac 210084f0b6dfSMatthew G. Knepley /*@ 2101c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 2102c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 2103c58f1c22SToby Isaac 21045b5e7992SMatthew G. Knepley Collective on sf 21055b5e7992SMatthew G. Knepley 2106c58f1c22SToby Isaac Input Parameters: 2107c58f1c22SToby Isaac + s - The PetscSection for the local field layout 2108c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 2109c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 2110c58f1c22SToby Isaac . label - The label specifying the points 2111c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 2112c58f1c22SToby Isaac 2113c58f1c22SToby Isaac Output Parameter: 2114c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 2115c58f1c22SToby Isaac 2116c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 2117c58f1c22SToby Isaac 2118c58f1c22SToby Isaac Level: developer 2119c58f1c22SToby Isaac 2120c58f1c22SToby Isaac .seealso: PetscSectionCreate() 2121c58f1c22SToby Isaac @*/ 2122c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2123c58f1c22SToby Isaac { 2124c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2125c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2126c58f1c22SToby Isaac 2127c58f1c22SToby Isaac PetscFunctionBegin; 2128d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2129d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2130d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 21319566063dSJacob Faibussowitsch PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection)); 21329566063dSJacob Faibussowitsch PetscCall(PetscSectionGetChart(s, &pStart, &pEnd)); 21339566063dSJacob Faibussowitsch PetscCall(PetscSectionSetChart(*gsection, pStart, pEnd)); 21349566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL)); 2135c58f1c22SToby Isaac if (nroots >= 0) { 213608401ef6SPierre Jolivet PetscCheck(nroots >= pEnd-pStart,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart); 21379566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &neg)); 2138c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 21399566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nroots, &tmpOff)); 2140c58f1c22SToby Isaac } else { 2141c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2142c58f1c22SToby Isaac } 2143c58f1c22SToby Isaac } 2144c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2145c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2146c58f1c22SToby Isaac PetscInt value; 2147c58f1c22SToby Isaac 21489566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &value)); 2149c58f1c22SToby Isaac if (value != labelValue) continue; 21509566063dSJacob Faibussowitsch PetscCall(PetscSectionGetDof(s, p, &dof)); 21519566063dSJacob Faibussowitsch PetscCall(PetscSectionSetDof(*gsection, p, dof)); 21529566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstraintDof(s, p, &cdof)); 21539566063dSJacob Faibussowitsch if (!includeConstraints && cdof > 0) PetscCall(PetscSectionSetConstraintDof(*gsection, p, cdof)); 2154c58f1c22SToby Isaac if (neg) neg[p] = -(dof+1); 2155c58f1c22SToby Isaac } 21569566063dSJacob Faibussowitsch PetscCall(PetscSectionSetUpBC(*gsection)); 2157c58f1c22SToby Isaac if (nroots >= 0) { 21589566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 21599566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 2160c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 2161c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 2162c58f1c22SToby Isaac } 2163c58f1c22SToby Isaac } 2164c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 2165c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 2166c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2167c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2168c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 2169c58f1c22SToby Isaac } 21709566063dSJacob Faibussowitsch PetscCallMPI(MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s))); 2171c58f1c22SToby Isaac globalOff -= off; 2172c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 2173c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2174c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 2175c58f1c22SToby Isaac } 2176c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2177c58f1c22SToby Isaac if (nroots >= 0) { 21789566063dSJacob Faibussowitsch PetscCall(PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 21799566063dSJacob Faibussowitsch PetscCall(PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE)); 2180c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 2181c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 2182c58f1c22SToby Isaac } 2183c58f1c22SToby Isaac } 21849566063dSJacob Faibussowitsch if (nroots >= 0 && nroots > pEnd-pStart) PetscCall(PetscFree(tmpOff)); 21859566063dSJacob Faibussowitsch PetscCall(PetscFree(neg)); 2186c58f1c22SToby Isaac PetscFunctionReturn(0); 2187c58f1c22SToby Isaac } 2188c58f1c22SToby Isaac 21895fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label 21905fdea053SToby Isaac { 21915fdea053SToby Isaac DMLabel label; 21925fdea053SToby Isaac PetscCopyMode *modes; 21935fdea053SToby Isaac PetscInt *sizes; 21945fdea053SToby Isaac const PetscInt ***perms; 21955fdea053SToby Isaac const PetscScalar ***rots; 21965fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 21975fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 21985fdea053SToby Isaac } PetscSectionSym_Label; 21995fdea053SToby Isaac 22005fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 22015fdea053SToby Isaac { 22025fdea053SToby Isaac PetscInt i, j; 22035fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 22045fdea053SToby Isaac 22055fdea053SToby Isaac PetscFunctionBegin; 22065fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22075fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 22085fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 22099566063dSJacob Faibussowitsch if (sl->perms[i]) PetscCall(PetscFree(sl->perms[i][j])); 22109566063dSJacob Faibussowitsch if (sl->rots[i]) PetscCall(PetscFree(sl->rots[i][j])); 22115fdea053SToby Isaac } 22125fdea053SToby Isaac if (sl->perms[i]) { 22135fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 22145fdea053SToby Isaac 22159566063dSJacob Faibussowitsch PetscCall(PetscFree(perms)); 22165fdea053SToby Isaac } 22175fdea053SToby Isaac if (sl->rots[i]) { 22185fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 22195fdea053SToby Isaac 22209566063dSJacob Faibussowitsch PetscCall(PetscFree(rots)); 22215fdea053SToby Isaac } 22225fdea053SToby Isaac } 22235fdea053SToby Isaac } 22249566063dSJacob Faibussowitsch PetscCall(PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients)); 22259566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&sl->label)); 22265fdea053SToby Isaac sl->numStrata = 0; 22275fdea053SToby Isaac PetscFunctionReturn(0); 22285fdea053SToby Isaac } 22295fdea053SToby Isaac 22305fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 22315fdea053SToby Isaac { 22325fdea053SToby Isaac PetscFunctionBegin; 22339566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelReset(sym)); 22349566063dSJacob Faibussowitsch PetscCall(PetscFree(sym->data)); 22355fdea053SToby Isaac PetscFunctionReturn(0); 22365fdea053SToby Isaac } 22375fdea053SToby Isaac 22385fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 22395fdea053SToby Isaac { 22405fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 22415fdea053SToby Isaac PetscBool isAscii; 22425fdea053SToby Isaac DMLabel label = sl->label; 2243d67d17b1SMatthew G. Knepley const char *name; 22445fdea053SToby Isaac 22455fdea053SToby Isaac PetscFunctionBegin; 22469566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii)); 22475fdea053SToby Isaac if (isAscii) { 22485fdea053SToby Isaac PetscInt i, j, k; 22495fdea053SToby Isaac PetscViewerFormat format; 22505fdea053SToby Isaac 22519566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 22525fdea053SToby Isaac if (label) { 22539566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 22545fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22569566063dSJacob Faibussowitsch PetscCall(DMLabelView(label, viewer)); 22579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 22585fdea053SToby Isaac } else { 22599566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sl->label, &name)); 22609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Label '%s'\n",name)); 22615fdea053SToby Isaac } 22625fdea053SToby Isaac } else { 22639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "No label given\n")); 22645fdea053SToby Isaac } 22659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22665fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22675fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 22685fdea053SToby Isaac 22695fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 22709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point): no symmetries\n", value, sl->sizes[i])); 22715fdea053SToby Isaac } else { 22729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point):\n", value, sl->sizes[i])); 22739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation range: [%D, %D)\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1])); 22755fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 22769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22775fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 22785fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 22799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %D: identity\n",j)); 22805fdea053SToby Isaac } else { 22815fdea053SToby Isaac PetscInt tab; 22825fdea053SToby Isaac 22839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Orientation %D:\n",j)); 22849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 22859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer,&tab)); 22865fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 22879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Permutation:")); 22889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,0)); 22899566063dSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer," %D",sl->perms[i][j][k])); 22909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 22919566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,tab)); 22925fdea053SToby Isaac } 22935fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 22949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Rotations: ")); 22959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,0)); 22965fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 22979566063dSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer," %+f+i*%+f",PetscRealPart(sl->rots[i][j][k]),PetscImaginaryPart(sl->rots[i][j][k]))); 22985fdea053SToby Isaac #else 22999566063dSJacob Faibussowitsch for (k = 0; k < sl->sizes[i]; k++) PetscCall(PetscViewerASCIIPrintf(viewer," %+f",sl->rots[i][j][k])); 23005fdea053SToby Isaac #endif 23019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 23029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,tab)); 23035fdea053SToby Isaac } 23049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23055fdea053SToby Isaac } 23065fdea053SToby Isaac } 23079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23085fdea053SToby Isaac } 23099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23105fdea053SToby Isaac } 23115fdea053SToby Isaac } 23129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 23135fdea053SToby Isaac } 23145fdea053SToby Isaac PetscFunctionReturn(0); 23155fdea053SToby Isaac } 23165fdea053SToby Isaac 23175fdea053SToby Isaac /*@ 23185fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 23195fdea053SToby Isaac 23205fdea053SToby Isaac Logically collective on sym 23215fdea053SToby Isaac 23225fdea053SToby Isaac Input parameters: 23235fdea053SToby Isaac + sym - the section symmetries 23245fdea053SToby Isaac - label - the DMLabel describing the types of points 23255fdea053SToby Isaac 23265fdea053SToby Isaac Level: developer: 23275fdea053SToby Isaac 23285fdea053SToby Isaac .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreateLabel(), PetscSectionGetPointSyms() 23295fdea053SToby Isaac @*/ 23305fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 23315fdea053SToby Isaac { 23325fdea053SToby Isaac PetscSectionSym_Label *sl; 23335fdea053SToby Isaac 23345fdea053SToby Isaac PetscFunctionBegin; 23355fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 23365fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 23379566063dSJacob Faibussowitsch if (sl->label && sl->label != label) PetscCall(PetscSectionSymLabelReset(sym)); 23385fdea053SToby Isaac if (label) { 23395fdea053SToby Isaac sl->label = label; 23409566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) label)); 23419566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(label,&sl->numStrata)); 23429566063dSJacob 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)); 23439566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode))); 23449566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt))); 23459566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **))); 23469566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **))); 23479566063dSJacob Faibussowitsch PetscCall(PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]))); 23485fdea053SToby Isaac } 23495fdea053SToby Isaac PetscFunctionReturn(0); 23505fdea053SToby Isaac } 23515fdea053SToby Isaac 23525fdea053SToby Isaac /*@C 2353b004864fSMatthew G. Knepley PetscSectionSymLabelGetStratum - get the symmetries for the orientations of a stratum 2354b004864fSMatthew G. Knepley 2355b004864fSMatthew G. Knepley Logically collective on sym 2356b004864fSMatthew G. Knepley 2357b004864fSMatthew G. Knepley Input Parameters: 2358b004864fSMatthew G. Knepley + sym - the section symmetries 2359b004864fSMatthew G. Knepley - stratum - the stratum value in the label that we are assigning symmetries for 2360b004864fSMatthew G. Knepley 2361b004864fSMatthew G. Knepley Output Parameters: 2362b004864fSMatthew G. Knepley + size - the number of dofs for points in the stratum of the label 2363b004864fSMatthew G. Knepley . minOrient - the smallest orientation for a point in this stratum 2364b004864fSMatthew G. Knepley . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 2365b004864fSMatthew G. Knepley . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2366b004864fSMatthew 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 2367b004864fSMatthew G. Knepley 2368b004864fSMatthew G. Knepley Level: developer 2369b004864fSMatthew G. Knepley 2370b004864fSMatthew G. Knepley .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel() 2371b004864fSMatthew G. Knepley @*/ 2372b004864fSMatthew G. Knepley PetscErrorCode PetscSectionSymLabelGetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt *size, PetscInt *minOrient, PetscInt *maxOrient, const PetscInt ***perms, const PetscScalar ***rots) 2373b004864fSMatthew G. Knepley { 2374b004864fSMatthew G. Knepley PetscSectionSym_Label *sl; 2375b004864fSMatthew G. Knepley const char *name; 2376b004864fSMatthew G. Knepley PetscInt i; 2377b004864fSMatthew G. Knepley 2378b004864fSMatthew G. Knepley PetscFunctionBegin; 2379b004864fSMatthew G. Knepley PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 2380b004864fSMatthew G. Knepley sl = (PetscSectionSym_Label *) sym->data; 2381b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 2382b004864fSMatthew G. Knepley for (i = 0; i <= sl->numStrata; i++) { 2383b004864fSMatthew G. Knepley PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 2384b004864fSMatthew G. Knepley 2385b004864fSMatthew G. Knepley if (stratum == value) break; 2386b004864fSMatthew G. Knepley } 23879566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sl->label, &name)); 2388b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %" PetscInt_FMT " not found in label %s", stratum, name); 2389b004864fSMatthew G. Knepley if (size) {PetscValidIntPointer(size, 3); *size = sl->sizes[i];} 2390b004864fSMatthew G. Knepley if (minOrient) {PetscValidIntPointer(minOrient, 4); *minOrient = sl->minMaxOrients[i][0];} 2391b004864fSMatthew G. Knepley if (maxOrient) {PetscValidIntPointer(maxOrient, 5); *maxOrient = sl->minMaxOrients[i][1];} 2392b004864fSMatthew G. Knepley if (perms) {PetscValidPointer(perms, 6); *perms = sl->perms[i] ? &sl->perms[i][sl->minMaxOrients[i][0]] : NULL;} 2393b004864fSMatthew G. Knepley if (rots) {PetscValidPointer(rots, 7); *rots = sl->rots[i] ? &sl->rots[i][sl->minMaxOrients[i][0]] : NULL;} 2394b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2395b004864fSMatthew G. Knepley } 2396b004864fSMatthew G. Knepley 2397b004864fSMatthew G. Knepley /*@C 23985fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 23995fdea053SToby Isaac 24005b5e7992SMatthew G. Knepley Logically collective on sym 24015fdea053SToby Isaac 24025fdea053SToby Isaac InputParameters: 24035b5e7992SMatthew G. Knepley + sym - the section symmetries 24045fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 24055fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 24065fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 24075fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 24085fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 24095fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2410a2b725a8SWilliam 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 24115fdea053SToby Isaac 24125fdea053SToby Isaac Level: developer 24135fdea053SToby Isaac 2414b004864fSMatthew G. Knepley .seealso: PetscSectionSymLabelGetStratum(), PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel() 24155fdea053SToby Isaac @*/ 24165fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 24175fdea053SToby Isaac { 24185fdea053SToby Isaac PetscSectionSym_Label *sl; 2419d67d17b1SMatthew G. Knepley const char *name; 2420d67d17b1SMatthew G. Knepley PetscInt i, j, k; 24215fdea053SToby Isaac 24225fdea053SToby Isaac PetscFunctionBegin; 24235fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 24245fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 2425b004864fSMatthew G. Knepley PetscCheck(sl->label, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_WRONGSTATE, "No label set yet"); 24265fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 24275fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 24285fdea053SToby Isaac 24295fdea053SToby Isaac if (stratum == value) break; 24305fdea053SToby Isaac } 24319566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject) sl->label, &name)); 2432b004864fSMatthew G. Knepley PetscCheck(i <= sl->numStrata, PetscObjectComm((PetscObject) sym), PETSC_ERR_ARG_OUTOFRANGE, "Stratum %D not found in label %s", stratum, name); 24335fdea053SToby Isaac sl->sizes[i] = size; 24345fdea053SToby Isaac sl->modes[i] = mode; 24355fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 24365fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 24375fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 24385fdea053SToby Isaac if (perms) { 24395fdea053SToby Isaac PetscInt **ownPerms; 24405fdea053SToby Isaac 24419566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient,&ownPerms)); 24425fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 24435fdea053SToby Isaac if (perms[j]) { 24449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&ownPerms[j])); 24455fdea053SToby Isaac for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];} 24465fdea053SToby Isaac } 24475fdea053SToby Isaac } 24485fdea053SToby Isaac sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient]; 24495fdea053SToby Isaac } 24505fdea053SToby Isaac if (rots) { 24515fdea053SToby Isaac PetscScalar **ownRots; 24525fdea053SToby Isaac 24539566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(maxOrient - minOrient,&ownRots)); 24545fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 24555fdea053SToby Isaac if (rots[j]) { 24569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&ownRots[j])); 24575fdea053SToby Isaac for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];} 24585fdea053SToby Isaac } 24595fdea053SToby Isaac } 24605fdea053SToby Isaac sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient]; 24615fdea053SToby Isaac } 24625fdea053SToby Isaac } else { 24635fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 24645fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 24655fdea053SToby Isaac } 24665fdea053SToby Isaac PetscFunctionReturn(0); 24675fdea053SToby Isaac } 24685fdea053SToby Isaac 24695fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 24705fdea053SToby Isaac { 24715fdea053SToby Isaac PetscInt i, j, numStrata; 24725fdea053SToby Isaac PetscSectionSym_Label *sl; 24735fdea053SToby Isaac DMLabel label; 24745fdea053SToby Isaac 24755fdea053SToby Isaac PetscFunctionBegin; 24765fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 24775fdea053SToby Isaac numStrata = sl->numStrata; 24785fdea053SToby Isaac label = sl->label; 24795fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 24805fdea053SToby Isaac PetscInt point = points[2*i]; 24815fdea053SToby Isaac PetscInt ornt = points[2*i+1]; 24825fdea053SToby Isaac 24835fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 24845fdea053SToby Isaac if (label->validIS[j]) { 24855fdea053SToby Isaac PetscInt k; 24865fdea053SToby Isaac 24879566063dSJacob Faibussowitsch PetscCall(ISLocate(label->points[j],point,&k)); 24885fdea053SToby Isaac if (k >= 0) break; 24895fdea053SToby Isaac } else { 24905fdea053SToby Isaac PetscBool has; 24915fdea053SToby Isaac 24929566063dSJacob Faibussowitsch PetscCall(PetscHSetIHas(label->ht[j], point, &has)); 24935fdea053SToby Isaac if (has) break; 24945fdea053SToby Isaac } 24955fdea053SToby Isaac } 249608401ef6SPierre Jolivet 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 %D orientation %D not in range [%D, %D) for stratum %D",point,ornt,sl->minMaxOrients[j][0],sl->minMaxOrients[j][1],j < numStrata ? label->stratumValues[j] : label->defaultValue); 24975fdea053SToby Isaac if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;} 24985fdea053SToby Isaac if (rots) {rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL;} 24995fdea053SToby Isaac } 25005fdea053SToby Isaac PetscFunctionReturn(0); 25015fdea053SToby Isaac } 25025fdea053SToby Isaac 2503b004864fSMatthew G. Knepley static PetscErrorCode PetscSectionSymCopy_Label(PetscSectionSym sym, PetscSectionSym nsym) 2504b004864fSMatthew G. Knepley { 2505b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *) nsym->data; 2506b004864fSMatthew G. Knepley IS valIS; 2507b004864fSMatthew G. Knepley const PetscInt *values; 2508b004864fSMatthew G. Knepley PetscInt Nv, v; 2509b004864fSMatthew G. Knepley 2510b004864fSMatthew G. Knepley PetscFunctionBegin; 25119566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(sl->label, &Nv)); 25129566063dSJacob Faibussowitsch PetscCall(DMLabelGetValueIS(sl->label, &valIS)); 25139566063dSJacob Faibussowitsch PetscCall(ISGetIndices(valIS, &values)); 2514b004864fSMatthew G. Knepley for (v = 0; v < Nv; ++v) { 2515b004864fSMatthew G. Knepley const PetscInt val = values[v]; 2516b004864fSMatthew G. Knepley PetscInt size, minOrient, maxOrient; 2517b004864fSMatthew G. Knepley const PetscInt **perms; 2518b004864fSMatthew G. Knepley const PetscScalar **rots; 2519b004864fSMatthew G. Knepley 25209566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelGetStratum(sym, val, &size, &minOrient, &maxOrient, &perms, &rots)); 25219566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetStratum(nsym, val, size, minOrient, maxOrient, PETSC_COPY_VALUES, perms, rots)); 2522b004864fSMatthew G. Knepley } 25239566063dSJacob Faibussowitsch PetscCall(ISDestroy(&valIS)); 2524b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2525b004864fSMatthew G. Knepley } 2526b004864fSMatthew G. Knepley 2527b004864fSMatthew G. Knepley static PetscErrorCode PetscSectionSymDistribute_Label(PetscSectionSym sym, PetscSF migrationSF, PetscSectionSym *dsym) 2528b004864fSMatthew G. Knepley { 2529b004864fSMatthew G. Knepley PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 2530b004864fSMatthew G. Knepley DMLabel dlabel; 2531b004864fSMatthew G. Knepley 2532b004864fSMatthew G. Knepley PetscFunctionBegin; 25339566063dSJacob Faibussowitsch PetscCall(DMLabelDistribute(sl->label, migrationSF, &dlabel)); 25349566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreateLabel(PetscObjectComm((PetscObject) sym), dlabel, dsym)); 25359566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&dlabel)); 25369566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCopy(sym, *dsym)); 2537b004864fSMatthew G. Knepley PetscFunctionReturn(0); 2538b004864fSMatthew G. Knepley } 2539b004864fSMatthew G. Knepley 25405fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 25415fdea053SToby Isaac { 25425fdea053SToby Isaac PetscSectionSym_Label *sl; 25435fdea053SToby Isaac 25445fdea053SToby Isaac PetscFunctionBegin; 25459566063dSJacob Faibussowitsch PetscCall(PetscNewLog(sym,&sl)); 25465fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 2547b004864fSMatthew G. Knepley sym->ops->distribute = PetscSectionSymDistribute_Label; 2548b004864fSMatthew G. Knepley sym->ops->copy = PetscSectionSymCopy_Label; 25495fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 25505fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 25515fdea053SToby Isaac sym->data = (void *) sl; 25525fdea053SToby Isaac PetscFunctionReturn(0); 25535fdea053SToby Isaac } 25545fdea053SToby Isaac 25555fdea053SToby Isaac /*@ 25565fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 25575fdea053SToby Isaac 25585fdea053SToby Isaac Collective 25595fdea053SToby Isaac 25605fdea053SToby Isaac Input Parameters: 25615fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 25625fdea053SToby Isaac - label - the label defining the strata 25635fdea053SToby Isaac 25645fdea053SToby Isaac Output Parameters: 25655fdea053SToby Isaac . sym - the section symmetries 25665fdea053SToby Isaac 25675fdea053SToby Isaac Level: developer 25685fdea053SToby Isaac 25695fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym(), PetscSectionSymLabelSetStratum(), PetscSectionGetPointSyms() 25705fdea053SToby Isaac @*/ 25715fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 25725fdea053SToby Isaac { 25735fdea053SToby Isaac PetscFunctionBegin; 25749566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 25759566063dSJacob Faibussowitsch PetscCall(PetscSectionSymCreate(comm,sym)); 25769566063dSJacob Faibussowitsch PetscCall(PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL)); 25779566063dSJacob Faibussowitsch PetscCall(PetscSectionSymLabelSetLabel(*sym,label)); 25785fdea053SToby Isaac PetscFunctionReturn(0); 25795fdea053SToby Isaac } 2580