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 PetscErrorCode ierr; 30c58f1c22SToby Isaac 31c58f1c22SToby Isaac PetscFunctionBegin; 32064a246eSJacob Faibussowitsch PetscValidPointer(label,3); 33d67d17b1SMatthew G. Knepley ierr = DMInitializePackage();CHKERRQ(ierr); 34c58f1c22SToby Isaac 35d67d17b1SMatthew G. Knepley ierr = PetscHeaderCreate(*label,DMLABEL_CLASSID,"DMLabel","DMLabel","DM",comm,DMLabelDestroy,DMLabelView);CHKERRQ(ierr); 36d67d17b1SMatthew G. Knepley 37c58f1c22SToby Isaac (*label)->numStrata = 0; 385aa44df4SToby Isaac (*label)->defaultValue = -1; 39c58f1c22SToby Isaac (*label)->stratumValues = NULL; 40ad8374ffSToby Isaac (*label)->validIS = NULL; 41c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 42c58f1c22SToby Isaac (*label)->points = NULL; 43c58f1c22SToby Isaac (*label)->ht = NULL; 44c58f1c22SToby Isaac (*label)->pStart = -1; 45c58f1c22SToby Isaac (*label)->pEnd = -1; 46c58f1c22SToby Isaac (*label)->bt = NULL; 47b9907514SLisandro Dalcin ierr = PetscHMapICreate(&(*label)->hmap);CHKERRQ(ierr); 48d67d17b1SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *label, name);CHKERRQ(ierr); 49c58f1c22SToby Isaac PetscFunctionReturn(0); 50c58f1c22SToby Isaac } 51c58f1c22SToby Isaac 52c58f1c22SToby Isaac /* 53c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 54c58f1c22SToby Isaac 555b5e7992SMatthew G. Knepley Not collective 565b5e7992SMatthew G. Knepley 57c58f1c22SToby Isaac Input parameter: 58c58f1c22SToby Isaac + label - The DMLabel 59c58f1c22SToby Isaac - v - The stratum value 60c58f1c22SToby Isaac 61c58f1c22SToby Isaac Output parameter: 62c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format 63c58f1c22SToby Isaac 64c58f1c22SToby Isaac Level: developer 65c58f1c22SToby Isaac 66c58f1c22SToby Isaac .seealso: DMLabelCreate() 67c58f1c22SToby Isaac */ 68c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) 69c58f1c22SToby Isaac { 70277ea44aSLisandro Dalcin IS is; 71b9907514SLisandro Dalcin PetscInt off = 0, *pointArray, p; 72c58f1c22SToby Isaac PetscErrorCode ierr; 73c58f1c22SToby Isaac 74b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) return 0; 75c58f1c22SToby Isaac PetscFunctionBegin; 760c3c4a36SLisandro Dalcin if (v < 0 || v >= label->numStrata) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D in DMLabelMakeValid_Private\n", v); 77e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v]);CHKERRQ(ierr); 78ad8374ffSToby Isaac ierr = PetscMalloc1(label->stratumSizes[v], &pointArray);CHKERRQ(ierr); 79e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(label->ht[v], &off, pointArray);CHKERRQ(ierr); 80b9907514SLisandro Dalcin ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr); 81ad8374ffSToby Isaac ierr = PetscSortInt(label->stratumSizes[v], pointArray);CHKERRQ(ierr); 82c58f1c22SToby Isaac if (label->bt) { 83c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 84ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 85c58f1c22SToby Isaac if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 86c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 87c58f1c22SToby Isaac } 88c58f1c22SToby Isaac } 89ba2698f1SMatthew G. Knepley if (label->stratumSizes[v] > 0 && pointArray[label->stratumSizes[v]-1] == pointArray[0] + label->stratumSizes[v]-1) { 90ba2698f1SMatthew G. Knepley ierr = ISCreateStride(PETSC_COMM_SELF, label->stratumSizes[v], pointArray[0], 1, &is);CHKERRQ(ierr); 91ba2698f1SMatthew G. Knepley ierr = PetscFree(pointArray);CHKERRQ(ierr); 92ba2698f1SMatthew G. Knepley } else { 93277ea44aSLisandro Dalcin ierr = ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is);CHKERRQ(ierr); 94ba2698f1SMatthew G. Knepley } 95277ea44aSLisandro Dalcin ierr = PetscObjectSetName((PetscObject) is, "indices");CHKERRQ(ierr); 96277ea44aSLisandro Dalcin label->points[v] = is; 97ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 98d67d17b1SMatthew G. Knepley ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 99c58f1c22SToby Isaac PetscFunctionReturn(0); 100c58f1c22SToby Isaac } 101c58f1c22SToby Isaac 102c58f1c22SToby Isaac /* 103c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 104c58f1c22SToby Isaac 1055b5e7992SMatthew G. Knepley Not collective 1065b5e7992SMatthew G. Knepley 107c58f1c22SToby Isaac Input parameter: 108c58f1c22SToby Isaac . label - The DMLabel 109c58f1c22SToby Isaac 110c58f1c22SToby Isaac Output parameter: 111c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format 112c58f1c22SToby Isaac 113c58f1c22SToby Isaac Level: developer 114c58f1c22SToby Isaac 115c58f1c22SToby Isaac .seealso: DMLabelCreate() 116c58f1c22SToby Isaac */ 117c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 118c58f1c22SToby Isaac { 119c58f1c22SToby Isaac PetscInt v; 120c58f1c22SToby Isaac PetscErrorCode ierr; 121c58f1c22SToby Isaac 122c58f1c22SToby Isaac PetscFunctionBegin; 123c58f1c22SToby Isaac for (v = 0; v < label->numStrata; v++) { 124c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 125c58f1c22SToby Isaac } 126c58f1c22SToby Isaac PetscFunctionReturn(0); 127c58f1c22SToby Isaac } 128c58f1c22SToby Isaac 129c58f1c22SToby Isaac /* 130c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 131c58f1c22SToby Isaac 1325b5e7992SMatthew G. Knepley Not collective 1335b5e7992SMatthew G. Knepley 134c58f1c22SToby Isaac Input parameter: 135c58f1c22SToby Isaac + label - The DMLabel 136c58f1c22SToby Isaac - v - The stratum value 137c58f1c22SToby Isaac 138c58f1c22SToby Isaac Output parameter: 139c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format 140c58f1c22SToby Isaac 141c58f1c22SToby Isaac Level: developer 142c58f1c22SToby Isaac 143c58f1c22SToby Isaac .seealso: DMLabelCreate() 144c58f1c22SToby Isaac */ 145c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 146c58f1c22SToby Isaac { 147c58f1c22SToby Isaac PetscInt p; 148ad8374ffSToby Isaac const PetscInt *points; 149c58f1c22SToby Isaac PetscErrorCode ierr; 150c58f1c22SToby Isaac 151b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) return 0; 152c58f1c22SToby Isaac PetscFunctionBegin; 1530c3c4a36SLisandro Dalcin if (v < 0 || v >= label->numStrata) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D in DMLabelMakeInvalid_Private\n", v); 154ad8374ffSToby Isaac if (label->points[v]) { 155ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 156e8f14785SLisandro Dalcin for (p = 0; p < label->stratumSizes[v]; ++p) { 157e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr); 158e8f14785SLisandro Dalcin } 159ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 160ad8374ffSToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 161ad8374ffSToby Isaac } 162ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 163c58f1c22SToby Isaac PetscFunctionReturn(0); 164c58f1c22SToby Isaac } 165c58f1c22SToby Isaac 166b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 167b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 168b9907514SLisandro Dalcin #endif 169b9907514SLisandro Dalcin 1700c3c4a36SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 1710c3c4a36SLisandro Dalcin { 1720c3c4a36SLisandro Dalcin PetscInt v; 173b9907514SLisandro Dalcin PetscErrorCode ierr; 1740e79e033SBarry Smith 1750c3c4a36SLisandro Dalcin PetscFunctionBegin; 1760e79e033SBarry Smith *index = -1; 177b9907514SLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 178b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 179b9907514SLisandro Dalcin if (label->stratumValues[v] == value) {*index = v; break;} 180b9907514SLisandro Dalcin } else { 181b9907514SLisandro Dalcin ierr = PetscHMapIGet(label->hmap, value, index);CHKERRQ(ierr); 1820e79e033SBarry Smith } 18376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* Check strata hash map consistency */ 18490e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 18590e9b2aeSLisandro Dalcin ierr = PetscHMapIGetSize(label->hmap, &len);CHKERRQ(ierr); 18690e9b2aeSLisandro Dalcin if (len != label->numStrata) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 18790e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 18890e9b2aeSLisandro Dalcin ierr = PetscHMapIGet(label->hmap, value, &loc);CHKERRQ(ierr); 18990e9b2aeSLisandro Dalcin } else { 19090e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 19190e9b2aeSLisandro Dalcin if (label->stratumValues[v] == value) {loc = v; break;} 19290e9b2aeSLisandro Dalcin } 19390e9b2aeSLisandro Dalcin if (loc != *index) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 19490e9b2aeSLisandro Dalcin } 1950c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 1960c3c4a36SLisandro Dalcin } 1970c3c4a36SLisandro Dalcin 198b9907514SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 199c58f1c22SToby Isaac { 200b9907514SLisandro Dalcin PetscInt v; 201b9907514SLisandro Dalcin PetscInt *tmpV; 202b9907514SLisandro Dalcin PetscInt *tmpS; 203b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 204b9907514SLisandro Dalcin IS *tmpP, is; 205c58f1c22SToby Isaac PetscBool *tmpB; 206b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 207c58f1c22SToby Isaac PetscErrorCode ierr; 208c58f1c22SToby Isaac 209c58f1c22SToby Isaac PetscFunctionBegin; 210b9907514SLisandro Dalcin v = label->numStrata; 211b9907514SLisandro Dalcin tmpV = label->stratumValues; 212b9907514SLisandro Dalcin tmpS = label->stratumSizes; 213b9907514SLisandro Dalcin tmpH = label->ht; 214b9907514SLisandro Dalcin tmpP = label->points; 215b9907514SLisandro Dalcin tmpB = label->validIS; 2168e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2178e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2188e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2198e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2208e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2218e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2228e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpV), &tmpV);CHKERRQ(ierr); 2238e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpS), &tmpS);CHKERRQ(ierr); 2248e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpH), &tmpH);CHKERRQ(ierr); 2258e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpP), &tmpP);CHKERRQ(ierr); 2268e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpB), &tmpB);CHKERRQ(ierr); 227580bdb30SBarry Smith ierr = PetscArraycpy(tmpV, oldV, v);CHKERRQ(ierr); 228580bdb30SBarry Smith ierr = PetscArraycpy(tmpS, oldS, v);CHKERRQ(ierr); 229580bdb30SBarry Smith ierr = PetscArraycpy(tmpH, oldH, v);CHKERRQ(ierr); 230580bdb30SBarry Smith ierr = PetscArraycpy(tmpP, oldP, v);CHKERRQ(ierr); 231580bdb30SBarry Smith ierr = PetscArraycpy(tmpB, oldB, v);CHKERRQ(ierr); 2328e1f8cf0SLisandro Dalcin ierr = PetscFree(oldV);CHKERRQ(ierr); 2338e1f8cf0SLisandro Dalcin ierr = PetscFree(oldS);CHKERRQ(ierr); 2348e1f8cf0SLisandro Dalcin ierr = PetscFree(oldH);CHKERRQ(ierr); 2358e1f8cf0SLisandro Dalcin ierr = PetscFree(oldP);CHKERRQ(ierr); 2368e1f8cf0SLisandro Dalcin ierr = PetscFree(oldB);CHKERRQ(ierr); 2378e1f8cf0SLisandro Dalcin } 238b9907514SLisandro Dalcin label->numStrata = v+1; 239c58f1c22SToby Isaac label->stratumValues = tmpV; 240c58f1c22SToby Isaac label->stratumSizes = tmpS; 241c58f1c22SToby Isaac label->ht = tmpH; 242c58f1c22SToby Isaac label->points = tmpP; 243ad8374ffSToby Isaac label->validIS = tmpB; 244b9907514SLisandro Dalcin ierr = PetscHSetICreate(&ht);CHKERRQ(ierr); 245b9907514SLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr); 246b9907514SLisandro Dalcin ierr = PetscHMapISet(hmap, value, v);CHKERRQ(ierr); 247b9907514SLisandro Dalcin tmpV[v] = value; 248b9907514SLisandro Dalcin tmpS[v] = 0; 249b9907514SLisandro Dalcin tmpH[v] = ht; 250b9907514SLisandro Dalcin tmpP[v] = is; 251b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 252277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 2530c3c4a36SLisandro Dalcin *index = v; 2540c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 2550c3c4a36SLisandro Dalcin } 2560c3c4a36SLisandro Dalcin 257b9907514SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 258b9907514SLisandro Dalcin { 259b9907514SLisandro Dalcin PetscErrorCode ierr; 260b9907514SLisandro Dalcin PetscFunctionBegin; 261b9907514SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, index);CHKERRQ(ierr); 262b9907514SLisandro Dalcin if (*index < 0) {ierr = DMLabelNewStratum(label, value, index);CHKERRQ(ierr);} 263b9907514SLisandro Dalcin PetscFunctionReturn(0); 264b9907514SLisandro Dalcin } 265b9907514SLisandro Dalcin 2669e63cc69SVaclav Hapla PETSC_STATIC_INLINE PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size) 2679e63cc69SVaclav Hapla { 2689e63cc69SVaclav Hapla PetscErrorCode ierr; 2699e63cc69SVaclav Hapla 2709e63cc69SVaclav Hapla PetscFunctionBegin; 2719e63cc69SVaclav Hapla *size = 0; 2729e63cc69SVaclav Hapla if (v < 0) PetscFunctionReturn(0); 2739e63cc69SVaclav Hapla if (label->validIS[v]) { 2749e63cc69SVaclav Hapla *size = label->stratumSizes[v]; 2759e63cc69SVaclav Hapla } else { 2769e63cc69SVaclav Hapla ierr = PetscHSetIGetSize(label->ht[v], size);CHKERRQ(ierr); 2779e63cc69SVaclav Hapla } 2789e63cc69SVaclav Hapla PetscFunctionReturn(0); 2799e63cc69SVaclav Hapla } 2809e63cc69SVaclav Hapla 281b9907514SLisandro Dalcin /*@ 282b9907514SLisandro Dalcin DMLabelAddStratum - Adds a new stratum value in a DMLabel 283b9907514SLisandro Dalcin 284d8d19677SJose E. Roman Input Parameters: 285b9907514SLisandro Dalcin + label - The DMLabel 286b9907514SLisandro Dalcin - value - The stratum value 287b9907514SLisandro Dalcin 288b9907514SLisandro Dalcin Level: beginner 289b9907514SLisandro Dalcin 290b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 291b9907514SLisandro Dalcin @*/ 2920c3c4a36SLisandro Dalcin PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 2930c3c4a36SLisandro Dalcin { 2940c3c4a36SLisandro Dalcin PetscInt v; 2950c3c4a36SLisandro Dalcin PetscErrorCode ierr; 2960c3c4a36SLisandro Dalcin 2970c3c4a36SLisandro Dalcin PetscFunctionBegin; 298d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 299b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 300b9907514SLisandro Dalcin PetscFunctionReturn(0); 301b9907514SLisandro Dalcin } 302b9907514SLisandro Dalcin 303b9907514SLisandro Dalcin /*@ 304b9907514SLisandro Dalcin DMLabelAddStrata - Adds new stratum values in a DMLabel 305b9907514SLisandro Dalcin 3065b5e7992SMatthew G. Knepley Not collective 3075b5e7992SMatthew G. Knepley 308d8d19677SJose E. Roman Input Parameters: 309b9907514SLisandro Dalcin + label - The DMLabel 310b9907514SLisandro Dalcin . numStrata - The number of stratum values 311b9907514SLisandro Dalcin - stratumValues - The stratum values 312b9907514SLisandro Dalcin 313b9907514SLisandro Dalcin Level: beginner 314b9907514SLisandro Dalcin 315b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 316b9907514SLisandro Dalcin @*/ 317b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 318b9907514SLisandro Dalcin { 319b9907514SLisandro Dalcin PetscInt *values, v; 320b9907514SLisandro Dalcin PetscErrorCode ierr; 321b9907514SLisandro Dalcin 322b9907514SLisandro Dalcin PetscFunctionBegin; 323b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 324b9907514SLisandro Dalcin if (numStrata) PetscValidIntPointer(stratumValues, 3); 325b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &values);CHKERRQ(ierr); 326580bdb30SBarry Smith ierr = PetscArraycpy(values, stratumValues, numStrata);CHKERRQ(ierr); 327b9907514SLisandro Dalcin ierr = PetscSortRemoveDupsInt(&numStrata, values);CHKERRQ(ierr); 328b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 329b9907514SLisandro Dalcin PetscInt *tmpV; 330b9907514SLisandro Dalcin PetscInt *tmpS; 331b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 332b9907514SLisandro Dalcin IS *tmpP, is; 333b9907514SLisandro Dalcin PetscBool *tmpB; 334b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 335b9907514SLisandro Dalcin 336b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpV);CHKERRQ(ierr); 337b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpS);CHKERRQ(ierr); 338b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpH);CHKERRQ(ierr); 339b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpP);CHKERRQ(ierr); 340b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpB);CHKERRQ(ierr); 341b9907514SLisandro Dalcin label->numStrata = numStrata; 342b9907514SLisandro Dalcin label->stratumValues = tmpV; 343b9907514SLisandro Dalcin label->stratumSizes = tmpS; 344b9907514SLisandro Dalcin label->ht = tmpH; 345b9907514SLisandro Dalcin label->points = tmpP; 346b9907514SLisandro Dalcin label->validIS = tmpB; 347b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 348b9907514SLisandro Dalcin ierr = PetscHSetICreate(&ht);CHKERRQ(ierr); 349b9907514SLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr); 350b9907514SLisandro Dalcin ierr = PetscHMapISet(hmap, values[v], v);CHKERRQ(ierr); 351b9907514SLisandro Dalcin tmpV[v] = values[v]; 352b9907514SLisandro Dalcin tmpS[v] = 0; 353b9907514SLisandro Dalcin tmpH[v] = ht; 354b9907514SLisandro Dalcin tmpP[v] = is; 355b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 356b9907514SLisandro Dalcin } 357277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 358b9907514SLisandro Dalcin } else { 359b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 360b9907514SLisandro Dalcin ierr = DMLabelAddStratum(label, values[v]);CHKERRQ(ierr); 361b9907514SLisandro Dalcin } 362b9907514SLisandro Dalcin } 363b9907514SLisandro Dalcin ierr = PetscFree(values);CHKERRQ(ierr); 364b9907514SLisandro Dalcin PetscFunctionReturn(0); 365b9907514SLisandro Dalcin } 366b9907514SLisandro Dalcin 367b9907514SLisandro Dalcin /*@ 368b9907514SLisandro Dalcin DMLabelAddStrataIS - Adds new stratum values in a DMLabel 369b9907514SLisandro Dalcin 3705b5e7992SMatthew G. Knepley Not collective 3715b5e7992SMatthew G. Knepley 372d8d19677SJose E. Roman Input Parameters: 373b9907514SLisandro Dalcin + label - The DMLabel 374b9907514SLisandro Dalcin - valueIS - Index set with stratum values 375b9907514SLisandro Dalcin 376b9907514SLisandro Dalcin Level: beginner 377b9907514SLisandro Dalcin 378b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 379b9907514SLisandro Dalcin @*/ 380b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 381b9907514SLisandro Dalcin { 382b9907514SLisandro Dalcin PetscInt numStrata; 383b9907514SLisandro Dalcin const PetscInt *stratumValues; 384b9907514SLisandro Dalcin PetscErrorCode ierr; 385b9907514SLisandro Dalcin 386b9907514SLisandro Dalcin PetscFunctionBegin; 387b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 388b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 389b9907514SLisandro Dalcin ierr = ISGetLocalSize(valueIS, &numStrata);CHKERRQ(ierr); 390b9907514SLisandro Dalcin ierr = ISGetIndices(valueIS, &stratumValues);CHKERRQ(ierr); 391b9907514SLisandro Dalcin ierr = DMLabelAddStrata(label, numStrata, stratumValues);CHKERRQ(ierr); 392c58f1c22SToby Isaac PetscFunctionReturn(0); 393c58f1c22SToby Isaac } 394c58f1c22SToby Isaac 395c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) 396c58f1c22SToby Isaac { 397c58f1c22SToby Isaac PetscInt v; 398c58f1c22SToby Isaac PetscMPIInt rank; 399c58f1c22SToby Isaac PetscErrorCode ierr; 400c58f1c22SToby Isaac 401c58f1c22SToby Isaac PetscFunctionBegin; 402ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRMPI(ierr); 403c58f1c22SToby Isaac ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 404c58f1c22SToby Isaac if (label) { 405d67d17b1SMatthew G. Knepley const char *name; 406d67d17b1SMatthew G. Knepley 407d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 408d67d17b1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name);CHKERRQ(ierr); 409c58f1c22SToby Isaac if (label->bt) {ierr = PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%D, %D)\n", label->pStart, label->pEnd);CHKERRQ(ierr);} 410c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 411c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 412ad8374ffSToby Isaac const PetscInt *points; 413c58f1c22SToby Isaac PetscInt p; 414c58f1c22SToby Isaac 415ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 416c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 417ad8374ffSToby Isaac ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\n", rank, points[p], value);CHKERRQ(ierr); 418c58f1c22SToby Isaac } 419ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 420c58f1c22SToby Isaac } 421c58f1c22SToby Isaac } 422c58f1c22SToby Isaac ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 423c58f1c22SToby Isaac ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 424c58f1c22SToby Isaac PetscFunctionReturn(0); 425c58f1c22SToby Isaac } 426c58f1c22SToby Isaac 427c58f1c22SToby Isaac /*@C 428c58f1c22SToby Isaac DMLabelView - View the label 429c58f1c22SToby Isaac 4305b5e7992SMatthew G. Knepley Collective on viewer 4315b5e7992SMatthew G. Knepley 432c58f1c22SToby Isaac Input Parameters: 433c58f1c22SToby Isaac + label - The DMLabel 434c58f1c22SToby Isaac - viewer - The PetscViewer 435c58f1c22SToby Isaac 436c58f1c22SToby Isaac Level: intermediate 437c58f1c22SToby Isaac 438c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelDestroy() 439c58f1c22SToby Isaac @*/ 440c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 441c58f1c22SToby Isaac { 442c58f1c22SToby Isaac PetscBool iascii; 443c58f1c22SToby Isaac PetscErrorCode ierr; 444c58f1c22SToby Isaac 445c58f1c22SToby Isaac PetscFunctionBegin; 446d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 447b9907514SLisandro Dalcin if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer);CHKERRQ(ierr);} 448c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 449c58f1c22SToby Isaac if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 450c58f1c22SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 451c58f1c22SToby Isaac if (iascii) { 452c58f1c22SToby Isaac ierr = DMLabelView_Ascii(label, viewer);CHKERRQ(ierr); 453c58f1c22SToby Isaac } 454c58f1c22SToby Isaac PetscFunctionReturn(0); 455c58f1c22SToby Isaac } 456c58f1c22SToby Isaac 45784f0b6dfSMatthew G. Knepley /*@ 458d67d17b1SMatthew G. Knepley DMLabelReset - Destroys internal data structures in a DMLabel 459d67d17b1SMatthew G. Knepley 4605b5e7992SMatthew G. Knepley Not collective 4615b5e7992SMatthew G. Knepley 462d67d17b1SMatthew G. Knepley Input Parameter: 463d67d17b1SMatthew G. Knepley . label - The DMLabel 464d67d17b1SMatthew G. Knepley 465d67d17b1SMatthew G. Knepley Level: beginner 466d67d17b1SMatthew G. Knepley 467d67d17b1SMatthew G. Knepley .seealso: DMLabelDestroy(), DMLabelCreate() 468d67d17b1SMatthew G. Knepley @*/ 469d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelReset(DMLabel label) 470d67d17b1SMatthew G. Knepley { 471d67d17b1SMatthew G. Knepley PetscInt v; 472d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 473d67d17b1SMatthew G. Knepley 474d67d17b1SMatthew G. Knepley PetscFunctionBegin; 475d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 476d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 477d67d17b1SMatthew G. Knepley ierr = PetscHSetIDestroy(&label->ht[v]);CHKERRQ(ierr); 478d67d17b1SMatthew G. Knepley ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 479d67d17b1SMatthew G. Knepley } 480b9907514SLisandro Dalcin label->numStrata = 0; 481b9907514SLisandro Dalcin ierr = PetscFree(label->stratumValues);CHKERRQ(ierr); 482b9907514SLisandro Dalcin ierr = PetscFree(label->stratumSizes);CHKERRQ(ierr); 483d67d17b1SMatthew G. Knepley ierr = PetscFree(label->ht);CHKERRQ(ierr); 484d67d17b1SMatthew G. Knepley ierr = PetscFree(label->points);CHKERRQ(ierr); 485d67d17b1SMatthew G. Knepley ierr = PetscFree(label->validIS);CHKERRQ(ierr); 486f9244615SMatthew G. Knepley label->stratumValues = NULL; 487f9244615SMatthew G. Knepley label->stratumSizes = NULL; 488f9244615SMatthew G. Knepley label->ht = NULL; 489f9244615SMatthew G. Knepley label->points = NULL; 490f9244615SMatthew G. Knepley label->validIS = NULL; 491b9907514SLisandro Dalcin ierr = PetscHMapIReset(label->hmap);CHKERRQ(ierr); 492b9907514SLisandro Dalcin label->pStart = -1; 493b9907514SLisandro Dalcin label->pEnd = -1; 494d67d17b1SMatthew G. Knepley ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 495d67d17b1SMatthew G. Knepley PetscFunctionReturn(0); 496d67d17b1SMatthew G. Knepley } 497d67d17b1SMatthew G. Knepley 498d67d17b1SMatthew G. Knepley /*@ 49984f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 50084f0b6dfSMatthew G. Knepley 5015b5e7992SMatthew G. Knepley Collective on label 5025b5e7992SMatthew G. Knepley 50384f0b6dfSMatthew G. Knepley Input Parameter: 50484f0b6dfSMatthew G. Knepley . label - The DMLabel 50584f0b6dfSMatthew G. Knepley 50684f0b6dfSMatthew G. Knepley Level: beginner 50784f0b6dfSMatthew G. Knepley 508d67d17b1SMatthew G. Knepley .seealso: DMLabelReset(), DMLabelCreate() 50984f0b6dfSMatthew G. Knepley @*/ 510c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label) 511c58f1c22SToby Isaac { 512c58f1c22SToby Isaac PetscErrorCode ierr; 513c58f1c22SToby Isaac 514c58f1c22SToby Isaac PetscFunctionBegin; 515d67d17b1SMatthew G. Knepley if (!*label) PetscFunctionReturn(0); 516d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label),DMLABEL_CLASSID,1); 517b9907514SLisandro Dalcin if (--((PetscObject)(*label))->refct > 0) {*label = NULL; PetscFunctionReturn(0);} 518d67d17b1SMatthew G. Knepley ierr = DMLabelReset(*label);CHKERRQ(ierr); 519b9907514SLisandro Dalcin ierr = PetscHMapIDestroy(&(*label)->hmap);CHKERRQ(ierr); 520d67d17b1SMatthew G. Knepley ierr = PetscHeaderDestroy(label);CHKERRQ(ierr); 521c58f1c22SToby Isaac PetscFunctionReturn(0); 522c58f1c22SToby Isaac } 523c58f1c22SToby Isaac 52484f0b6dfSMatthew G. Knepley /*@ 52584f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 52684f0b6dfSMatthew G. Knepley 5275b5e7992SMatthew G. Knepley Collective on label 5285b5e7992SMatthew G. Knepley 52984f0b6dfSMatthew G. Knepley Input Parameter: 53084f0b6dfSMatthew G. Knepley . label - The DMLabel 53184f0b6dfSMatthew G. Knepley 53284f0b6dfSMatthew G. Knepley Output Parameter: 53384f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 53484f0b6dfSMatthew G. Knepley 53584f0b6dfSMatthew G. Knepley Level: intermediate 53684f0b6dfSMatthew G. Knepley 53784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelDestroy() 53884f0b6dfSMatthew G. Knepley @*/ 539c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 540c58f1c22SToby Isaac { 541d67d17b1SMatthew G. Knepley const char *name; 542ad8374ffSToby Isaac PetscInt v; 543c58f1c22SToby Isaac PetscErrorCode ierr; 544c58f1c22SToby Isaac 545c58f1c22SToby Isaac PetscFunctionBegin; 546d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 547c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 548d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 549d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PetscObjectComm((PetscObject) label), name, labelnew);CHKERRQ(ierr); 550c58f1c22SToby Isaac 551c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5525aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 553c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues);CHKERRQ(ierr); 554c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes);CHKERRQ(ierr); 555c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->ht);CHKERRQ(ierr); 556c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->points);CHKERRQ(ierr); 557ad8374ffSToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->validIS);CHKERRQ(ierr); 558c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 559e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelnew)->ht[v]);CHKERRQ(ierr); 560c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 561c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 562ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) (label->points[v]));CHKERRQ(ierr); 563ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 564b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 565c58f1c22SToby Isaac } 566f14fe40dSLisandro Dalcin ierr = PetscHMapIDestroy(&(*labelnew)->hmap);CHKERRQ(ierr); 567b9907514SLisandro Dalcin ierr = PetscHMapIDuplicate(label->hmap,&(*labelnew)->hmap);CHKERRQ(ierr); 568c58f1c22SToby Isaac (*labelnew)->pStart = -1; 569c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 570c58f1c22SToby Isaac (*labelnew)->bt = NULL; 571c58f1c22SToby Isaac PetscFunctionReturn(0); 572c58f1c22SToby Isaac } 573c58f1c22SToby Isaac 574609dae6eSVaclav Hapla /*@C 575609dae6eSVaclav Hapla DMLabelCompare - Compare two DMLabel objects 576609dae6eSVaclav Hapla 577*5efe38ccSVaclav Hapla Collective on comm 578609dae6eSVaclav Hapla 579609dae6eSVaclav Hapla Input Parameters: 580609dae6eSVaclav Hapla + l0 - First DMLabel 581609dae6eSVaclav Hapla - l1 - Second DMLabel 582609dae6eSVaclav Hapla 583609dae6eSVaclav Hapla Output Parameters 584*5efe38ccSVaclav Hapla + equal - (Optional) Flag whether the two labels are equal 585*5efe38ccSVaclav Hapla - message - (Optional) Message describing the difference 586609dae6eSVaclav Hapla 587609dae6eSVaclav Hapla Level: intermediate 588609dae6eSVaclav Hapla 589609dae6eSVaclav Hapla Notes: 590*5efe38ccSVaclav Hapla The output flag equal is the same on all processes. 591*5efe38ccSVaclav Hapla If it is passed as NULL and difference is found, an error is thrown on all processes. 592*5efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 593609dae6eSVaclav Hapla 594*5efe38ccSVaclav Hapla The output message is set independently on each rank. 595*5efe38ccSVaclav Hapla It is set to NULL if no difference was found on the current rank. It must be freed by user. 596*5efe38ccSVaclav Hapla If message is passed as NULL and difference is found, the difference description is printed to stderr in synchronized manner. 597*5efe38ccSVaclav Hapla Make sure to pass NULL on all processes. 598609dae6eSVaclav Hapla 599609dae6eSVaclav Hapla For the comparison, we ignore the order of stratum values, and strata with no points. 600609dae6eSVaclav Hapla 601*5efe38ccSVaclav Hapla The communicator needs to be specified because currently DMLabel can live on PETSC_COMM_SELF even if the underlying DM is parallel. 602*5efe38ccSVaclav Hapla 603609dae6eSVaclav Hapla Fortran Notes: 604609dae6eSVaclav Hapla This function is currently not available from Fortran. 605609dae6eSVaclav Hapla 606609dae6eSVaclav Hapla .seealso: DMCompareLabels(), DMLabelGetNumValues(), DMLabelGetDefaultValue(), DMLabelGetNonEmptyStratumValuesIS(), DMLabelGetStratumIS() 607609dae6eSVaclav Hapla @*/ 608*5efe38ccSVaclav Hapla PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message) 609609dae6eSVaclav Hapla { 610609dae6eSVaclav Hapla const char *name0, *name1; 611609dae6eSVaclav Hapla char msg[PETSC_MAX_PATH_LEN] = ""; 612*5efe38ccSVaclav Hapla PetscBool eq; 613*5efe38ccSVaclav Hapla PetscMPIInt rank; 614609dae6eSVaclav Hapla PetscErrorCode ierr; 615609dae6eSVaclav Hapla 616609dae6eSVaclav Hapla PetscFunctionBegin; 617*5efe38ccSVaclav Hapla PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2); 618*5efe38ccSVaclav Hapla PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3); 619*5efe38ccSVaclav Hapla if (equal) PetscValidBoolPointer(equal, 4); 620*5efe38ccSVaclav Hapla if (message) PetscValidPointer(message, 5); 621*5efe38ccSVaclav Hapla ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 622609dae6eSVaclav Hapla ierr = PetscObjectGetName((PetscObject)l0, &name0);CHKERRQ(ierr); 623609dae6eSVaclav Hapla ierr = PetscObjectGetName((PetscObject)l1, &name1);CHKERRQ(ierr); 624609dae6eSVaclav Hapla { 625609dae6eSVaclav Hapla PetscInt v0, v1; 626609dae6eSVaclav Hapla 627609dae6eSVaclav Hapla ierr = DMLabelGetDefaultValue(l0, &v0);CHKERRQ(ierr); 628609dae6eSVaclav Hapla ierr = DMLabelGetDefaultValue(l1, &v1);CHKERRQ(ierr); 629*5efe38ccSVaclav Hapla eq = (PetscBool) (v0 == v1); 630*5efe38ccSVaclav Hapla if (!eq) { 631609dae6eSVaclav Hapla ierr = PetscSNPrintf(msg, sizeof(msg), "Default value of DMLabel l0 \"%s\" = %D != %D = Default value of DMLabel l1 \"%s\"", name0, v0, v1, name1);CHKERRQ(ierr); 632609dae6eSVaclav Hapla } 633*5efe38ccSVaclav Hapla ierr = MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr); 634*5efe38ccSVaclav Hapla if (!eq) goto finish; 635609dae6eSVaclav Hapla } 636609dae6eSVaclav Hapla { 637609dae6eSVaclav Hapla IS is0, is1; 638609dae6eSVaclav Hapla 639609dae6eSVaclav Hapla ierr = DMLabelGetNonEmptyStratumValuesIS(l0, &is0);CHKERRQ(ierr); 640609dae6eSVaclav Hapla ierr = DMLabelGetNonEmptyStratumValuesIS(l1, &is1);CHKERRQ(ierr); 641*5efe38ccSVaclav Hapla ierr = ISEqual(is0, is1, &eq);CHKERRQ(ierr); 642609dae6eSVaclav Hapla ierr = ISDestroy(&is0);CHKERRQ(ierr); 643609dae6eSVaclav Hapla ierr = ISDestroy(&is1);CHKERRQ(ierr); 644*5efe38ccSVaclav Hapla if (!eq) { 645609dae6eSVaclav Hapla ierr = PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1);CHKERRQ(ierr); 646609dae6eSVaclav Hapla } 647*5efe38ccSVaclav Hapla ierr = MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr); 648*5efe38ccSVaclav Hapla if (!eq) goto finish; 649609dae6eSVaclav Hapla } 650609dae6eSVaclav Hapla { 651609dae6eSVaclav Hapla PetscInt i, nValues; 652609dae6eSVaclav Hapla 653609dae6eSVaclav Hapla ierr = DMLabelGetNumValues(l0, &nValues);CHKERRQ(ierr); 654609dae6eSVaclav Hapla for (i=0; i<nValues; i++) { 655609dae6eSVaclav Hapla const PetscInt v = l0->stratumValues[i]; 656609dae6eSVaclav Hapla PetscInt n; 657609dae6eSVaclav Hapla IS is0, is1; 658609dae6eSVaclav Hapla 659609dae6eSVaclav Hapla ierr = DMLabelGetStratumSize_Private(l0, i, &n);CHKERRQ(ierr); 660609dae6eSVaclav Hapla if (!n) continue; 661609dae6eSVaclav Hapla ierr = DMLabelGetStratumIS(l0, v, &is0);CHKERRQ(ierr); 662609dae6eSVaclav Hapla ierr = DMLabelGetStratumIS(l1, v, &is1);CHKERRQ(ierr); 663*5efe38ccSVaclav Hapla ierr = ISEqualUnsorted(is0, is1, &eq);CHKERRQ(ierr); 664609dae6eSVaclav Hapla ierr = ISDestroy(&is0);CHKERRQ(ierr); 665609dae6eSVaclav Hapla ierr = ISDestroy(&is1);CHKERRQ(ierr); 666*5efe38ccSVaclav Hapla if (!eq) { 667609dae6eSVaclav Hapla ierr = PetscSNPrintf(msg, sizeof(msg), "Stratum #%D with value %D contains different points in DMLabel l0 \"%s\" and DMLabel l1 \"%s\"", i, v, name0, name1);CHKERRQ(ierr); 668*5efe38ccSVaclav Hapla break; 669609dae6eSVaclav Hapla } 670609dae6eSVaclav Hapla } 671*5efe38ccSVaclav Hapla ierr = MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr); 672609dae6eSVaclav Hapla } 673609dae6eSVaclav Hapla finish: 674*5efe38ccSVaclav Hapla /* If message output arg not set, print to stderr */ 675609dae6eSVaclav Hapla if (message) { 676609dae6eSVaclav Hapla *message = NULL; 677609dae6eSVaclav Hapla if (msg[0]) { 678609dae6eSVaclav Hapla ierr = PetscStrallocpy(msg, message);CHKERRQ(ierr); 679609dae6eSVaclav Hapla } 680*5efe38ccSVaclav Hapla } else { 681*5efe38ccSVaclav Hapla if (msg[0]) { 682*5efe38ccSVaclav Hapla ierr = PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg);CHKERRQ(ierr); 683609dae6eSVaclav Hapla } 684*5efe38ccSVaclav Hapla ierr = PetscSynchronizedFlush(comm, PETSC_STDERR);CHKERRQ(ierr); 685*5efe38ccSVaclav Hapla } 686*5efe38ccSVaclav Hapla /* If same output arg not ser and labels are not equal, throw error */ 687*5efe38ccSVaclav Hapla if (equal) *equal = eq; 688*5efe38ccSVaclav Hapla else if (!eq) SETERRQ(comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal"); 689609dae6eSVaclav Hapla PetscFunctionReturn(0); 690609dae6eSVaclav Hapla } 691609dae6eSVaclav Hapla 692c6a43d28SMatthew G. Knepley /*@ 693c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 694c6a43d28SMatthew G. Knepley 6955b5e7992SMatthew G. Knepley Not collective 6965b5e7992SMatthew G. Knepley 697c6a43d28SMatthew G. Knepley Input Parameter: 698c6a43d28SMatthew G. Knepley . label - The DMLabel 699c6a43d28SMatthew G. Knepley 700c6a43d28SMatthew G. Knepley Level: intermediate 701c6a43d28SMatthew G. Knepley 702c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 703c6a43d28SMatthew G. Knepley @*/ 704c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelComputeIndex(DMLabel label) 705c6a43d28SMatthew G. Knepley { 706c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 707c6a43d28SMatthew G. Knepley PetscErrorCode ierr; 708c6a43d28SMatthew G. Knepley 709c6a43d28SMatthew G. Knepley PetscFunctionBegin; 710c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 711c6a43d28SMatthew G. Knepley ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 712c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 713c6a43d28SMatthew G. Knepley const PetscInt *points; 714c6a43d28SMatthew G. Knepley PetscInt i; 715c6a43d28SMatthew G. Knepley 716c6a43d28SMatthew G. Knepley ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 717c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 718c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 719c6a43d28SMatthew G. Knepley 720c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 721c6a43d28SMatthew G. Knepley pEnd = PetscMax(point+1, pEnd); 722c6a43d28SMatthew G. Knepley } 723c6a43d28SMatthew G. Knepley ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 724c6a43d28SMatthew G. Knepley } 725c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 726c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 727c6a43d28SMatthew G. Knepley ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 728c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 729c6a43d28SMatthew G. Knepley } 730c6a43d28SMatthew G. Knepley 731c6a43d28SMatthew G. Knepley /*@ 732c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 733c6a43d28SMatthew G. Knepley 7345b5e7992SMatthew G. Knepley Not collective 7355b5e7992SMatthew G. Knepley 736c6a43d28SMatthew G. Knepley Input Parameters: 737c6a43d28SMatthew G. Knepley + label - The DMLabel 738c6a43d28SMatthew G. Knepley . pStart - The smallest point 739c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 740c6a43d28SMatthew G. Knepley 741c6a43d28SMatthew G. Knepley Level: intermediate 742c6a43d28SMatthew G. Knepley 743c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelComputeIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 744c6a43d28SMatthew G. Knepley @*/ 745c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 746c58f1c22SToby Isaac { 747c58f1c22SToby Isaac PetscInt v; 748c58f1c22SToby Isaac PetscErrorCode ierr; 749c58f1c22SToby Isaac 750c58f1c22SToby Isaac PetscFunctionBegin; 751d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 7520c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 753c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 754c58f1c22SToby Isaac label->pStart = pStart; 755c58f1c22SToby Isaac label->pEnd = pEnd; 756c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 757c58f1c22SToby Isaac ierr = PetscBTCreate(pEnd - pStart, &label->bt);CHKERRQ(ierr); 758c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 759ad8374ffSToby Isaac const PetscInt *points; 760c58f1c22SToby Isaac PetscInt i; 761c58f1c22SToby Isaac 762ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 763c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 764ad8374ffSToby Isaac const PetscInt point = points[i]; 765c58f1c22SToby Isaac 766c58f1c22SToby Isaac if ((point < pStart) || (point >= pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, pStart, pEnd); 767c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - pStart);CHKERRQ(ierr); 768c58f1c22SToby Isaac } 769ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 770c58f1c22SToby Isaac } 771c58f1c22SToby Isaac PetscFunctionReturn(0); 772c58f1c22SToby Isaac } 773c58f1c22SToby Isaac 774c6a43d28SMatthew G. Knepley /*@ 775c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 776c6a43d28SMatthew G. Knepley 7775b5e7992SMatthew G. Knepley Not collective 7785b5e7992SMatthew G. Knepley 779c6a43d28SMatthew G. Knepley Input Parameter: 780c6a43d28SMatthew G. Knepley . label - the DMLabel 781c6a43d28SMatthew G. Knepley 782c6a43d28SMatthew G. Knepley Level: intermediate 783c6a43d28SMatthew G. Knepley 784c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 785c6a43d28SMatthew G. Knepley @*/ 786c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label) 787c58f1c22SToby Isaac { 788c58f1c22SToby Isaac PetscErrorCode ierr; 789c58f1c22SToby Isaac 790c58f1c22SToby Isaac PetscFunctionBegin; 791d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 792c58f1c22SToby Isaac label->pStart = -1; 793c58f1c22SToby Isaac label->pEnd = -1; 7940c3c4a36SLisandro Dalcin ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 795c58f1c22SToby Isaac PetscFunctionReturn(0); 796c58f1c22SToby Isaac } 797c58f1c22SToby Isaac 798c58f1c22SToby Isaac /*@ 799c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 800c6a43d28SMatthew G. Knepley 8015b5e7992SMatthew G. Knepley Not collective 8025b5e7992SMatthew G. Knepley 803c6a43d28SMatthew G. Knepley Input Parameter: 804c6a43d28SMatthew G. Knepley . label - the DMLabel 805c6a43d28SMatthew G. Knepley 806c6a43d28SMatthew G. Knepley Output Parameters: 807c6a43d28SMatthew G. Knepley + pStart - The smallest point 808c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 809c6a43d28SMatthew G. Knepley 810c6a43d28SMatthew G. Knepley Note: This will compute an index for the label if one does not exist. 811c6a43d28SMatthew G. Knepley 812c6a43d28SMatthew G. Knepley Level: intermediate 813c6a43d28SMatthew G. Knepley 814c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 815c6a43d28SMatthew G. Knepley @*/ 816c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 817c6a43d28SMatthew G. Knepley { 818c6a43d28SMatthew G. Knepley PetscErrorCode ierr; 819c6a43d28SMatthew G. Knepley 820c6a43d28SMatthew G. Knepley PetscFunctionBegin; 821c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 822c6a43d28SMatthew G. Knepley if ((label->pStart == -1) && (label->pEnd == -1)) {ierr = DMLabelComputeIndex(label);CHKERRQ(ierr);} 823c6a43d28SMatthew G. Knepley if (pStart) { 824534a8f05SLisandro Dalcin PetscValidIntPointer(pStart, 2); 825c6a43d28SMatthew G. Knepley *pStart = label->pStart; 826c6a43d28SMatthew G. Knepley } 827c6a43d28SMatthew G. Knepley if (pEnd) { 828534a8f05SLisandro Dalcin PetscValidIntPointer(pEnd, 3); 829c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 830c6a43d28SMatthew G. Knepley } 831c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 832c6a43d28SMatthew G. Knepley } 833c6a43d28SMatthew G. Knepley 834c6a43d28SMatthew G. Knepley /*@ 835c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 836c58f1c22SToby Isaac 8375b5e7992SMatthew G. Knepley Not collective 8385b5e7992SMatthew G. Knepley 839c58f1c22SToby Isaac Input Parameters: 840c58f1c22SToby Isaac + label - the DMLabel 841c58f1c22SToby Isaac - value - the value 842c58f1c22SToby Isaac 843c58f1c22SToby Isaac Output Parameter: 844c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 845c58f1c22SToby Isaac 846c58f1c22SToby Isaac Level: developer 847c58f1c22SToby Isaac 848c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue() 849c58f1c22SToby Isaac @*/ 850c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 851c58f1c22SToby Isaac { 852c58f1c22SToby Isaac PetscInt v; 8530c3c4a36SLisandro Dalcin PetscErrorCode ierr; 854c58f1c22SToby Isaac 855c58f1c22SToby Isaac PetscFunctionBegin; 856d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 857534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 8580c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 8590c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 860c58f1c22SToby Isaac PetscFunctionReturn(0); 861c58f1c22SToby Isaac } 862c58f1c22SToby Isaac 863c58f1c22SToby Isaac /*@ 864c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 865c58f1c22SToby Isaac 8665b5e7992SMatthew G. Knepley Not collective 8675b5e7992SMatthew G. Knepley 868c58f1c22SToby Isaac Input Parameters: 869c58f1c22SToby Isaac + label - the DMLabel 870c58f1c22SToby Isaac - point - the point 871c58f1c22SToby Isaac 872c58f1c22SToby Isaac Output Parameter: 873c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 874c58f1c22SToby Isaac 875c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 876c58f1c22SToby Isaac 877c58f1c22SToby Isaac Level: developer 878c58f1c22SToby Isaac 879c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 880c58f1c22SToby Isaac @*/ 881c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 882c58f1c22SToby Isaac { 883c58f1c22SToby Isaac PetscErrorCode ierr; 884c58f1c22SToby Isaac 885c58f1c22SToby Isaac PetscFunctionBeginHot; 886d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 887534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 888c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 88976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 890c58f1c22SToby Isaac if (!label->bt) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 891c58f1c22SToby Isaac if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 89276bd3646SJed Brown } 893c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 894c58f1c22SToby Isaac PetscFunctionReturn(0); 895c58f1c22SToby Isaac } 896c58f1c22SToby Isaac 897c58f1c22SToby Isaac /*@ 898c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 899c58f1c22SToby Isaac 9005b5e7992SMatthew G. Knepley Not collective 9015b5e7992SMatthew G. Knepley 902c58f1c22SToby Isaac Input Parameters: 903c58f1c22SToby Isaac + label - the DMLabel 904c58f1c22SToby Isaac . value - the stratum value 905c58f1c22SToby Isaac - point - the point 906c58f1c22SToby Isaac 907c58f1c22SToby Isaac Output Parameter: 908c58f1c22SToby Isaac . contains - true if the stratum contains the point 909c58f1c22SToby Isaac 910c58f1c22SToby Isaac Level: intermediate 911c58f1c22SToby Isaac 912c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue() 913c58f1c22SToby Isaac @*/ 914c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 915c58f1c22SToby Isaac { 916c58f1c22SToby Isaac PetscInt v; 917c58f1c22SToby Isaac PetscErrorCode ierr; 918c58f1c22SToby Isaac 9190c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 920d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 921534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 4); 922c58f1c22SToby Isaac *contains = PETSC_FALSE; 9230c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 9240c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 9250c3c4a36SLisandro Dalcin 926ad8374ffSToby Isaac if (label->validIS[v]) { 927c58f1c22SToby Isaac PetscInt i; 928c58f1c22SToby Isaac 929a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 9300c3c4a36SLisandro Dalcin if (i >= 0) *contains = PETSC_TRUE; 931c58f1c22SToby Isaac } else { 932c58f1c22SToby Isaac PetscBool has; 933c58f1c22SToby Isaac 934b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr); 9350c3c4a36SLisandro Dalcin if (has) *contains = PETSC_TRUE; 936c58f1c22SToby Isaac } 937c58f1c22SToby Isaac PetscFunctionReturn(0); 938c58f1c22SToby Isaac } 939c58f1c22SToby Isaac 94084f0b6dfSMatthew G. Knepley /*@ 9415aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9425aa44df4SToby Isaac When a label is created, it is initialized to -1. 9435aa44df4SToby Isaac 9445b5e7992SMatthew G. Knepley Not collective 9455b5e7992SMatthew G. Knepley 9465aa44df4SToby Isaac Input parameter: 9475aa44df4SToby Isaac . label - a DMLabel object 9485aa44df4SToby Isaac 9495aa44df4SToby Isaac Output parameter: 9505aa44df4SToby Isaac . defaultValue - the default value 9515aa44df4SToby Isaac 9525aa44df4SToby Isaac Level: beginner 9535aa44df4SToby Isaac 9545aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 95584f0b6dfSMatthew G. Knepley @*/ 9565aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 9575aa44df4SToby Isaac { 9585aa44df4SToby Isaac PetscFunctionBegin; 959d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9605aa44df4SToby Isaac *defaultValue = label->defaultValue; 9615aa44df4SToby Isaac PetscFunctionReturn(0); 9625aa44df4SToby Isaac } 9635aa44df4SToby Isaac 96484f0b6dfSMatthew G. Knepley /*@ 9655aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 9665aa44df4SToby Isaac When a label is created, it is initialized to -1. 9675aa44df4SToby Isaac 9685b5e7992SMatthew G. Knepley Not collective 9695b5e7992SMatthew G. Knepley 9705aa44df4SToby Isaac Input parameter: 9715aa44df4SToby Isaac . label - a DMLabel object 9725aa44df4SToby Isaac 9735aa44df4SToby Isaac Output parameter: 9745aa44df4SToby Isaac . defaultValue - the default value 9755aa44df4SToby Isaac 9765aa44df4SToby Isaac Level: beginner 9775aa44df4SToby Isaac 9785aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 97984f0b6dfSMatthew G. Knepley @*/ 9805aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 9815aa44df4SToby Isaac { 9825aa44df4SToby Isaac PetscFunctionBegin; 983d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9845aa44df4SToby Isaac label->defaultValue = defaultValue; 9855aa44df4SToby Isaac PetscFunctionReturn(0); 9865aa44df4SToby Isaac } 9875aa44df4SToby Isaac 988c58f1c22SToby Isaac /*@ 9895aa44df4SToby 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()) 990c58f1c22SToby Isaac 9915b5e7992SMatthew G. Knepley Not collective 9925b5e7992SMatthew G. Knepley 993c58f1c22SToby Isaac Input Parameters: 994c58f1c22SToby Isaac + label - the DMLabel 995c58f1c22SToby Isaac - point - the point 996c58f1c22SToby Isaac 997c58f1c22SToby Isaac Output Parameter: 9988e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 999c58f1c22SToby Isaac 1000c58f1c22SToby Isaac Level: intermediate 1001c58f1c22SToby Isaac 10025aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 1003c58f1c22SToby Isaac @*/ 1004c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 1005c58f1c22SToby Isaac { 1006c58f1c22SToby Isaac PetscInt v; 1007c58f1c22SToby Isaac PetscErrorCode ierr; 1008c58f1c22SToby Isaac 10090c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 1010d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1011c58f1c22SToby Isaac PetscValidPointer(value, 3); 10125aa44df4SToby Isaac *value = label->defaultValue; 1013c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 1014ad8374ffSToby Isaac if (label->validIS[v]) { 1015c58f1c22SToby Isaac PetscInt i; 1016c58f1c22SToby Isaac 1017a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 1018c58f1c22SToby Isaac if (i >= 0) { 1019c58f1c22SToby Isaac *value = label->stratumValues[v]; 1020c58f1c22SToby Isaac break; 1021c58f1c22SToby Isaac } 1022c58f1c22SToby Isaac } else { 1023c58f1c22SToby Isaac PetscBool has; 1024c58f1c22SToby Isaac 1025b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr); 1026c58f1c22SToby Isaac if (has) { 1027c58f1c22SToby Isaac *value = label->stratumValues[v]; 1028c58f1c22SToby Isaac break; 1029c58f1c22SToby Isaac } 1030c58f1c22SToby Isaac } 1031c58f1c22SToby Isaac } 1032c58f1c22SToby Isaac PetscFunctionReturn(0); 1033c58f1c22SToby Isaac } 1034c58f1c22SToby Isaac 1035c58f1c22SToby Isaac /*@ 1036367003a6SStefano 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. 1037c58f1c22SToby Isaac 10385b5e7992SMatthew G. Knepley Not collective 10395b5e7992SMatthew G. Knepley 1040c58f1c22SToby Isaac Input Parameters: 1041c58f1c22SToby Isaac + label - the DMLabel 1042c58f1c22SToby Isaac . point - the point 1043c58f1c22SToby Isaac - value - The point value 1044c58f1c22SToby Isaac 1045c58f1c22SToby Isaac Level: intermediate 1046c58f1c22SToby Isaac 10475aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 1048c58f1c22SToby Isaac @*/ 1049c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 1050c58f1c22SToby Isaac { 1051c58f1c22SToby Isaac PetscInt v; 1052c58f1c22SToby Isaac PetscErrorCode ierr; 1053c58f1c22SToby Isaac 1054c58f1c22SToby Isaac PetscFunctionBegin; 1055d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 10560c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 10575aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 1058b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 1059c58f1c22SToby Isaac /* Set key */ 10600c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 1061e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(label->ht[v], point);CHKERRQ(ierr); 1062c58f1c22SToby Isaac PetscFunctionReturn(0); 1063c58f1c22SToby Isaac } 1064c58f1c22SToby Isaac 1065c58f1c22SToby Isaac /*@ 1066c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 1067c58f1c22SToby Isaac 10685b5e7992SMatthew G. Knepley Not collective 10695b5e7992SMatthew G. Knepley 1070c58f1c22SToby Isaac Input Parameters: 1071c58f1c22SToby Isaac + label - the DMLabel 1072c58f1c22SToby Isaac . point - the point 1073c58f1c22SToby Isaac - value - The point value 1074c58f1c22SToby Isaac 1075c58f1c22SToby Isaac Level: intermediate 1076c58f1c22SToby Isaac 1077c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue() 1078c58f1c22SToby Isaac @*/ 1079c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 1080c58f1c22SToby Isaac { 1081ad8374ffSToby Isaac PetscInt v; 1082c58f1c22SToby Isaac PetscErrorCode ierr; 1083c58f1c22SToby Isaac 1084c58f1c22SToby Isaac PetscFunctionBegin; 1085d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1086c58f1c22SToby Isaac /* Find label value */ 10870c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 10880c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 10890c3c4a36SLisandro Dalcin 1090eeed21e7SToby Isaac if (label->bt) { 1091eeed21e7SToby Isaac if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 1092eeed21e7SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 1093eeed21e7SToby Isaac } 10940c3c4a36SLisandro Dalcin 10950c3c4a36SLisandro Dalcin /* Delete key */ 10960c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 1097e8f14785SLisandro Dalcin ierr = PetscHSetIDel(label->ht[v], point);CHKERRQ(ierr); 1098c58f1c22SToby Isaac PetscFunctionReturn(0); 1099c58f1c22SToby Isaac } 1100c58f1c22SToby Isaac 1101c58f1c22SToby Isaac /*@ 1102c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 1103c58f1c22SToby Isaac 11045b5e7992SMatthew G. Knepley Not collective 11055b5e7992SMatthew G. Knepley 1106c58f1c22SToby Isaac Input Parameters: 1107c58f1c22SToby Isaac + label - the DMLabel 1108c58f1c22SToby Isaac . is - the point IS 1109c58f1c22SToby Isaac - value - The point value 1110c58f1c22SToby Isaac 1111c58f1c22SToby Isaac Level: intermediate 1112c58f1c22SToby Isaac 1113c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 1114c58f1c22SToby Isaac @*/ 1115c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 1116c58f1c22SToby Isaac { 11170c3c4a36SLisandro Dalcin PetscInt v, n, p; 1118c58f1c22SToby Isaac const PetscInt *points; 1119c58f1c22SToby Isaac PetscErrorCode ierr; 1120c58f1c22SToby Isaac 1121c58f1c22SToby Isaac PetscFunctionBegin; 1122d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1123c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 11240c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 11250c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 1126b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 11270c3c4a36SLisandro Dalcin /* Set keys */ 11280c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 1129c58f1c22SToby Isaac ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 1130c58f1c22SToby Isaac ierr = ISGetIndices(is, &points);CHKERRQ(ierr); 1131e8f14785SLisandro Dalcin for (p = 0; p < n; ++p) {ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);} 1132c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &points);CHKERRQ(ierr); 1133c58f1c22SToby Isaac PetscFunctionReturn(0); 1134c58f1c22SToby Isaac } 1135c58f1c22SToby Isaac 113684f0b6dfSMatthew G. Knepley /*@ 113784f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 113884f0b6dfSMatthew G. Knepley 11395b5e7992SMatthew G. Knepley Not collective 11405b5e7992SMatthew G. Knepley 114184f0b6dfSMatthew G. Knepley Input Parameter: 114284f0b6dfSMatthew G. Knepley . label - the DMLabel 114384f0b6dfSMatthew G. Knepley 114401d2d390SJose E. Roman Output Parameter: 114584f0b6dfSMatthew G. Knepley . numValues - the number of values 114684f0b6dfSMatthew G. Knepley 114784f0b6dfSMatthew G. Knepley Level: intermediate 114884f0b6dfSMatthew G. Knepley 114984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 115084f0b6dfSMatthew G. Knepley @*/ 1151c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1152c58f1c22SToby Isaac { 1153c58f1c22SToby Isaac PetscFunctionBegin; 1154d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1155c58f1c22SToby Isaac PetscValidPointer(numValues, 2); 1156c58f1c22SToby Isaac *numValues = label->numStrata; 1157c58f1c22SToby Isaac PetscFunctionReturn(0); 1158c58f1c22SToby Isaac } 1159c58f1c22SToby Isaac 116084f0b6dfSMatthew G. Knepley /*@ 116184f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 116284f0b6dfSMatthew G. Knepley 11635b5e7992SMatthew G. Knepley Not collective 11645b5e7992SMatthew G. Knepley 116584f0b6dfSMatthew G. Knepley Input Parameter: 116684f0b6dfSMatthew G. Knepley . label - the DMLabel 116784f0b6dfSMatthew G. Knepley 116801d2d390SJose E. Roman Output Parameter: 116984f0b6dfSMatthew G. Knepley . is - the value IS 117084f0b6dfSMatthew G. Knepley 117184f0b6dfSMatthew G. Knepley Level: intermediate 117284f0b6dfSMatthew G. Knepley 11731d04cbbeSVaclav Hapla Notes: 11741d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 11751d04cbbeSVaclav Hapla Strata which are allocated but empty [DMLabelGetStratumSize() yields 0] are counted. 11761d04cbbeSVaclav Hapla If you need to count only nonempty strata, use DMLabelGetNonEmptyStratumValuesIS(). 11771d04cbbeSVaclav Hapla 11781d04cbbeSVaclav Hapla .seealso: DMLabelGetNonEmptyStratumValuesIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 117984f0b6dfSMatthew G. Knepley @*/ 1180c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1181c58f1c22SToby Isaac { 1182c58f1c22SToby Isaac PetscErrorCode ierr; 1183c58f1c22SToby Isaac 1184c58f1c22SToby Isaac PetscFunctionBegin; 1185d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1186c58f1c22SToby Isaac PetscValidPointer(values, 2); 1187c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr); 1188c58f1c22SToby Isaac PetscFunctionReturn(0); 1189c58f1c22SToby Isaac } 1190c58f1c22SToby Isaac 119184f0b6dfSMatthew G. Knepley /*@ 11921d04cbbeSVaclav Hapla DMLabelGetNonEmptyStratumValuesIS - Get an IS of all values that the DMlabel takes 11931d04cbbeSVaclav Hapla 11941d04cbbeSVaclav Hapla Not collective 11951d04cbbeSVaclav Hapla 11961d04cbbeSVaclav Hapla Input Parameter: 11971d04cbbeSVaclav Hapla . label - the DMLabel 11981d04cbbeSVaclav Hapla 11991d04cbbeSVaclav Hapla Output Paramater: 12001d04cbbeSVaclav Hapla . is - the value IS 12011d04cbbeSVaclav Hapla 12021d04cbbeSVaclav Hapla Level: intermediate 12031d04cbbeSVaclav Hapla 12041d04cbbeSVaclav Hapla Notes: 12051d04cbbeSVaclav Hapla The output IS should be destroyed when no longer needed. 12061d04cbbeSVaclav Hapla This is similar to DMLabelGetValueIS() but counts only nonempty strata. 12071d04cbbeSVaclav Hapla 12081d04cbbeSVaclav Hapla .seealso: DMLabelGetValueIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 12091d04cbbeSVaclav Hapla @*/ 12101d04cbbeSVaclav Hapla PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values) 12111d04cbbeSVaclav Hapla { 12121d04cbbeSVaclav Hapla PetscInt i, j; 12131d04cbbeSVaclav Hapla PetscInt *valuesArr; 12141d04cbbeSVaclav Hapla PetscErrorCode ierr; 12151d04cbbeSVaclav Hapla 12161d04cbbeSVaclav Hapla PetscFunctionBegin; 12171d04cbbeSVaclav Hapla PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12181d04cbbeSVaclav Hapla PetscValidPointer(values, 2); 12191d04cbbeSVaclav Hapla ierr = PetscMalloc1(label->numStrata, &valuesArr);CHKERRQ(ierr); 12201d04cbbeSVaclav Hapla for (i = 0, j = 0; i < label->numStrata; i++) { 12211d04cbbeSVaclav Hapla PetscInt n; 12221d04cbbeSVaclav Hapla 12231d04cbbeSVaclav Hapla ierr = DMLabelGetStratumSize_Private(label, i, &n);CHKERRQ(ierr); 12241d04cbbeSVaclav Hapla if (n) valuesArr[j++] = label->stratumValues[i]; 12251d04cbbeSVaclav Hapla } 12261d04cbbeSVaclav Hapla if (j == label->numStrata) { 12271d04cbbeSVaclav Hapla ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr); 12281d04cbbeSVaclav Hapla } else { 12291d04cbbeSVaclav Hapla ierr = ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values);CHKERRQ(ierr); 12301d04cbbeSVaclav Hapla } 12311d04cbbeSVaclav Hapla ierr = PetscFree(valuesArr);CHKERRQ(ierr); 12321d04cbbeSVaclav Hapla PetscFunctionReturn(0); 12331d04cbbeSVaclav Hapla } 12341d04cbbeSVaclav Hapla 12351d04cbbeSVaclav Hapla /*@ 1236d123abd9SMatthew 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 1237d123abd9SMatthew G. Knepley 1238d123abd9SMatthew G. Knepley Not collective 1239d123abd9SMatthew G. Knepley 1240d123abd9SMatthew G. Knepley Input Parameters: 1241d123abd9SMatthew G. Knepley + label - the DMLabel 124297bb3fdcSJose E. Roman - value - the value 1243d123abd9SMatthew G. Knepley 124401d2d390SJose E. Roman Output Parameter: 1245d123abd9SMatthew G. Knepley . index - the index of value in the list of values 1246d123abd9SMatthew G. Knepley 1247d123abd9SMatthew G. Knepley Level: intermediate 1248d123abd9SMatthew G. Knepley 1249d123abd9SMatthew G. Knepley .seealso: DMLabelGetValueIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 1250d123abd9SMatthew G. Knepley @*/ 1251d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index) 1252d123abd9SMatthew G. Knepley { 1253d123abd9SMatthew G. Knepley PetscInt v; 1254d123abd9SMatthew G. Knepley 1255d123abd9SMatthew G. Knepley PetscFunctionBegin; 1256d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1257d123abd9SMatthew G. Knepley PetscValidPointer(index, 3); 1258d123abd9SMatthew G. Knepley /* Do not assume they are sorted */ 1259d123abd9SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) if (label->stratumValues[v] == value) break; 1260d123abd9SMatthew G. Knepley if (v >= label->numStrata) *index = -1; 1261d123abd9SMatthew G. Knepley else *index = v; 1262d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1263d123abd9SMatthew G. Knepley } 1264d123abd9SMatthew G. Knepley 1265d123abd9SMatthew G. Knepley /*@ 126684f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 126784f0b6dfSMatthew G. Knepley 12685b5e7992SMatthew G. Knepley Not collective 12695b5e7992SMatthew G. Knepley 127084f0b6dfSMatthew G. Knepley Input Parameters: 127184f0b6dfSMatthew G. Knepley + label - the DMLabel 127284f0b6dfSMatthew G. Knepley - value - the stratum value 127384f0b6dfSMatthew G. Knepley 127401d2d390SJose E. Roman Output Parameter: 127584f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 127684f0b6dfSMatthew G. Knepley 127784f0b6dfSMatthew G. Knepley Level: intermediate 127884f0b6dfSMatthew G. Knepley 127984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 128084f0b6dfSMatthew G. Knepley @*/ 1281fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1282fada774cSMatthew G. Knepley { 1283fada774cSMatthew G. Knepley PetscInt v; 12840c3c4a36SLisandro Dalcin PetscErrorCode ierr; 1285fada774cSMatthew G. Knepley 1286fada774cSMatthew G. Knepley PetscFunctionBegin; 1287d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1288fada774cSMatthew G. Knepley PetscValidPointer(exists, 3); 12890c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 12900c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 1291fada774cSMatthew G. Knepley PetscFunctionReturn(0); 1292fada774cSMatthew G. Knepley } 1293fada774cSMatthew G. Knepley 129484f0b6dfSMatthew G. Knepley /*@ 129584f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 129684f0b6dfSMatthew G. Knepley 12975b5e7992SMatthew G. Knepley Not collective 12985b5e7992SMatthew G. Knepley 129984f0b6dfSMatthew G. Knepley Input Parameters: 130084f0b6dfSMatthew G. Knepley + label - the DMLabel 130184f0b6dfSMatthew G. Knepley - value - the stratum value 130284f0b6dfSMatthew G. Knepley 130301d2d390SJose E. Roman Output Parameter: 130484f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 130584f0b6dfSMatthew G. Knepley 130684f0b6dfSMatthew G. Knepley Level: intermediate 130784f0b6dfSMatthew G. Knepley 130884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 130984f0b6dfSMatthew G. Knepley @*/ 1310c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1311c58f1c22SToby Isaac { 1312c58f1c22SToby Isaac PetscInt v; 1313c58f1c22SToby Isaac PetscErrorCode ierr; 1314c58f1c22SToby Isaac 1315c58f1c22SToby Isaac PetscFunctionBegin; 1316d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1317c58f1c22SToby Isaac PetscValidPointer(size, 3); 13180c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 13199e63cc69SVaclav Hapla ierr = DMLabelGetStratumSize_Private(label, v, size);CHKERRQ(ierr); 1320c58f1c22SToby Isaac PetscFunctionReturn(0); 1321c58f1c22SToby Isaac } 1322c58f1c22SToby Isaac 132384f0b6dfSMatthew G. Knepley /*@ 132484f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 132584f0b6dfSMatthew G. Knepley 13265b5e7992SMatthew G. Knepley Not collective 13275b5e7992SMatthew G. Knepley 132884f0b6dfSMatthew G. Knepley Input Parameters: 132984f0b6dfSMatthew G. Knepley + label - the DMLabel 133084f0b6dfSMatthew G. Knepley - value - the stratum value 133184f0b6dfSMatthew G. Knepley 133201d2d390SJose E. Roman Output Parameters: 133384f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 133484f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 133584f0b6dfSMatthew G. Knepley 133684f0b6dfSMatthew G. Knepley Level: intermediate 133784f0b6dfSMatthew G. Knepley 133884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 133984f0b6dfSMatthew G. Knepley @*/ 1340c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1341c58f1c22SToby Isaac { 13420c3c4a36SLisandro Dalcin PetscInt v, min, max; 1343c58f1c22SToby Isaac PetscErrorCode ierr; 1344c58f1c22SToby Isaac 1345c58f1c22SToby Isaac PetscFunctionBegin; 1346d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1347cade499fSVaclav Hapla if (start) {PetscValidPointer(start, 3); *start = -1;} 1348cade499fSVaclav Hapla if (end) {PetscValidPointer(end, 4); *end = -1;} 13490c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 13500c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1351c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 13520c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 1353d6cb179aSToby Isaac ierr = ISGetMinMax(label->points[v], &min, &max);CHKERRQ(ierr); 1354d6cb179aSToby Isaac if (start) *start = min; 1355d6cb179aSToby Isaac if (end) *end = max+1; 1356c58f1c22SToby Isaac PetscFunctionReturn(0); 1357c58f1c22SToby Isaac } 1358c58f1c22SToby Isaac 135984f0b6dfSMatthew G. Knepley /*@ 136084f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 136184f0b6dfSMatthew G. Knepley 13625b5e7992SMatthew G. Knepley Not collective 13635b5e7992SMatthew G. Knepley 136484f0b6dfSMatthew G. Knepley Input Parameters: 136584f0b6dfSMatthew G. Knepley + label - the DMLabel 136684f0b6dfSMatthew G. Knepley - value - the stratum value 136784f0b6dfSMatthew G. Knepley 136801d2d390SJose E. Roman Output Parameter: 136984f0b6dfSMatthew G. Knepley . points - The stratum points 137084f0b6dfSMatthew G. Knepley 137184f0b6dfSMatthew G. Knepley Level: intermediate 137284f0b6dfSMatthew G. Knepley 1373593ce467SVaclav Hapla Notes: 1374593ce467SVaclav Hapla The output IS should be destroyed when no longer needed. 1375593ce467SVaclav Hapla Returns NULL if the stratum is empty. 1376593ce467SVaclav Hapla 137784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 137884f0b6dfSMatthew G. Knepley @*/ 1379c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1380c58f1c22SToby Isaac { 1381c58f1c22SToby Isaac PetscInt v; 1382c58f1c22SToby Isaac PetscErrorCode ierr; 1383c58f1c22SToby Isaac 1384c58f1c22SToby Isaac PetscFunctionBegin; 1385d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1386c58f1c22SToby Isaac PetscValidPointer(points, 3); 1387c58f1c22SToby Isaac *points = NULL; 13880c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 13890c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1390c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 1391ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) label->points[v]);CHKERRQ(ierr); 1392ad8374ffSToby Isaac *points = label->points[v]; 1393c58f1c22SToby Isaac PetscFunctionReturn(0); 1394c58f1c22SToby Isaac } 1395c58f1c22SToby Isaac 139684f0b6dfSMatthew G. Knepley /*@ 139784f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 139884f0b6dfSMatthew G. Knepley 13995b5e7992SMatthew G. Knepley Not collective 14005b5e7992SMatthew G. Knepley 140184f0b6dfSMatthew G. Knepley Input Parameters: 140284f0b6dfSMatthew G. Knepley + label - the DMLabel 140384f0b6dfSMatthew G. Knepley . value - the stratum value 140484f0b6dfSMatthew G. Knepley - points - The stratum points 140584f0b6dfSMatthew G. Knepley 140684f0b6dfSMatthew G. Knepley Level: intermediate 140784f0b6dfSMatthew G. Knepley 140884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 140984f0b6dfSMatthew G. Knepley @*/ 14104de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 14114de306b1SToby Isaac { 14120c3c4a36SLisandro Dalcin PetscInt v; 14134de306b1SToby Isaac PetscErrorCode ierr; 14144de306b1SToby Isaac 14154de306b1SToby Isaac PetscFunctionBegin; 1416d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1417d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 1418b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 14194de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 14204de306b1SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 14214de306b1SToby Isaac ierr = ISGetLocalSize(is, &(label->stratumSizes[v]));CHKERRQ(ierr); 14224de306b1SToby Isaac ierr = PetscObjectReference((PetscObject)is);CHKERRQ(ierr); 14234de306b1SToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 14240c3c4a36SLisandro Dalcin label->points[v] = is; 14250c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 1426277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 14274de306b1SToby Isaac if (label->bt) { 14284de306b1SToby Isaac const PetscInt *points; 14294de306b1SToby Isaac PetscInt p; 14304de306b1SToby Isaac 14314de306b1SToby Isaac ierr = ISGetIndices(is,&points);CHKERRQ(ierr); 14324de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 14334de306b1SToby Isaac const PetscInt point = points[p]; 14344de306b1SToby Isaac 14354de306b1SToby Isaac if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 14364de306b1SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 14374de306b1SToby Isaac } 14384de306b1SToby Isaac } 14394de306b1SToby Isaac PetscFunctionReturn(0); 14404de306b1SToby Isaac } 14414de306b1SToby Isaac 144284f0b6dfSMatthew G. Knepley /*@ 144384f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 14444de306b1SToby Isaac 14455b5e7992SMatthew G. Knepley Not collective 14465b5e7992SMatthew G. Knepley 144784f0b6dfSMatthew G. Knepley Input Parameters: 144884f0b6dfSMatthew G. Knepley + label - the DMLabel 144984f0b6dfSMatthew G. Knepley - value - the stratum value 145084f0b6dfSMatthew G. Knepley 145184f0b6dfSMatthew G. Knepley Level: intermediate 145284f0b6dfSMatthew G. Knepley 145384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 145484f0b6dfSMatthew G. Knepley @*/ 1455c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1456c58f1c22SToby Isaac { 1457c58f1c22SToby Isaac PetscInt v; 1458c58f1c22SToby Isaac PetscErrorCode ierr; 1459c58f1c22SToby Isaac 1460c58f1c22SToby Isaac PetscFunctionBegin; 1461d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 14620c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 14630c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 14644de306b1SToby Isaac if (label->validIS[v]) { 14654de306b1SToby Isaac if (label->bt) { 1466c58f1c22SToby Isaac PetscInt i; 1467ad8374ffSToby Isaac const PetscInt *points; 1468c58f1c22SToby Isaac 1469ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 1470c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1471ad8374ffSToby Isaac const PetscInt point = points[i]; 1472c58f1c22SToby Isaac 1473c58f1c22SToby Isaac if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd); 1474c58f1c22SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 1475c58f1c22SToby Isaac } 1476ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 1477c58f1c22SToby Isaac } 1478c58f1c22SToby Isaac label->stratumSizes[v] = 0; 14790c3c4a36SLisandro Dalcin ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 1480277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v]);CHKERRQ(ierr); 14810c3c4a36SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr); 1482277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 1483c58f1c22SToby Isaac } else { 1484b9907514SLisandro Dalcin ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr); 1485c58f1c22SToby Isaac } 1486c58f1c22SToby Isaac PetscFunctionReturn(0); 1487c58f1c22SToby Isaac } 1488c58f1c22SToby Isaac 148984f0b6dfSMatthew G. Knepley /*@ 1490412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1491412e9a14SMatthew G. Knepley 1492412e9a14SMatthew G. Knepley Not collective 1493412e9a14SMatthew G. Knepley 1494412e9a14SMatthew G. Knepley Input Parameters: 1495412e9a14SMatthew G. Knepley + label - The DMLabel 1496412e9a14SMatthew G. Knepley . value - The label value for all points 1497412e9a14SMatthew G. Knepley . pStart - The first point 1498412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1499412e9a14SMatthew G. Knepley 1500412e9a14SMatthew G. Knepley Note: The marks points are [pStart, pEnd), and only the bounds are stored. 1501412e9a14SMatthew G. Knepley 1502412e9a14SMatthew G. Knepley Level: intermediate 1503412e9a14SMatthew G. Knepley 1504412e9a14SMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelSetStratumIS(), DMLabelGetStratumIS() 1505412e9a14SMatthew G. Knepley @*/ 1506412e9a14SMatthew G. Knepley PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1507412e9a14SMatthew G. Knepley { 1508412e9a14SMatthew G. Knepley IS pIS; 1509412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1510412e9a14SMatthew G. Knepley 1511412e9a14SMatthew G. Knepley PetscFunctionBegin; 1512412e9a14SMatthew G. Knepley ierr = ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS);CHKERRQ(ierr); 1513412e9a14SMatthew G. Knepley ierr = DMLabelSetStratumIS(label, value, pIS);CHKERRQ(ierr); 1514412e9a14SMatthew G. Knepley ierr = ISDestroy(&pIS);CHKERRQ(ierr); 1515412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1516412e9a14SMatthew G. Knepley } 1517412e9a14SMatthew G. Knepley 1518412e9a14SMatthew G. Knepley /*@ 1519d123abd9SMatthew G. Knepley DMLabelGetStratumPointIndex - Get the index of a point in a given stratum 1520d123abd9SMatthew G. Knepley 1521d123abd9SMatthew G. Knepley Not collective 1522d123abd9SMatthew G. Knepley 1523d123abd9SMatthew G. Knepley Input Parameters: 1524d123abd9SMatthew G. Knepley + label - The DMLabel 1525d123abd9SMatthew G. Knepley . value - The label value 1526d123abd9SMatthew G. Knepley - p - A point with this value 1527d123abd9SMatthew G. Knepley 1528d123abd9SMatthew G. Knepley Output Parameter: 1529d123abd9SMatthew 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 1530d123abd9SMatthew G. Knepley 1531d123abd9SMatthew G. Knepley Level: intermediate 1532d123abd9SMatthew G. Knepley 1533d123abd9SMatthew G. Knepley .seealso: DMLabelGetValueIndex(), DMLabelGetStratumIS(), DMLabelCreate() 1534d123abd9SMatthew G. Knepley @*/ 1535d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index) 1536d123abd9SMatthew G. Knepley { 1537d123abd9SMatthew G. Knepley const PetscInt *indices; 1538d123abd9SMatthew G. Knepley PetscInt v; 1539d123abd9SMatthew G. Knepley PetscErrorCode ierr; 1540d123abd9SMatthew G. Knepley 1541d123abd9SMatthew G. Knepley PetscFunctionBegin; 1542d123abd9SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1543d123abd9SMatthew G. Knepley PetscValidPointer(index, 4); 1544d123abd9SMatthew G. Knepley *index = -1; 1545d123abd9SMatthew G. Knepley ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 1546d123abd9SMatthew G. Knepley if (v < 0) PetscFunctionReturn(0); 1547d123abd9SMatthew G. Knepley ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 1548d123abd9SMatthew G. Knepley ierr = ISGetIndices(label->points[v], &indices);CHKERRQ(ierr); 1549d123abd9SMatthew G. Knepley ierr = PetscFindInt(p, label->stratumSizes[v], indices, index);CHKERRQ(ierr); 1550d123abd9SMatthew G. Knepley ierr = ISRestoreIndices(label->points[v], &indices);CHKERRQ(ierr); 1551d123abd9SMatthew G. Knepley PetscFunctionReturn(0); 1552d123abd9SMatthew G. Knepley } 1553d123abd9SMatthew G. Knepley 1554d123abd9SMatthew G. Knepley /*@ 155584f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 155684f0b6dfSMatthew G. Knepley 15575b5e7992SMatthew G. Knepley Not collective 15585b5e7992SMatthew G. Knepley 155984f0b6dfSMatthew G. Knepley Input Parameters: 156084f0b6dfSMatthew G. Knepley + label - the DMLabel 156122cd2cdaSVaclav Hapla . start - the first point kept 156222cd2cdaSVaclav Hapla - end - one more than the last point kept 156384f0b6dfSMatthew G. Knepley 156484f0b6dfSMatthew G. Knepley Level: intermediate 156584f0b6dfSMatthew G. Knepley 156684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 156784f0b6dfSMatthew G. Knepley @*/ 1568c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1569c58f1c22SToby Isaac { 1570c58f1c22SToby Isaac PetscInt v; 1571c58f1c22SToby Isaac PetscErrorCode ierr; 1572c58f1c22SToby Isaac 1573c58f1c22SToby Isaac PetscFunctionBegin; 1574d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 15750c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 1576c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1577c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 15789106b633SVaclav Hapla ierr = ISGeneralFilter(label->points[v], start, end);CHKERRQ(ierr); 1579c58f1c22SToby Isaac } 1580c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, start, end);CHKERRQ(ierr); 1581c58f1c22SToby Isaac PetscFunctionReturn(0); 1582c58f1c22SToby Isaac } 1583c58f1c22SToby Isaac 158484f0b6dfSMatthew G. Knepley /*@ 158584f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 158684f0b6dfSMatthew G. Knepley 15875b5e7992SMatthew G. Knepley Not collective 15885b5e7992SMatthew G. Knepley 158984f0b6dfSMatthew G. Knepley Input Parameters: 159084f0b6dfSMatthew G. Knepley + label - the DMLabel 159184f0b6dfSMatthew G. Knepley - permutation - the point permutation 159284f0b6dfSMatthew G. Knepley 159384f0b6dfSMatthew G. Knepley Output Parameter: 159484f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 159584f0b6dfSMatthew G. Knepley 159684f0b6dfSMatthew G. Knepley Level: intermediate 159784f0b6dfSMatthew G. Knepley 159884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 159984f0b6dfSMatthew G. Knepley @*/ 1600c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1601c58f1c22SToby Isaac { 1602c58f1c22SToby Isaac const PetscInt *perm; 1603c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1604c58f1c22SToby Isaac PetscErrorCode ierr; 1605c58f1c22SToby Isaac 1606c58f1c22SToby Isaac PetscFunctionBegin; 1607d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1608d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 1609c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1610c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, labelNew);CHKERRQ(ierr); 1611c58f1c22SToby Isaac ierr = DMLabelGetNumValues(*labelNew, &numValues);CHKERRQ(ierr); 1612c58f1c22SToby Isaac ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr); 1613c58f1c22SToby Isaac ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr); 1614c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1615c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1616ad8374ffSToby Isaac const PetscInt *points; 1617ad8374ffSToby Isaac PetscInt *pointsNew; 1618c58f1c22SToby Isaac 1619ad8374ffSToby Isaac ierr = ISGetIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1620ad8374ffSToby Isaac ierr = PetscMalloc1(size,&pointsNew);CHKERRQ(ierr); 1621c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1622ad8374ffSToby Isaac const PetscInt point = points[q]; 1623c58f1c22SToby Isaac 1624c58f1c22SToby Isaac if ((point < 0) || (point >= numPoints)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [0, %D) for the remapping", point, numPoints); 1625ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1626c58f1c22SToby Isaac } 1627ad8374ffSToby Isaac ierr = ISRestoreIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1628ad8374ffSToby Isaac ierr = PetscSortInt(size, pointsNew);CHKERRQ(ierr); 1629ad8374ffSToby Isaac ierr = ISDestroy(&((*labelNew)->points[v]));CHKERRQ(ierr); 1630fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 1631fa8e8ae5SToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]));CHKERRQ(ierr); 1632fa8e8ae5SToby Isaac ierr = PetscFree(pointsNew);CHKERRQ(ierr); 1633fa8e8ae5SToby Isaac } else { 1634ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]));CHKERRQ(ierr); 1635fa8e8ae5SToby Isaac } 1636ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices");CHKERRQ(ierr); 1637c58f1c22SToby Isaac } 1638c58f1c22SToby Isaac ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr); 1639c58f1c22SToby Isaac if (label->bt) { 1640c58f1c22SToby Isaac ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 1641c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 1642c58f1c22SToby Isaac } 1643c58f1c22SToby Isaac PetscFunctionReturn(0); 1644c58f1c22SToby Isaac } 1645c58f1c22SToby Isaac 164626c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 164726c55118SMichael Lange { 164826c55118SMichael Lange MPI_Comm comm; 164926c55118SMichael Lange PetscInt s, l, nroots, nleaves, dof, offset, size; 165026c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 165126c55118SMichael Lange PetscSection rootSection; 165226c55118SMichael Lange PetscSF labelSF; 165326c55118SMichael Lange PetscErrorCode ierr; 165426c55118SMichael Lange 165526c55118SMichael Lange PetscFunctionBegin; 165626c55118SMichael Lange if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 165726c55118SMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 165826c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 165926c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 166026c55118SMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL);CHKERRQ(ierr); 166126c55118SMichael Lange ierr = PetscSectionCreate(comm, &rootSection);CHKERRQ(ierr); 166226c55118SMichael Lange ierr = PetscSectionSetChart(rootSection, 0, nroots);CHKERRQ(ierr); 166326c55118SMichael Lange if (label) { 166426c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1665ad8374ffSToby Isaac const PetscInt *points; 1666ad8374ffSToby Isaac 1667ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 166826c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1669ad8374ffSToby Isaac ierr = PetscSectionGetDof(rootSection, points[l], &dof);CHKERRQ(ierr); 1670ad8374ffSToby Isaac ierr = PetscSectionSetDof(rootSection, points[l], dof+1);CHKERRQ(ierr); 167126c55118SMichael Lange } 1672ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 167326c55118SMichael Lange } 167426c55118SMichael Lange } 167526c55118SMichael Lange ierr = PetscSectionSetUp(rootSection);CHKERRQ(ierr); 167626c55118SMichael Lange /* Create a point-wise array of stratum values */ 167726c55118SMichael Lange ierr = PetscSectionGetStorageSize(rootSection, &size);CHKERRQ(ierr); 167826c55118SMichael Lange ierr = PetscMalloc1(size, &rootStrata);CHKERRQ(ierr); 167926c55118SMichael Lange ierr = PetscCalloc1(nroots, &rootIdx);CHKERRQ(ierr); 168026c55118SMichael Lange if (label) { 168126c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1682ad8374ffSToby Isaac const PetscInt *points; 1683ad8374ffSToby Isaac 1684ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 168526c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1686ad8374ffSToby Isaac const PetscInt p = points[l]; 168726c55118SMichael Lange ierr = PetscSectionGetOffset(rootSection, p, &offset);CHKERRQ(ierr); 168826c55118SMichael Lange rootStrata[offset+rootIdx[p]++] = label->stratumValues[s]; 168926c55118SMichael Lange } 1690ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 169126c55118SMichael Lange } 169226c55118SMichael Lange } 169326c55118SMichael Lange /* Build SF that maps label points to remote processes */ 169426c55118SMichael Lange ierr = PetscSectionCreate(comm, leafSection);CHKERRQ(ierr); 169526c55118SMichael Lange ierr = PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection);CHKERRQ(ierr); 169626c55118SMichael Lange ierr = PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF);CHKERRQ(ierr); 169726c55118SMichael Lange ierr = PetscFree(remoteOffsets);CHKERRQ(ierr); 169826c55118SMichael Lange /* Send the strata for each point over the derived SF */ 169926c55118SMichael Lange ierr = PetscSectionGetStorageSize(*leafSection, &size);CHKERRQ(ierr); 170026c55118SMichael Lange ierr = PetscMalloc1(size, leafStrata);CHKERRQ(ierr); 1701ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE);CHKERRQ(ierr); 1702ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE);CHKERRQ(ierr); 170326c55118SMichael Lange /* Clean up */ 170426c55118SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 170526c55118SMichael Lange ierr = PetscFree(rootIdx);CHKERRQ(ierr); 170626c55118SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 170726c55118SMichael Lange ierr = PetscSFDestroy(&labelSF);CHKERRQ(ierr); 170826c55118SMichael Lange PetscFunctionReturn(0); 170926c55118SMichael Lange } 171026c55118SMichael Lange 171184f0b6dfSMatthew G. Knepley /*@ 171284f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 171384f0b6dfSMatthew G. Knepley 17145b5e7992SMatthew G. Knepley Collective on sf 17155b5e7992SMatthew G. Knepley 171684f0b6dfSMatthew G. Knepley Input Parameters: 171784f0b6dfSMatthew G. Knepley + label - the DMLabel 171884f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 171984f0b6dfSMatthew G. Knepley 172084f0b6dfSMatthew G. Knepley Output Parameter: 172184f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 172284f0b6dfSMatthew G. Knepley 172384f0b6dfSMatthew G. Knepley Level: intermediate 172484f0b6dfSMatthew G. Knepley 172584f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 172684f0b6dfSMatthew G. Knepley @*/ 1727c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1728c58f1c22SToby Isaac { 1729c58f1c22SToby Isaac MPI_Comm comm; 173026c55118SMichael Lange PetscSection leafSection; 173126c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 173226c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1733ad8374ffSToby Isaac PetscInt **points; 1734d67d17b1SMatthew G. Knepley const char *lname = NULL; 1735c58f1c22SToby Isaac char *name; 1736c58f1c22SToby Isaac PetscInt nameSize; 1737e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1738c58f1c22SToby Isaac size_t len = 0; 173926c55118SMichael Lange PetscMPIInt rank; 1740c58f1c22SToby Isaac PetscErrorCode ierr; 1741c58f1c22SToby Isaac 1742c58f1c22SToby Isaac PetscFunctionBegin; 1743d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1744f018e600SMatthew G. Knepley if (label) { 1745f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1746f018e600SMatthew G. Knepley ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1747f018e600SMatthew G. Knepley } 1748c58f1c22SToby Isaac ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 1749ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1750c58f1c22SToby Isaac /* Bcast name */ 1751dd400576SPatrick Sanan if (rank == 0) { 1752d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 1753d67d17b1SMatthew G. Knepley ierr = PetscStrlen(lname, &len);CHKERRQ(ierr); 1754d67d17b1SMatthew G. Knepley } 1755c58f1c22SToby Isaac nameSize = len; 1756ffc4695bSBarry Smith ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1757c58f1c22SToby Isaac ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1758dd400576SPatrick Sanan if (rank == 0) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);} 1759ffc4695bSBarry Smith ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr); 1760d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr); 1761c58f1c22SToby Isaac ierr = PetscFree(name);CHKERRQ(ierr); 176277d236dfSMichael Lange /* Bcast defaultValue */ 1763dd400576SPatrick Sanan if (rank == 0) (*labelNew)->defaultValue = label->defaultValue; 1764ffc4695bSBarry Smith ierr = MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 176526c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 176626c55118SMichael Lange ierr = DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata);CHKERRQ(ierr); 17675cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 1768e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&stratumHash);CHKERRQ(ierr); 176926c55118SMichael Lange ierr = PetscSectionGetStorageSize(leafSection, &size);CHKERRQ(ierr); 1770e8f14785SLisandro Dalcin for (p = 0; p < size; ++p) {ierr = PetscHSetIAdd(stratumHash, leafStrata[p]);CHKERRQ(ierr);} 1771e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata);CHKERRQ(ierr); 1772ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS);CHKERRQ(ierr); 1773ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 17745cbdf6fcSMichael Lange ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues);CHKERRQ(ierr); 17755cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 17765cbdf6fcSMichael Lange offset = 0; 1777e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues);CHKERRQ(ierr); 1778a205f1fdSToby Isaac ierr = PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues);CHKERRQ(ierr); 177990e9b2aeSLisandro Dalcin for (s = 0; s < (*labelNew)->numStrata; ++s) { 178090e9b2aeSLisandro Dalcin ierr = PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s);CHKERRQ(ierr); 178190e9b2aeSLisandro Dalcin } 17825cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1783231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 1784231b9e6fSMatthew G. Knepley if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;} 17855cbdf6fcSMichael Lange } 17865cbdf6fcSMichael Lange } 1787c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 1788c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes);CHKERRQ(ierr); 1789c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1790c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1791c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1792c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1793c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1794c58f1c22SToby Isaac (*labelNew)->stratumSizes[leafStrata[offset+s]]++; 1795c58f1c22SToby Isaac } 1796c58f1c22SToby Isaac } 1797c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht);CHKERRQ(ierr); 1798c58f1c22SToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points);CHKERRQ(ierr); 1799ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&points);CHKERRQ(ierr); 1800c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 1801e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelNew)->ht[s]);CHKERRQ(ierr); 1802ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]));CHKERRQ(ierr); 1803c58f1c22SToby Isaac } 1804c58f1c22SToby Isaac /* Insert points into new strata */ 1805c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata, &strataIdx);CHKERRQ(ierr); 1806c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1807c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1808c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1809c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1810c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1811c58f1c22SToby Isaac stratum = leafStrata[offset+s]; 1812ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1813c58f1c22SToby Isaac } 1814c58f1c22SToby Isaac } 1815ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1816ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]));CHKERRQ(ierr); 1817ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices");CHKERRQ(ierr); 1818ad8374ffSToby Isaac } 1819ad8374ffSToby Isaac ierr = PetscFree(points);CHKERRQ(ierr); 1820e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&stratumHash);CHKERRQ(ierr); 1821c58f1c22SToby Isaac ierr = PetscFree(leafStrata);CHKERRQ(ierr); 1822c58f1c22SToby Isaac ierr = PetscFree(strataIdx);CHKERRQ(ierr); 1823c58f1c22SToby Isaac ierr = PetscSectionDestroy(&leafSection);CHKERRQ(ierr); 1824c58f1c22SToby Isaac PetscFunctionReturn(0); 1825c58f1c22SToby Isaac } 1826c58f1c22SToby Isaac 18277937d9ceSMichael Lange /*@ 18287937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 18297937d9ceSMichael Lange 18305b5e7992SMatthew G. Knepley Collective on sf 18315b5e7992SMatthew G. Knepley 18327937d9ceSMichael Lange Input Parameters: 18337937d9ceSMichael Lange + label - the DMLabel 183484f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 18357937d9ceSMichael Lange 183684f0b6dfSMatthew G. Knepley Output Parameters: 183784f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 18387937d9ceSMichael Lange 18397937d9ceSMichael Lange Level: developer 18407937d9ceSMichael Lange 18417937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 18427937d9ceSMichael Lange 18437937d9ceSMichael Lange .seealso: DMLabelDistribute() 18447937d9ceSMichael Lange @*/ 18457937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 18467937d9ceSMichael Lange { 18477937d9ceSMichael Lange MPI_Comm comm; 18487937d9ceSMichael Lange PetscSection rootSection; 18497937d9ceSMichael Lange PetscSF sfLabel; 18507937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 18517937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 18527937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 18537937d9ceSMichael Lange PetscInt *rootStrata; 1854d67d17b1SMatthew G. Knepley const char *lname; 18557937d9ceSMichael Lange char *name; 18567937d9ceSMichael Lange PetscInt nameSize; 18577937d9ceSMichael Lange size_t len = 0; 18589852e123SBarry Smith PetscMPIInt rank, size; 18597937d9ceSMichael Lange PetscErrorCode ierr; 18607937d9ceSMichael Lange 18617937d9ceSMichael Lange PetscFunctionBegin; 1862d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1863d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 18647937d9ceSMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 1865ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1866ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 18677937d9ceSMichael Lange /* Bcast name */ 1868dd400576SPatrick Sanan if (rank == 0) { 1869d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 1870d67d17b1SMatthew G. Knepley ierr = PetscStrlen(lname, &len);CHKERRQ(ierr); 1871d67d17b1SMatthew G. Knepley } 18727937d9ceSMichael Lange nameSize = len; 1873ffc4695bSBarry Smith ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 18747937d9ceSMichael Lange ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1875dd400576SPatrick Sanan if (rank == 0) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);} 1876ffc4695bSBarry Smith ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr); 1877d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr); 18787937d9ceSMichael Lange ierr = PetscFree(name);CHKERRQ(ierr); 18797937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 18807937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 18817937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 18827937d9ceSMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL);CHKERRQ(ierr); 1883dc53bc9bSMatthew G. Knepley ierr = PetscMalloc1(nroots, &leafPoints);CHKERRQ(ierr); 1884dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 18857937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 18868212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 18878212dd46SStefano Zampini 18888212dd46SStefano Zampini leafPoints[ilp].index = ilp; 18898212dd46SStefano Zampini leafPoints[ilp].rank = rank; 18907937d9ceSMichael Lange } 18917937d9ceSMichael Lange ierr = PetscSFComputeDegreeBegin(sf, &rootDegree);CHKERRQ(ierr); 18927937d9ceSMichael Lange ierr = PetscSFComputeDegreeEnd(sf, &rootDegree);CHKERRQ(ierr); 18937937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 18947937d9ceSMichael Lange ierr = PetscMalloc1(nmultiroots, &rootPoints);CHKERRQ(ierr); 18957937d9ceSMichael Lange ierr = PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 18967937d9ceSMichael Lange ierr = PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 18977937d9ceSMichael Lange ierr = PetscSFCreate(comm,& sfLabel);CHKERRQ(ierr); 18987937d9ceSMichael Lange ierr = PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 18997937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 19007937d9ceSMichael Lange ierr = DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata);CHKERRQ(ierr); 19017937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 19027937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 19037937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 19047937d9ceSMichael Lange ierr = PetscSectionGetDof(rootSection, idx+d, &dof);CHKERRQ(ierr); 19057937d9ceSMichael Lange ierr = PetscSectionGetOffset(rootSection, idx+d, &offset);CHKERRQ(ierr); 19067937d9ceSMichael Lange for (s = 0; s < dof; s++) {ierr = DMLabelSetValue(*labelNew, p, rootStrata[offset+s]);CHKERRQ(ierr);} 19077937d9ceSMichael Lange } 19087937d9ceSMichael Lange idx += rootDegree[p]; 19097937d9ceSMichael Lange } 191077e0c0e7SMichael Lange ierr = PetscFree(leafPoints);CHKERRQ(ierr); 191177e0c0e7SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 191277e0c0e7SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 191377e0c0e7SMichael Lange ierr = PetscSFDestroy(&sfLabel);CHKERRQ(ierr); 19147937d9ceSMichael Lange PetscFunctionReturn(0); 19157937d9ceSMichael Lange } 19167937d9ceSMichael Lange 191784f0b6dfSMatthew G. Knepley /*@ 191884f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 191984f0b6dfSMatthew G. Knepley 19205b5e7992SMatthew G. Knepley Not collective 19215b5e7992SMatthew G. Knepley 192284f0b6dfSMatthew G. Knepley Input Parameter: 192384f0b6dfSMatthew G. Knepley . label - the DMLabel 192484f0b6dfSMatthew G. Knepley 192584f0b6dfSMatthew G. Knepley Output Parameters: 192684f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 192784f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 192884f0b6dfSMatthew G. Knepley 192984f0b6dfSMatthew G. Knepley Level: developer 193084f0b6dfSMatthew G. Knepley 193184f0b6dfSMatthew G. Knepley .seealso: DMLabelDistribute() 193284f0b6dfSMatthew G. Knepley @*/ 1933c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 1934c58f1c22SToby Isaac { 1935c58f1c22SToby Isaac IS vIS; 1936c58f1c22SToby Isaac const PetscInt *values; 1937c58f1c22SToby Isaac PetscInt *points; 1938c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 1939c58f1c22SToby Isaac PetscErrorCode ierr; 1940c58f1c22SToby Isaac 1941c58f1c22SToby Isaac PetscFunctionBegin; 1942d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1943c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr); 1944c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr); 1945c58f1c22SToby Isaac ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr); 1946c58f1c22SToby Isaac if (nV) {vS = values[0]; vE = values[0]+1;} 1947c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 1948c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 1949c58f1c22SToby Isaac vE = PetscMax(vE, values[v]+1); 1950c58f1c22SToby Isaac } 1951c58f1c22SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr); 1952c58f1c22SToby Isaac ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr); 1953c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1954c58f1c22SToby Isaac PetscInt n; 1955c58f1c22SToby Isaac 1956c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr); 1957c58f1c22SToby Isaac ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr); 1958c58f1c22SToby Isaac } 1959c58f1c22SToby Isaac ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 1960c58f1c22SToby Isaac ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr); 1961c58f1c22SToby Isaac ierr = PetscMalloc1(N, &points);CHKERRQ(ierr); 1962c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1963c58f1c22SToby Isaac IS is; 1964c58f1c22SToby Isaac const PetscInt *spoints; 1965c58f1c22SToby Isaac PetscInt dof, off, p; 1966c58f1c22SToby Isaac 1967c58f1c22SToby Isaac ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr); 1968c58f1c22SToby Isaac ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr); 1969c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr); 1970c58f1c22SToby Isaac ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr); 1971c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; 1972c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr); 1973c58f1c22SToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 1974c58f1c22SToby Isaac } 1975c58f1c22SToby Isaac ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr); 1976c58f1c22SToby Isaac ierr = ISDestroy(&vIS);CHKERRQ(ierr); 1977c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 1978c58f1c22SToby Isaac PetscFunctionReturn(0); 1979c58f1c22SToby Isaac } 1980c58f1c22SToby Isaac 198184f0b6dfSMatthew G. Knepley /*@ 1982c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 1983c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 1984c58f1c22SToby Isaac 19855b5e7992SMatthew G. Knepley Collective on sf 19865b5e7992SMatthew G. Knepley 1987c58f1c22SToby Isaac Input Parameters: 1988c58f1c22SToby Isaac + s - The PetscSection for the local field layout 1989c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 1990c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 1991c58f1c22SToby Isaac . label - The label specifying the points 1992c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 1993c58f1c22SToby Isaac 1994c58f1c22SToby Isaac Output Parameter: 1995c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 1996c58f1c22SToby Isaac 1997c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 1998c58f1c22SToby Isaac 1999c58f1c22SToby Isaac Level: developer 2000c58f1c22SToby Isaac 2001c58f1c22SToby Isaac .seealso: PetscSectionCreate() 2002c58f1c22SToby Isaac @*/ 2003c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 2004c58f1c22SToby Isaac { 2005c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 2006c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 2007c58f1c22SToby Isaac PetscErrorCode ierr; 2008c58f1c22SToby Isaac 2009c58f1c22SToby Isaac PetscFunctionBegin; 2010d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 2011d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 2012d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 2013c58f1c22SToby Isaac ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr); 2014c58f1c22SToby Isaac ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 2015c58f1c22SToby Isaac ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr); 2016c58f1c22SToby Isaac ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2017c58f1c22SToby Isaac if (nroots >= 0) { 2018c58f1c22SToby Isaac if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart); 2019c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr); 2020c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 2021c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr); 2022c58f1c22SToby Isaac } else { 2023c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 2024c58f1c22SToby Isaac } 2025c58f1c22SToby Isaac } 2026c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 2027c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 2028c58f1c22SToby Isaac PetscInt value; 2029c58f1c22SToby Isaac 2030c58f1c22SToby Isaac ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr); 2031c58f1c22SToby Isaac if (value != labelValue) continue; 2032c58f1c22SToby Isaac ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 2033c58f1c22SToby Isaac ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr); 2034c58f1c22SToby Isaac ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 2035c58f1c22SToby Isaac if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);} 2036c58f1c22SToby Isaac if (neg) neg[p] = -(dof+1); 2037c58f1c22SToby Isaac } 2038c58f1c22SToby Isaac ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr); 2039c58f1c22SToby Isaac if (nroots >= 0) { 2040ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 2041ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 2042c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 2043c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 2044c58f1c22SToby Isaac } 2045c58f1c22SToby Isaac } 2046c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 2047c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 2048c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 2049c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 2050c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 2051c58f1c22SToby Isaac } 205255b25c41SPierre Jolivet ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRMPI(ierr); 2053c58f1c22SToby Isaac globalOff -= off; 2054c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 2055c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 2056c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 2057c58f1c22SToby Isaac } 2058c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 2059c58f1c22SToby Isaac if (nroots >= 0) { 2060ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 2061ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 2062c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 2063c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 2064c58f1c22SToby Isaac } 2065c58f1c22SToby Isaac } 2066c58f1c22SToby Isaac if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);} 2067c58f1c22SToby Isaac ierr = PetscFree(neg);CHKERRQ(ierr); 2068c58f1c22SToby Isaac PetscFunctionReturn(0); 2069c58f1c22SToby Isaac } 2070c58f1c22SToby Isaac 20715fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label 20725fdea053SToby Isaac { 20735fdea053SToby Isaac DMLabel label; 20745fdea053SToby Isaac PetscCopyMode *modes; 20755fdea053SToby Isaac PetscInt *sizes; 20765fdea053SToby Isaac const PetscInt ***perms; 20775fdea053SToby Isaac const PetscScalar ***rots; 20785fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 20795fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 20805fdea053SToby Isaac } PetscSectionSym_Label; 20815fdea053SToby Isaac 20825fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 20835fdea053SToby Isaac { 20845fdea053SToby Isaac PetscInt i, j; 20855fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 20865fdea053SToby Isaac PetscErrorCode ierr; 20875fdea053SToby Isaac 20885fdea053SToby Isaac PetscFunctionBegin; 20895fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 20905fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 20915fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 20925fdea053SToby Isaac if (sl->perms[i]) {ierr = PetscFree(sl->perms[i][j]);CHKERRQ(ierr);} 20935fdea053SToby Isaac if (sl->rots[i]) {ierr = PetscFree(sl->rots[i][j]);CHKERRQ(ierr);} 20945fdea053SToby Isaac } 20955fdea053SToby Isaac if (sl->perms[i]) { 20965fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 20975fdea053SToby Isaac 20985fdea053SToby Isaac ierr = PetscFree(perms);CHKERRQ(ierr); 20995fdea053SToby Isaac } 21005fdea053SToby Isaac if (sl->rots[i]) { 21015fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 21025fdea053SToby Isaac 21035fdea053SToby Isaac ierr = PetscFree(rots);CHKERRQ(ierr); 21045fdea053SToby Isaac } 21055fdea053SToby Isaac } 21065fdea053SToby Isaac } 21075fdea053SToby Isaac ierr = PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients);CHKERRQ(ierr); 21085fdea053SToby Isaac ierr = DMLabelDestroy(&sl->label);CHKERRQ(ierr); 21095fdea053SToby Isaac sl->numStrata = 0; 21105fdea053SToby Isaac PetscFunctionReturn(0); 21115fdea053SToby Isaac } 21125fdea053SToby Isaac 21135fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 21145fdea053SToby Isaac { 21155fdea053SToby Isaac PetscErrorCode ierr; 21165fdea053SToby Isaac 21175fdea053SToby Isaac PetscFunctionBegin; 21185fdea053SToby Isaac ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr); 21195fdea053SToby Isaac ierr = PetscFree(sym->data);CHKERRQ(ierr); 21205fdea053SToby Isaac PetscFunctionReturn(0); 21215fdea053SToby Isaac } 21225fdea053SToby Isaac 21235fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 21245fdea053SToby Isaac { 21255fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 21265fdea053SToby Isaac PetscBool isAscii; 21275fdea053SToby Isaac DMLabel label = sl->label; 2128d67d17b1SMatthew G. Knepley const char *name; 21295fdea053SToby Isaac PetscErrorCode ierr; 21305fdea053SToby Isaac 21315fdea053SToby Isaac PetscFunctionBegin; 21325fdea053SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii);CHKERRQ(ierr); 21335fdea053SToby Isaac if (isAscii) { 21345fdea053SToby Isaac PetscInt i, j, k; 21355fdea053SToby Isaac PetscViewerFormat format; 21365fdea053SToby Isaac 21375fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 21385fdea053SToby Isaac if (label) { 21395fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 21405fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 21415fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 21425fdea053SToby Isaac ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 21435fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 21445fdea053SToby Isaac } else { 2145d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr); 2146d67d17b1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer," Label '%s'\n",name);CHKERRQ(ierr); 21475fdea053SToby Isaac } 21485fdea053SToby Isaac } else { 21495fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "No label given\n");CHKERRQ(ierr); 21505fdea053SToby Isaac } 21515fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 21525fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 21535fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 21545fdea053SToby Isaac 21555fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 21565fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point): no symmetries\n", value, sl->sizes[i]);CHKERRQ(ierr); 21575fdea053SToby Isaac } else { 21585fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point):\n", value, sl->sizes[i]);CHKERRQ(ierr); 21595fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 21605fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation range: [%D, %D)\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1]);CHKERRQ(ierr); 21615fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 21625fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 21635fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 21645fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 21655fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D: identity\n",j);CHKERRQ(ierr); 21665fdea053SToby Isaac } else { 21675fdea053SToby Isaac PetscInt tab; 21685fdea053SToby Isaac 21695fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D:\n",j);CHKERRQ(ierr); 21705fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 21715fdea053SToby Isaac ierr = PetscViewerASCIIGetTab(viewer,&tab);CHKERRQ(ierr); 21725fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 21735fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Permutation:");CHKERRQ(ierr); 21745fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 21755fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %D",sl->perms[i][j][k]);CHKERRQ(ierr);} 21765fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 21775fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 21785fdea053SToby Isaac } 21795fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 21805fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Rotations: ");CHKERRQ(ierr); 21815fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 21825fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 21835fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f+i*%+f",PetscRealPart(sl->rots[i][j][k]),PetscImaginaryPart(sl->rots[i][j][k]));CHKERRQ(ierr);} 21845fdea053SToby Isaac #else 21855fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f",sl->rots[i][j][k]);CHKERRQ(ierr);} 21865fdea053SToby Isaac #endif 21875fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 21885fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 21895fdea053SToby Isaac } 21905fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 21915fdea053SToby Isaac } 21925fdea053SToby Isaac } 21935fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 21945fdea053SToby Isaac } 21955fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 21965fdea053SToby Isaac } 21975fdea053SToby Isaac } 21985fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 21995fdea053SToby Isaac } 22005fdea053SToby Isaac PetscFunctionReturn(0); 22015fdea053SToby Isaac } 22025fdea053SToby Isaac 22035fdea053SToby Isaac /*@ 22045fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 22055fdea053SToby Isaac 22065fdea053SToby Isaac Logically collective on sym 22075fdea053SToby Isaac 22085fdea053SToby Isaac Input parameters: 22095fdea053SToby Isaac + sym - the section symmetries 22105fdea053SToby Isaac - label - the DMLabel describing the types of points 22115fdea053SToby Isaac 22125fdea053SToby Isaac Level: developer: 22135fdea053SToby Isaac 22145fdea053SToby Isaac .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreateLabel(), PetscSectionGetPointSyms() 22155fdea053SToby Isaac @*/ 22165fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 22175fdea053SToby Isaac { 22185fdea053SToby Isaac PetscSectionSym_Label *sl; 22195fdea053SToby Isaac PetscErrorCode ierr; 22205fdea053SToby Isaac 22215fdea053SToby Isaac PetscFunctionBegin; 22225fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 22235fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 22245fdea053SToby Isaac if (sl->label && sl->label != label) {ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);} 22255fdea053SToby Isaac if (label) { 22265fdea053SToby Isaac sl->label = label; 2227d67d17b1SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 22285fdea053SToby Isaac ierr = DMLabelGetNumValues(label,&sl->numStrata);CHKERRQ(ierr); 22291a834cf9SToby Isaac ierr = 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);CHKERRQ(ierr); 22301a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode));CHKERRQ(ierr); 22311a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt));CHKERRQ(ierr); 22321a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **));CHKERRQ(ierr); 22331a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **));CHKERRQ(ierr); 22341a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]));CHKERRQ(ierr); 22355fdea053SToby Isaac } 22365fdea053SToby Isaac PetscFunctionReturn(0); 22375fdea053SToby Isaac } 22385fdea053SToby Isaac 22395fdea053SToby Isaac /*@C 22405fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 22415fdea053SToby Isaac 22425b5e7992SMatthew G. Knepley Logically collective on sym 22435fdea053SToby Isaac 22445fdea053SToby Isaac InputParameters: 22455b5e7992SMatthew G. Knepley + sym - the section symmetries 22465fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 22475fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 22485fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 22495fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 22505fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 22515fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2252a2b725a8SWilliam 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 22535fdea053SToby Isaac 22545fdea053SToby Isaac Level: developer 22555fdea053SToby Isaac 22565fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel() 22575fdea053SToby Isaac @*/ 22585fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 22595fdea053SToby Isaac { 22605fdea053SToby Isaac PetscSectionSym_Label *sl; 2261d67d17b1SMatthew G. Knepley const char *name; 2262d67d17b1SMatthew G. Knepley PetscInt i, j, k; 22635fdea053SToby Isaac PetscErrorCode ierr; 22645fdea053SToby Isaac 22655fdea053SToby Isaac PetscFunctionBegin; 22665fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 22675fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 22685fdea053SToby Isaac if (!sl->label) SETERRQ(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_WRONGSTATE,"No label set yet"); 22695fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 22705fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 22715fdea053SToby Isaac 22725fdea053SToby Isaac if (stratum == value) break; 22735fdea053SToby Isaac } 2274d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr); 2275d67d17b1SMatthew G. Knepley if (i > sl->numStrata) SETERRQ2(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_OUTOFRANGE,"Stratum %D not found in label %s\n",stratum,name); 22765fdea053SToby Isaac sl->sizes[i] = size; 22775fdea053SToby Isaac sl->modes[i] = mode; 22785fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 22795fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 22805fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 22815fdea053SToby Isaac if (perms) { 22825fdea053SToby Isaac PetscInt **ownPerms; 22835fdea053SToby Isaac 22845fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownPerms);CHKERRQ(ierr); 22855fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 22865fdea053SToby Isaac if (perms[j]) { 22875fdea053SToby Isaac ierr = PetscMalloc1(size,&ownPerms[j]);CHKERRQ(ierr); 22885fdea053SToby Isaac for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];} 22895fdea053SToby Isaac } 22905fdea053SToby Isaac } 22915fdea053SToby Isaac sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient]; 22925fdea053SToby Isaac } 22935fdea053SToby Isaac if (rots) { 22945fdea053SToby Isaac PetscScalar **ownRots; 22955fdea053SToby Isaac 22965fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownRots);CHKERRQ(ierr); 22975fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 22985fdea053SToby Isaac if (rots[j]) { 22995fdea053SToby Isaac ierr = PetscMalloc1(size,&ownRots[j]);CHKERRQ(ierr); 23005fdea053SToby Isaac for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];} 23015fdea053SToby Isaac } 23025fdea053SToby Isaac } 23035fdea053SToby Isaac sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient]; 23045fdea053SToby Isaac } 23055fdea053SToby Isaac } else { 23065fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 23075fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 23085fdea053SToby Isaac } 23095fdea053SToby Isaac PetscFunctionReturn(0); 23105fdea053SToby Isaac } 23115fdea053SToby Isaac 23125fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 23135fdea053SToby Isaac { 23145fdea053SToby Isaac PetscInt i, j, numStrata; 23155fdea053SToby Isaac PetscSectionSym_Label *sl; 23165fdea053SToby Isaac DMLabel label; 23175fdea053SToby Isaac PetscErrorCode ierr; 23185fdea053SToby Isaac 23195fdea053SToby Isaac PetscFunctionBegin; 23205fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 23215fdea053SToby Isaac numStrata = sl->numStrata; 23225fdea053SToby Isaac label = sl->label; 23235fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 23245fdea053SToby Isaac PetscInt point = points[2*i]; 23255fdea053SToby Isaac PetscInt ornt = points[2*i+1]; 23265fdea053SToby Isaac 23275fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 23285fdea053SToby Isaac if (label->validIS[j]) { 23295fdea053SToby Isaac PetscInt k; 23305fdea053SToby Isaac 23315fdea053SToby Isaac ierr = ISLocate(label->points[j],point,&k);CHKERRQ(ierr); 23325fdea053SToby Isaac if (k >= 0) break; 23335fdea053SToby Isaac } else { 23345fdea053SToby Isaac PetscBool has; 23355fdea053SToby Isaac 2336b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[j], point, &has);CHKERRQ(ierr); 23375fdea053SToby Isaac if (has) break; 23385fdea053SToby Isaac } 23395fdea053SToby Isaac } 23405fdea053SToby Isaac if ((sl->minMaxOrients[j][1] > sl->minMaxOrients[j][0]) && (ornt < sl->minMaxOrients[j][0] || ornt >= sl->minMaxOrients[j][1])) SETERRQ5(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); 23415fdea053SToby Isaac if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;} 23425fdea053SToby Isaac if (rots) {rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL;} 23435fdea053SToby Isaac } 23445fdea053SToby Isaac PetscFunctionReturn(0); 23455fdea053SToby Isaac } 23465fdea053SToby Isaac 23475fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 23485fdea053SToby Isaac { 23495fdea053SToby Isaac PetscSectionSym_Label *sl; 23505fdea053SToby Isaac PetscErrorCode ierr; 23515fdea053SToby Isaac 23525fdea053SToby Isaac PetscFunctionBegin; 23535fdea053SToby Isaac ierr = PetscNewLog(sym,&sl);CHKERRQ(ierr); 23545fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 23555fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 23565fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 23575fdea053SToby Isaac sym->data = (void *) sl; 23585fdea053SToby Isaac PetscFunctionReturn(0); 23595fdea053SToby Isaac } 23605fdea053SToby Isaac 23615fdea053SToby Isaac /*@ 23625fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 23635fdea053SToby Isaac 23645fdea053SToby Isaac Collective 23655fdea053SToby Isaac 23665fdea053SToby Isaac Input Parameters: 23675fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 23685fdea053SToby Isaac - label - the label defining the strata 23695fdea053SToby Isaac 23705fdea053SToby Isaac Output Parameters: 23715fdea053SToby Isaac . sym - the section symmetries 23725fdea053SToby Isaac 23735fdea053SToby Isaac Level: developer 23745fdea053SToby Isaac 23755fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym(), PetscSectionSymLabelSetStratum(), PetscSectionGetPointSyms() 23765fdea053SToby Isaac @*/ 23775fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 23785fdea053SToby Isaac { 23795fdea053SToby Isaac PetscErrorCode ierr; 23805fdea053SToby Isaac 23815fdea053SToby Isaac PetscFunctionBegin; 23825fdea053SToby Isaac ierr = DMInitializePackage();CHKERRQ(ierr); 23835fdea053SToby Isaac ierr = PetscSectionSymCreate(comm,sym);CHKERRQ(ierr); 23845fdea053SToby Isaac ierr = PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL);CHKERRQ(ierr); 23855fdea053SToby Isaac ierr = PetscSectionSymLabelSetLabel(*sym,label);CHKERRQ(ierr); 23865fdea053SToby Isaac PetscFunctionReturn(0); 23875fdea053SToby Isaac } 2388