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; 32d67d17b1SMatthew G. Knepley PetscValidPointer(label,2); 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 266b9907514SLisandro Dalcin /*@ 267b9907514SLisandro Dalcin DMLabelAddStratum - Adds a new stratum value in a DMLabel 268b9907514SLisandro Dalcin 269b9907514SLisandro Dalcin Input Parameter: 270b9907514SLisandro Dalcin + label - The DMLabel 271b9907514SLisandro Dalcin - value - The stratum value 272b9907514SLisandro Dalcin 273b9907514SLisandro Dalcin Level: beginner 274b9907514SLisandro Dalcin 275b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 276b9907514SLisandro Dalcin @*/ 2770c3c4a36SLisandro Dalcin PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 2780c3c4a36SLisandro Dalcin { 2790c3c4a36SLisandro Dalcin PetscInt v; 2800c3c4a36SLisandro Dalcin PetscErrorCode ierr; 2810c3c4a36SLisandro Dalcin 2820c3c4a36SLisandro Dalcin PetscFunctionBegin; 283d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 284b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 285b9907514SLisandro Dalcin PetscFunctionReturn(0); 286b9907514SLisandro Dalcin } 287b9907514SLisandro Dalcin 288b9907514SLisandro Dalcin /*@ 289b9907514SLisandro Dalcin DMLabelAddStrata - Adds new stratum values in a DMLabel 290b9907514SLisandro Dalcin 2915b5e7992SMatthew G. Knepley Not collective 2925b5e7992SMatthew G. Knepley 293b9907514SLisandro Dalcin Input Parameter: 294b9907514SLisandro Dalcin + label - The DMLabel 295b9907514SLisandro Dalcin . numStrata - The number of stratum values 296b9907514SLisandro Dalcin - stratumValues - The stratum values 297b9907514SLisandro Dalcin 298b9907514SLisandro Dalcin Level: beginner 299b9907514SLisandro Dalcin 300b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 301b9907514SLisandro Dalcin @*/ 302b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 303b9907514SLisandro Dalcin { 304b9907514SLisandro Dalcin PetscInt *values, v; 305b9907514SLisandro Dalcin PetscErrorCode ierr; 306b9907514SLisandro Dalcin 307b9907514SLisandro Dalcin PetscFunctionBegin; 308b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 309b9907514SLisandro Dalcin if (numStrata) PetscValidIntPointer(stratumValues, 3); 310b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &values);CHKERRQ(ierr); 311580bdb30SBarry Smith ierr = PetscArraycpy(values, stratumValues, numStrata);CHKERRQ(ierr); 312b9907514SLisandro Dalcin ierr = PetscSortRemoveDupsInt(&numStrata, values);CHKERRQ(ierr); 313b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 314b9907514SLisandro Dalcin PetscInt *tmpV; 315b9907514SLisandro Dalcin PetscInt *tmpS; 316b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 317b9907514SLisandro Dalcin IS *tmpP, is; 318b9907514SLisandro Dalcin PetscBool *tmpB; 319b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 320b9907514SLisandro Dalcin 321b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpV);CHKERRQ(ierr); 322b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpS);CHKERRQ(ierr); 323b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpH);CHKERRQ(ierr); 324b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpP);CHKERRQ(ierr); 325b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpB);CHKERRQ(ierr); 326b9907514SLisandro Dalcin label->numStrata = numStrata; 327b9907514SLisandro Dalcin label->stratumValues = tmpV; 328b9907514SLisandro Dalcin label->stratumSizes = tmpS; 329b9907514SLisandro Dalcin label->ht = tmpH; 330b9907514SLisandro Dalcin label->points = tmpP; 331b9907514SLisandro Dalcin label->validIS = tmpB; 332b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 333b9907514SLisandro Dalcin ierr = PetscHSetICreate(&ht);CHKERRQ(ierr); 334b9907514SLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr); 335b9907514SLisandro Dalcin ierr = PetscHMapISet(hmap, values[v], v);CHKERRQ(ierr); 336b9907514SLisandro Dalcin tmpV[v] = values[v]; 337b9907514SLisandro Dalcin tmpS[v] = 0; 338b9907514SLisandro Dalcin tmpH[v] = ht; 339b9907514SLisandro Dalcin tmpP[v] = is; 340b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 341b9907514SLisandro Dalcin } 342277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 343b9907514SLisandro Dalcin } else { 344b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 345b9907514SLisandro Dalcin ierr = DMLabelAddStratum(label, values[v]);CHKERRQ(ierr); 346b9907514SLisandro Dalcin } 347b9907514SLisandro Dalcin } 348b9907514SLisandro Dalcin ierr = PetscFree(values);CHKERRQ(ierr); 349b9907514SLisandro Dalcin PetscFunctionReturn(0); 350b9907514SLisandro Dalcin } 351b9907514SLisandro Dalcin 352b9907514SLisandro Dalcin /*@ 353b9907514SLisandro Dalcin DMLabelAddStrataIS - Adds new stratum values in a DMLabel 354b9907514SLisandro Dalcin 3555b5e7992SMatthew G. Knepley Not collective 3565b5e7992SMatthew G. Knepley 357b9907514SLisandro Dalcin Input Parameter: 358b9907514SLisandro Dalcin + label - The DMLabel 359b9907514SLisandro Dalcin - valueIS - Index set with stratum values 360b9907514SLisandro Dalcin 361b9907514SLisandro Dalcin Level: beginner 362b9907514SLisandro Dalcin 363b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 364b9907514SLisandro Dalcin @*/ 365b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 366b9907514SLisandro Dalcin { 367b9907514SLisandro Dalcin PetscInt numStrata; 368b9907514SLisandro Dalcin const PetscInt *stratumValues; 369b9907514SLisandro Dalcin PetscErrorCode ierr; 370b9907514SLisandro Dalcin 371b9907514SLisandro Dalcin PetscFunctionBegin; 372b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 373b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 374b9907514SLisandro Dalcin ierr = ISGetLocalSize(valueIS, &numStrata);CHKERRQ(ierr); 375b9907514SLisandro Dalcin ierr = ISGetIndices(valueIS, &stratumValues);CHKERRQ(ierr); 376b9907514SLisandro Dalcin ierr = DMLabelAddStrata(label, numStrata, stratumValues);CHKERRQ(ierr); 377c58f1c22SToby Isaac PetscFunctionReturn(0); 378c58f1c22SToby Isaac } 379c58f1c22SToby Isaac 380c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) 381c58f1c22SToby Isaac { 382c58f1c22SToby Isaac PetscInt v; 383c58f1c22SToby Isaac PetscMPIInt rank; 384c58f1c22SToby Isaac PetscErrorCode ierr; 385c58f1c22SToby Isaac 386c58f1c22SToby Isaac PetscFunctionBegin; 387ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRMPI(ierr); 388c58f1c22SToby Isaac ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 389c58f1c22SToby Isaac if (label) { 390d67d17b1SMatthew G. Knepley const char *name; 391d67d17b1SMatthew G. Knepley 392d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 393d67d17b1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name);CHKERRQ(ierr); 394c58f1c22SToby Isaac if (label->bt) {ierr = PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%D, %D)\n", label->pStart, label->pEnd);CHKERRQ(ierr);} 395c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 396c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 397ad8374ffSToby Isaac const PetscInt *points; 398c58f1c22SToby Isaac PetscInt p; 399c58f1c22SToby Isaac 400ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 401c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 402ad8374ffSToby Isaac ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\n", rank, points[p], value);CHKERRQ(ierr); 403c58f1c22SToby Isaac } 404ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 405c58f1c22SToby Isaac } 406c58f1c22SToby Isaac } 407c58f1c22SToby Isaac ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 408c58f1c22SToby Isaac ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 409c58f1c22SToby Isaac PetscFunctionReturn(0); 410c58f1c22SToby Isaac } 411c58f1c22SToby Isaac 412c58f1c22SToby Isaac /*@C 413c58f1c22SToby Isaac DMLabelView - View the label 414c58f1c22SToby Isaac 4155b5e7992SMatthew G. Knepley Collective on viewer 4165b5e7992SMatthew G. Knepley 417c58f1c22SToby Isaac Input Parameters: 418c58f1c22SToby Isaac + label - The DMLabel 419c58f1c22SToby Isaac - viewer - The PetscViewer 420c58f1c22SToby Isaac 421c58f1c22SToby Isaac Level: intermediate 422c58f1c22SToby Isaac 423c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelDestroy() 424c58f1c22SToby Isaac @*/ 425c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 426c58f1c22SToby Isaac { 427c58f1c22SToby Isaac PetscBool iascii; 428c58f1c22SToby Isaac PetscErrorCode ierr; 429c58f1c22SToby Isaac 430c58f1c22SToby Isaac PetscFunctionBegin; 431d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 432b9907514SLisandro Dalcin if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer);CHKERRQ(ierr);} 433c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 434c58f1c22SToby Isaac if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 435c58f1c22SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 436c58f1c22SToby Isaac if (iascii) { 437c58f1c22SToby Isaac ierr = DMLabelView_Ascii(label, viewer);CHKERRQ(ierr); 438c58f1c22SToby Isaac } 439c58f1c22SToby Isaac PetscFunctionReturn(0); 440c58f1c22SToby Isaac } 441c58f1c22SToby Isaac 44284f0b6dfSMatthew G. Knepley /*@ 443d67d17b1SMatthew G. Knepley DMLabelReset - Destroys internal data structures in a DMLabel 444d67d17b1SMatthew G. Knepley 4455b5e7992SMatthew G. Knepley Not collective 4465b5e7992SMatthew G. Knepley 447d67d17b1SMatthew G. Knepley Input Parameter: 448d67d17b1SMatthew G. Knepley . label - The DMLabel 449d67d17b1SMatthew G. Knepley 450d67d17b1SMatthew G. Knepley Level: beginner 451d67d17b1SMatthew G. Knepley 452d67d17b1SMatthew G. Knepley .seealso: DMLabelDestroy(), DMLabelCreate() 453d67d17b1SMatthew G. Knepley @*/ 454d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelReset(DMLabel label) 455d67d17b1SMatthew G. Knepley { 456d67d17b1SMatthew G. Knepley PetscInt v; 457d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 458d67d17b1SMatthew G. Knepley 459d67d17b1SMatthew G. Knepley PetscFunctionBegin; 460d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 461d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 462d67d17b1SMatthew G. Knepley ierr = PetscHSetIDestroy(&label->ht[v]);CHKERRQ(ierr); 463d67d17b1SMatthew G. Knepley ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 464d67d17b1SMatthew G. Knepley } 465b9907514SLisandro Dalcin label->numStrata = 0; 466b9907514SLisandro Dalcin ierr = PetscFree(label->stratumValues);CHKERRQ(ierr); 467b9907514SLisandro Dalcin ierr = PetscFree(label->stratumSizes);CHKERRQ(ierr); 468d67d17b1SMatthew G. Knepley ierr = PetscFree(label->ht);CHKERRQ(ierr); 469d67d17b1SMatthew G. Knepley ierr = PetscFree(label->points);CHKERRQ(ierr); 470d67d17b1SMatthew G. Knepley ierr = PetscFree(label->validIS);CHKERRQ(ierr); 471f9244615SMatthew G. Knepley label->stratumValues = NULL; 472f9244615SMatthew G. Knepley label->stratumSizes = NULL; 473f9244615SMatthew G. Knepley label->ht = NULL; 474f9244615SMatthew G. Knepley label->points = NULL; 475f9244615SMatthew G. Knepley label->validIS = NULL; 476b9907514SLisandro Dalcin ierr = PetscHMapIReset(label->hmap);CHKERRQ(ierr); 477b9907514SLisandro Dalcin label->pStart = -1; 478b9907514SLisandro Dalcin label->pEnd = -1; 479d67d17b1SMatthew G. Knepley ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 480d67d17b1SMatthew G. Knepley PetscFunctionReturn(0); 481d67d17b1SMatthew G. Knepley } 482d67d17b1SMatthew G. Knepley 483d67d17b1SMatthew G. Knepley /*@ 48484f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 48584f0b6dfSMatthew G. Knepley 4865b5e7992SMatthew G. Knepley Collective on label 4875b5e7992SMatthew G. Knepley 48884f0b6dfSMatthew G. Knepley Input Parameter: 48984f0b6dfSMatthew G. Knepley . label - The DMLabel 49084f0b6dfSMatthew G. Knepley 49184f0b6dfSMatthew G. Knepley Level: beginner 49284f0b6dfSMatthew G. Knepley 493d67d17b1SMatthew G. Knepley .seealso: DMLabelReset(), DMLabelCreate() 49484f0b6dfSMatthew G. Knepley @*/ 495c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label) 496c58f1c22SToby Isaac { 497c58f1c22SToby Isaac PetscErrorCode ierr; 498c58f1c22SToby Isaac 499c58f1c22SToby Isaac PetscFunctionBegin; 500d67d17b1SMatthew G. Knepley if (!*label) PetscFunctionReturn(0); 501d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label),DMLABEL_CLASSID,1); 502b9907514SLisandro Dalcin if (--((PetscObject)(*label))->refct > 0) {*label = NULL; PetscFunctionReturn(0);} 503d67d17b1SMatthew G. Knepley ierr = DMLabelReset(*label);CHKERRQ(ierr); 504b9907514SLisandro Dalcin ierr = PetscHMapIDestroy(&(*label)->hmap);CHKERRQ(ierr); 505d67d17b1SMatthew G. Knepley ierr = PetscHeaderDestroy(label);CHKERRQ(ierr); 506c58f1c22SToby Isaac PetscFunctionReturn(0); 507c58f1c22SToby Isaac } 508c58f1c22SToby Isaac 50984f0b6dfSMatthew G. Knepley /*@ 51084f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 51184f0b6dfSMatthew G. Knepley 5125b5e7992SMatthew G. Knepley Collective on label 5135b5e7992SMatthew G. Knepley 51484f0b6dfSMatthew G. Knepley Input Parameter: 51584f0b6dfSMatthew G. Knepley . label - The DMLabel 51684f0b6dfSMatthew G. Knepley 51784f0b6dfSMatthew G. Knepley Output Parameter: 51884f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 51984f0b6dfSMatthew G. Knepley 52084f0b6dfSMatthew G. Knepley Level: intermediate 52184f0b6dfSMatthew G. Knepley 52284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelDestroy() 52384f0b6dfSMatthew G. Knepley @*/ 524c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 525c58f1c22SToby Isaac { 526d67d17b1SMatthew G. Knepley const char *name; 527ad8374ffSToby Isaac PetscInt v; 528c58f1c22SToby Isaac PetscErrorCode ierr; 529c58f1c22SToby Isaac 530c58f1c22SToby Isaac PetscFunctionBegin; 531d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 532c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 533d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 534d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PetscObjectComm((PetscObject) label), name, labelnew);CHKERRQ(ierr); 535c58f1c22SToby Isaac 536c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5375aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 538c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues);CHKERRQ(ierr); 539c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes);CHKERRQ(ierr); 540c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->ht);CHKERRQ(ierr); 541c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->points);CHKERRQ(ierr); 542ad8374ffSToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->validIS);CHKERRQ(ierr); 543c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 544e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelnew)->ht[v]);CHKERRQ(ierr); 545c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 546c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 547ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) (label->points[v]));CHKERRQ(ierr); 548ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 549b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 550c58f1c22SToby Isaac } 551f14fe40dSLisandro Dalcin ierr = PetscHMapIDestroy(&(*labelnew)->hmap);CHKERRQ(ierr); 552b9907514SLisandro Dalcin ierr = PetscHMapIDuplicate(label->hmap,&(*labelnew)->hmap);CHKERRQ(ierr); 553c58f1c22SToby Isaac (*labelnew)->pStart = -1; 554c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 555c58f1c22SToby Isaac (*labelnew)->bt = NULL; 556c58f1c22SToby Isaac PetscFunctionReturn(0); 557c58f1c22SToby Isaac } 558c58f1c22SToby Isaac 559c6a43d28SMatthew G. Knepley /*@ 560c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 561c6a43d28SMatthew G. Knepley 5625b5e7992SMatthew G. Knepley Not collective 5635b5e7992SMatthew G. Knepley 564c6a43d28SMatthew G. Knepley Input Parameter: 565c6a43d28SMatthew G. Knepley . label - The DMLabel 566c6a43d28SMatthew G. Knepley 567c6a43d28SMatthew G. Knepley Level: intermediate 568c6a43d28SMatthew G. Knepley 569c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 570c6a43d28SMatthew G. Knepley @*/ 571c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelComputeIndex(DMLabel label) 572c6a43d28SMatthew G. Knepley { 573c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 574c6a43d28SMatthew G. Knepley PetscErrorCode ierr; 575c6a43d28SMatthew G. Knepley 576c6a43d28SMatthew G. Knepley PetscFunctionBegin; 577c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 578c6a43d28SMatthew G. Knepley ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 579c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 580c6a43d28SMatthew G. Knepley const PetscInt *points; 581c6a43d28SMatthew G. Knepley PetscInt i; 582c6a43d28SMatthew G. Knepley 583c6a43d28SMatthew G. Knepley ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 584c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 585c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 586c6a43d28SMatthew G. Knepley 587c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 588c6a43d28SMatthew G. Knepley pEnd = PetscMax(point+1, pEnd); 589c6a43d28SMatthew G. Knepley } 590c6a43d28SMatthew G. Knepley ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 591c6a43d28SMatthew G. Knepley } 592c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 593c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 594c6a43d28SMatthew G. Knepley ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 595c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 596c6a43d28SMatthew G. Knepley } 597c6a43d28SMatthew G. Knepley 598c6a43d28SMatthew G. Knepley /*@ 599c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 600c6a43d28SMatthew G. Knepley 6015b5e7992SMatthew G. Knepley Not collective 6025b5e7992SMatthew G. Knepley 603c6a43d28SMatthew G. Knepley Input Parameters: 604c6a43d28SMatthew G. Knepley + label - The DMLabel 605c6a43d28SMatthew G. Knepley . pStart - The smallest point 606c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 607c6a43d28SMatthew G. Knepley 608c6a43d28SMatthew G. Knepley Level: intermediate 609c6a43d28SMatthew G. Knepley 610c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelComputeIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 611c6a43d28SMatthew G. Knepley @*/ 612c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 613c58f1c22SToby Isaac { 614c58f1c22SToby Isaac PetscInt v; 615c58f1c22SToby Isaac PetscErrorCode ierr; 616c58f1c22SToby Isaac 617c58f1c22SToby Isaac PetscFunctionBegin; 618d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 6190c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 620c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 621c58f1c22SToby Isaac label->pStart = pStart; 622c58f1c22SToby Isaac label->pEnd = pEnd; 623c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 624c58f1c22SToby Isaac ierr = PetscBTCreate(pEnd - pStart, &label->bt);CHKERRQ(ierr); 625c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 626ad8374ffSToby Isaac const PetscInt *points; 627c58f1c22SToby Isaac PetscInt i; 628c58f1c22SToby Isaac 629ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 630c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 631ad8374ffSToby Isaac const PetscInt point = points[i]; 632c58f1c22SToby Isaac 633c58f1c22SToby 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); 634c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - pStart);CHKERRQ(ierr); 635c58f1c22SToby Isaac } 636ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 637c58f1c22SToby Isaac } 638c58f1c22SToby Isaac PetscFunctionReturn(0); 639c58f1c22SToby Isaac } 640c58f1c22SToby Isaac 641c6a43d28SMatthew G. Knepley /*@ 642c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 643c6a43d28SMatthew G. Knepley 6445b5e7992SMatthew G. Knepley Not collective 6455b5e7992SMatthew G. Knepley 646c6a43d28SMatthew G. Knepley Input Parameter: 647c6a43d28SMatthew G. Knepley . label - the DMLabel 648c6a43d28SMatthew G. Knepley 649c6a43d28SMatthew G. Knepley Level: intermediate 650c6a43d28SMatthew G. Knepley 651c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 652c6a43d28SMatthew G. Knepley @*/ 653c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label) 654c58f1c22SToby Isaac { 655c58f1c22SToby Isaac PetscErrorCode ierr; 656c58f1c22SToby Isaac 657c58f1c22SToby Isaac PetscFunctionBegin; 658d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 659c58f1c22SToby Isaac label->pStart = -1; 660c58f1c22SToby Isaac label->pEnd = -1; 6610c3c4a36SLisandro Dalcin ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 662c58f1c22SToby Isaac PetscFunctionReturn(0); 663c58f1c22SToby Isaac } 664c58f1c22SToby Isaac 665c58f1c22SToby Isaac /*@ 666c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 667c6a43d28SMatthew G. Knepley 6685b5e7992SMatthew G. Knepley Not collective 6695b5e7992SMatthew G. Knepley 670c6a43d28SMatthew G. Knepley Input Parameter: 671c6a43d28SMatthew G. Knepley . label - the DMLabel 672c6a43d28SMatthew G. Knepley 673c6a43d28SMatthew G. Knepley Output Parameters: 674c6a43d28SMatthew G. Knepley + pStart - The smallest point 675c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 676c6a43d28SMatthew G. Knepley 677c6a43d28SMatthew G. Knepley Note: This will compute an index for the label if one does not exist. 678c6a43d28SMatthew G. Knepley 679c6a43d28SMatthew G. Knepley Level: intermediate 680c6a43d28SMatthew G. Knepley 681c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 682c6a43d28SMatthew G. Knepley @*/ 683c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 684c6a43d28SMatthew G. Knepley { 685c6a43d28SMatthew G. Knepley PetscErrorCode ierr; 686c6a43d28SMatthew G. Knepley 687c6a43d28SMatthew G. Knepley PetscFunctionBegin; 688c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 689c6a43d28SMatthew G. Knepley if ((label->pStart == -1) && (label->pEnd == -1)) {ierr = DMLabelComputeIndex(label);CHKERRQ(ierr);} 690c6a43d28SMatthew G. Knepley if (pStart) { 691534a8f05SLisandro Dalcin PetscValidIntPointer(pStart, 2); 692c6a43d28SMatthew G. Knepley *pStart = label->pStart; 693c6a43d28SMatthew G. Knepley } 694c6a43d28SMatthew G. Knepley if (pEnd) { 695534a8f05SLisandro Dalcin PetscValidIntPointer(pEnd, 3); 696c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 697c6a43d28SMatthew G. Knepley } 698c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 699c6a43d28SMatthew G. Knepley } 700c6a43d28SMatthew G. Knepley 701c6a43d28SMatthew G. Knepley /*@ 702c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 703c58f1c22SToby Isaac 7045b5e7992SMatthew G. Knepley Not collective 7055b5e7992SMatthew G. Knepley 706c58f1c22SToby Isaac Input Parameters: 707c58f1c22SToby Isaac + label - the DMLabel 708c58f1c22SToby Isaac - value - the value 709c58f1c22SToby Isaac 710c58f1c22SToby Isaac Output Parameter: 711c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 712c58f1c22SToby Isaac 713c58f1c22SToby Isaac Level: developer 714c58f1c22SToby Isaac 715c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue() 716c58f1c22SToby Isaac @*/ 717c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 718c58f1c22SToby Isaac { 719c58f1c22SToby Isaac PetscInt v; 7200c3c4a36SLisandro Dalcin PetscErrorCode ierr; 721c58f1c22SToby Isaac 722c58f1c22SToby Isaac PetscFunctionBegin; 723d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 724534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 7250c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 7260c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 727c58f1c22SToby Isaac PetscFunctionReturn(0); 728c58f1c22SToby Isaac } 729c58f1c22SToby Isaac 730c58f1c22SToby Isaac /*@ 731c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 732c58f1c22SToby Isaac 7335b5e7992SMatthew G. Knepley Not collective 7345b5e7992SMatthew G. Knepley 735c58f1c22SToby Isaac Input Parameters: 736c58f1c22SToby Isaac + label - the DMLabel 737c58f1c22SToby Isaac - point - the point 738c58f1c22SToby Isaac 739c58f1c22SToby Isaac Output Parameter: 740c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 741c58f1c22SToby Isaac 742c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 743c58f1c22SToby Isaac 744c58f1c22SToby Isaac Level: developer 745c58f1c22SToby Isaac 746c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 747c58f1c22SToby Isaac @*/ 748c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 749c58f1c22SToby Isaac { 750c58f1c22SToby Isaac PetscErrorCode ierr; 751c58f1c22SToby Isaac 752c58f1c22SToby Isaac PetscFunctionBeginHot; 753d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 754534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 3); 755c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 75676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 757c58f1c22SToby Isaac if (!label->bt) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 758c58f1c22SToby 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); 75976bd3646SJed Brown } 760c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 761c58f1c22SToby Isaac PetscFunctionReturn(0); 762c58f1c22SToby Isaac } 763c58f1c22SToby Isaac 764c58f1c22SToby Isaac /*@ 765c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 766c58f1c22SToby Isaac 7675b5e7992SMatthew G. Knepley Not collective 7685b5e7992SMatthew G. Knepley 769c58f1c22SToby Isaac Input Parameters: 770c58f1c22SToby Isaac + label - the DMLabel 771c58f1c22SToby Isaac . value - the stratum value 772c58f1c22SToby Isaac - point - the point 773c58f1c22SToby Isaac 774c58f1c22SToby Isaac Output Parameter: 775c58f1c22SToby Isaac . contains - true if the stratum contains the point 776c58f1c22SToby Isaac 777c58f1c22SToby Isaac Level: intermediate 778c58f1c22SToby Isaac 779c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue() 780c58f1c22SToby Isaac @*/ 781c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 782c58f1c22SToby Isaac { 783c58f1c22SToby Isaac PetscInt v; 784c58f1c22SToby Isaac PetscErrorCode ierr; 785c58f1c22SToby Isaac 7860c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 787d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 788534a8f05SLisandro Dalcin PetscValidBoolPointer(contains, 4); 789c58f1c22SToby Isaac *contains = PETSC_FALSE; 7900c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 7910c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 7920c3c4a36SLisandro Dalcin 793ad8374ffSToby Isaac if (label->validIS[v]) { 794c58f1c22SToby Isaac PetscInt i; 795c58f1c22SToby Isaac 796a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 7970c3c4a36SLisandro Dalcin if (i >= 0) *contains = PETSC_TRUE; 798c58f1c22SToby Isaac } else { 799c58f1c22SToby Isaac PetscBool has; 800c58f1c22SToby Isaac 801b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr); 8020c3c4a36SLisandro Dalcin if (has) *contains = PETSC_TRUE; 803c58f1c22SToby Isaac } 804c58f1c22SToby Isaac PetscFunctionReturn(0); 805c58f1c22SToby Isaac } 806c58f1c22SToby Isaac 80784f0b6dfSMatthew G. Knepley /*@ 8085aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 8095aa44df4SToby Isaac When a label is created, it is initialized to -1. 8105aa44df4SToby Isaac 8115b5e7992SMatthew G. Knepley Not collective 8125b5e7992SMatthew G. Knepley 8135aa44df4SToby Isaac Input parameter: 8145aa44df4SToby Isaac . label - a DMLabel object 8155aa44df4SToby Isaac 8165aa44df4SToby Isaac Output parameter: 8175aa44df4SToby Isaac . defaultValue - the default value 8185aa44df4SToby Isaac 8195aa44df4SToby Isaac Level: beginner 8205aa44df4SToby Isaac 8215aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 82284f0b6dfSMatthew G. Knepley @*/ 8235aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 8245aa44df4SToby Isaac { 8255aa44df4SToby Isaac PetscFunctionBegin; 826d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8275aa44df4SToby Isaac *defaultValue = label->defaultValue; 8285aa44df4SToby Isaac PetscFunctionReturn(0); 8295aa44df4SToby Isaac } 8305aa44df4SToby Isaac 83184f0b6dfSMatthew G. Knepley /*@ 8325aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 8335aa44df4SToby Isaac When a label is created, it is initialized to -1. 8345aa44df4SToby Isaac 8355b5e7992SMatthew G. Knepley Not collective 8365b5e7992SMatthew G. Knepley 8375aa44df4SToby Isaac Input parameter: 8385aa44df4SToby Isaac . label - a DMLabel object 8395aa44df4SToby Isaac 8405aa44df4SToby Isaac Output parameter: 8415aa44df4SToby Isaac . defaultValue - the default value 8425aa44df4SToby Isaac 8435aa44df4SToby Isaac Level: beginner 8445aa44df4SToby Isaac 8455aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 84684f0b6dfSMatthew G. Knepley @*/ 8475aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 8485aa44df4SToby Isaac { 8495aa44df4SToby Isaac PetscFunctionBegin; 850d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8515aa44df4SToby Isaac label->defaultValue = defaultValue; 8525aa44df4SToby Isaac PetscFunctionReturn(0); 8535aa44df4SToby Isaac } 8545aa44df4SToby Isaac 855c58f1c22SToby Isaac /*@ 8565aa44df4SToby 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()) 857c58f1c22SToby Isaac 8585b5e7992SMatthew G. Knepley Not collective 8595b5e7992SMatthew G. Knepley 860c58f1c22SToby Isaac Input Parameters: 861c58f1c22SToby Isaac + label - the DMLabel 862c58f1c22SToby Isaac - point - the point 863c58f1c22SToby Isaac 864c58f1c22SToby Isaac Output Parameter: 8658e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 866c58f1c22SToby Isaac 867c58f1c22SToby Isaac Level: intermediate 868c58f1c22SToby Isaac 8695aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 870c58f1c22SToby Isaac @*/ 871c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 872c58f1c22SToby Isaac { 873c58f1c22SToby Isaac PetscInt v; 874c58f1c22SToby Isaac PetscErrorCode ierr; 875c58f1c22SToby Isaac 8760c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 877d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 878c58f1c22SToby Isaac PetscValidPointer(value, 3); 8795aa44df4SToby Isaac *value = label->defaultValue; 880c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 881ad8374ffSToby Isaac if (label->validIS[v]) { 882c58f1c22SToby Isaac PetscInt i; 883c58f1c22SToby Isaac 884a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 885c58f1c22SToby Isaac if (i >= 0) { 886c58f1c22SToby Isaac *value = label->stratumValues[v]; 887c58f1c22SToby Isaac break; 888c58f1c22SToby Isaac } 889c58f1c22SToby Isaac } else { 890c58f1c22SToby Isaac PetscBool has; 891c58f1c22SToby Isaac 892b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr); 893c58f1c22SToby Isaac if (has) { 894c58f1c22SToby Isaac *value = label->stratumValues[v]; 895c58f1c22SToby Isaac break; 896c58f1c22SToby Isaac } 897c58f1c22SToby Isaac } 898c58f1c22SToby Isaac } 899c58f1c22SToby Isaac PetscFunctionReturn(0); 900c58f1c22SToby Isaac } 901c58f1c22SToby Isaac 902c58f1c22SToby Isaac /*@ 903367003a6SStefano 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. 904c58f1c22SToby Isaac 9055b5e7992SMatthew G. Knepley Not collective 9065b5e7992SMatthew G. Knepley 907c58f1c22SToby Isaac Input Parameters: 908c58f1c22SToby Isaac + label - the DMLabel 909c58f1c22SToby Isaac . point - the point 910c58f1c22SToby Isaac - value - The point value 911c58f1c22SToby Isaac 912c58f1c22SToby Isaac Level: intermediate 913c58f1c22SToby Isaac 9145aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 915c58f1c22SToby Isaac @*/ 916c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 917c58f1c22SToby Isaac { 918c58f1c22SToby Isaac PetscInt v; 919c58f1c22SToby Isaac PetscErrorCode ierr; 920c58f1c22SToby Isaac 921c58f1c22SToby Isaac PetscFunctionBegin; 922d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9230c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 9245aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 925b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 926c58f1c22SToby Isaac /* Set key */ 9270c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 928e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(label->ht[v], point);CHKERRQ(ierr); 929c58f1c22SToby Isaac PetscFunctionReturn(0); 930c58f1c22SToby Isaac } 931c58f1c22SToby Isaac 932c58f1c22SToby Isaac /*@ 933c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 934c58f1c22SToby Isaac 9355b5e7992SMatthew G. Knepley Not collective 9365b5e7992SMatthew G. Knepley 937c58f1c22SToby Isaac Input Parameters: 938c58f1c22SToby Isaac + label - the DMLabel 939c58f1c22SToby Isaac . point - the point 940c58f1c22SToby Isaac - value - The point value 941c58f1c22SToby Isaac 942c58f1c22SToby Isaac Level: intermediate 943c58f1c22SToby Isaac 944c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue() 945c58f1c22SToby Isaac @*/ 946c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 947c58f1c22SToby Isaac { 948ad8374ffSToby Isaac PetscInt v; 949c58f1c22SToby Isaac PetscErrorCode ierr; 950c58f1c22SToby Isaac 951c58f1c22SToby Isaac PetscFunctionBegin; 952d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 953c58f1c22SToby Isaac /* Find label value */ 9540c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 9550c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 9560c3c4a36SLisandro Dalcin 957eeed21e7SToby Isaac if (label->bt) { 958eeed21e7SToby 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); 959eeed21e7SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 960eeed21e7SToby Isaac } 9610c3c4a36SLisandro Dalcin 9620c3c4a36SLisandro Dalcin /* Delete key */ 9630c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 964e8f14785SLisandro Dalcin ierr = PetscHSetIDel(label->ht[v], point);CHKERRQ(ierr); 965c58f1c22SToby Isaac PetscFunctionReturn(0); 966c58f1c22SToby Isaac } 967c58f1c22SToby Isaac 968c58f1c22SToby Isaac /*@ 969c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 970c58f1c22SToby Isaac 9715b5e7992SMatthew G. Knepley Not collective 9725b5e7992SMatthew G. Knepley 973c58f1c22SToby Isaac Input Parameters: 974c58f1c22SToby Isaac + label - the DMLabel 975c58f1c22SToby Isaac . is - the point IS 976c58f1c22SToby Isaac - value - The point value 977c58f1c22SToby Isaac 978c58f1c22SToby Isaac Level: intermediate 979c58f1c22SToby Isaac 980c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 981c58f1c22SToby Isaac @*/ 982c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 983c58f1c22SToby Isaac { 9840c3c4a36SLisandro Dalcin PetscInt v, n, p; 985c58f1c22SToby Isaac const PetscInt *points; 986c58f1c22SToby Isaac PetscErrorCode ierr; 987c58f1c22SToby Isaac 988c58f1c22SToby Isaac PetscFunctionBegin; 989d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 990c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 9910c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 9920c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 993b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 9940c3c4a36SLisandro Dalcin /* Set keys */ 9950c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 996c58f1c22SToby Isaac ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 997c58f1c22SToby Isaac ierr = ISGetIndices(is, &points);CHKERRQ(ierr); 998e8f14785SLisandro Dalcin for (p = 0; p < n; ++p) {ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);} 999c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &points);CHKERRQ(ierr); 1000c58f1c22SToby Isaac PetscFunctionReturn(0); 1001c58f1c22SToby Isaac } 1002c58f1c22SToby Isaac 100384f0b6dfSMatthew G. Knepley /*@ 100484f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 100584f0b6dfSMatthew G. Knepley 10065b5e7992SMatthew G. Knepley Not collective 10075b5e7992SMatthew G. Knepley 100884f0b6dfSMatthew G. Knepley Input Parameter: 100984f0b6dfSMatthew G. Knepley . label - the DMLabel 101084f0b6dfSMatthew G. Knepley 101184f0b6dfSMatthew G. Knepley Output Paramater: 101284f0b6dfSMatthew G. Knepley . numValues - the number of values 101384f0b6dfSMatthew G. Knepley 101484f0b6dfSMatthew G. Knepley Level: intermediate 101584f0b6dfSMatthew G. Knepley 101684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 101784f0b6dfSMatthew G. Knepley @*/ 1018c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1019c58f1c22SToby Isaac { 1020c58f1c22SToby Isaac PetscFunctionBegin; 1021d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1022c58f1c22SToby Isaac PetscValidPointer(numValues, 2); 1023c58f1c22SToby Isaac *numValues = label->numStrata; 1024c58f1c22SToby Isaac PetscFunctionReturn(0); 1025c58f1c22SToby Isaac } 1026c58f1c22SToby Isaac 102784f0b6dfSMatthew G. Knepley /*@ 102884f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 102984f0b6dfSMatthew G. Knepley 10305b5e7992SMatthew G. Knepley Not collective 10315b5e7992SMatthew G. Knepley 103284f0b6dfSMatthew G. Knepley Input Parameter: 103384f0b6dfSMatthew G. Knepley . label - the DMLabel 103484f0b6dfSMatthew G. Knepley 103584f0b6dfSMatthew G. Knepley Output Paramater: 103684f0b6dfSMatthew G. Knepley . is - the value IS 103784f0b6dfSMatthew G. Knepley 103884f0b6dfSMatthew G. Knepley Level: intermediate 103984f0b6dfSMatthew G. Knepley 104084f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 104184f0b6dfSMatthew G. Knepley @*/ 1042c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1043c58f1c22SToby Isaac { 1044c58f1c22SToby Isaac PetscErrorCode ierr; 1045c58f1c22SToby Isaac 1046c58f1c22SToby Isaac PetscFunctionBegin; 1047d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1048c58f1c22SToby Isaac PetscValidPointer(values, 2); 1049c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr); 1050c58f1c22SToby Isaac PetscFunctionReturn(0); 1051c58f1c22SToby Isaac } 1052c58f1c22SToby Isaac 105384f0b6dfSMatthew G. Knepley /*@ 105484f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 105584f0b6dfSMatthew G. Knepley 10565b5e7992SMatthew G. Knepley Not collective 10575b5e7992SMatthew G. Knepley 105884f0b6dfSMatthew G. Knepley Input Parameters: 105984f0b6dfSMatthew G. Knepley + label - the DMLabel 106084f0b6dfSMatthew G. Knepley - value - the stratum value 106184f0b6dfSMatthew G. Knepley 106284f0b6dfSMatthew G. Knepley Output Paramater: 106384f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 106484f0b6dfSMatthew G. Knepley 106584f0b6dfSMatthew G. Knepley Level: intermediate 106684f0b6dfSMatthew G. Knepley 106784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 106884f0b6dfSMatthew G. Knepley @*/ 1069fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1070fada774cSMatthew G. Knepley { 1071fada774cSMatthew G. Knepley PetscInt v; 10720c3c4a36SLisandro Dalcin PetscErrorCode ierr; 1073fada774cSMatthew G. Knepley 1074fada774cSMatthew G. Knepley PetscFunctionBegin; 1075d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1076fada774cSMatthew G. Knepley PetscValidPointer(exists, 3); 10770c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 10780c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 1079fada774cSMatthew G. Knepley PetscFunctionReturn(0); 1080fada774cSMatthew G. Knepley } 1081fada774cSMatthew G. Knepley 108284f0b6dfSMatthew G. Knepley /*@ 108384f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 108484f0b6dfSMatthew G. Knepley 10855b5e7992SMatthew G. Knepley Not collective 10865b5e7992SMatthew G. Knepley 108784f0b6dfSMatthew G. Knepley Input Parameters: 108884f0b6dfSMatthew G. Knepley + label - the DMLabel 108984f0b6dfSMatthew G. Knepley - value - the stratum value 109084f0b6dfSMatthew G. Knepley 109184f0b6dfSMatthew G. Knepley Output Paramater: 109284f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 109384f0b6dfSMatthew G. Knepley 109484f0b6dfSMatthew G. Knepley Level: intermediate 109584f0b6dfSMatthew G. Knepley 109684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 109784f0b6dfSMatthew G. Knepley @*/ 1098c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1099c58f1c22SToby Isaac { 1100c58f1c22SToby Isaac PetscInt v; 1101c58f1c22SToby Isaac PetscErrorCode ierr; 1102c58f1c22SToby Isaac 1103c58f1c22SToby Isaac PetscFunctionBegin; 1104d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1105c58f1c22SToby Isaac PetscValidPointer(size, 3); 1106c58f1c22SToby Isaac *size = 0; 11070c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 11080c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1109c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 1110c58f1c22SToby Isaac *size = label->stratumSizes[v]; 1111c58f1c22SToby Isaac PetscFunctionReturn(0); 1112c58f1c22SToby Isaac } 1113c58f1c22SToby Isaac 111484f0b6dfSMatthew G. Knepley /*@ 111584f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 111684f0b6dfSMatthew G. Knepley 11175b5e7992SMatthew G. Knepley Not collective 11185b5e7992SMatthew G. Knepley 111984f0b6dfSMatthew G. Knepley Input Parameters: 112084f0b6dfSMatthew G. Knepley + label - the DMLabel 112184f0b6dfSMatthew G. Knepley - value - the stratum value 112284f0b6dfSMatthew G. Knepley 112384f0b6dfSMatthew G. Knepley Output Paramaters: 112484f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 112584f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 112684f0b6dfSMatthew G. Knepley 112784f0b6dfSMatthew G. Knepley Level: intermediate 112884f0b6dfSMatthew G. Knepley 112984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 113084f0b6dfSMatthew G. Knepley @*/ 1131c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1132c58f1c22SToby Isaac { 11330c3c4a36SLisandro Dalcin PetscInt v, min, max; 1134c58f1c22SToby Isaac PetscErrorCode ierr; 1135c58f1c22SToby Isaac 1136c58f1c22SToby Isaac PetscFunctionBegin; 1137d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1138*cade499fSVaclav Hapla if (start) {PetscValidPointer(start, 3); *start = -1;} 1139*cade499fSVaclav Hapla if (end) {PetscValidPointer(end, 4); *end = -1;} 11400c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 11410c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1142c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 11430c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 1144d6cb179aSToby Isaac ierr = ISGetMinMax(label->points[v], &min, &max);CHKERRQ(ierr); 1145d6cb179aSToby Isaac if (start) *start = min; 1146d6cb179aSToby Isaac if (end) *end = max+1; 1147c58f1c22SToby Isaac PetscFunctionReturn(0); 1148c58f1c22SToby Isaac } 1149c58f1c22SToby Isaac 115084f0b6dfSMatthew G. Knepley /*@ 115184f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 115284f0b6dfSMatthew G. Knepley 11535b5e7992SMatthew G. Knepley Not collective 11545b5e7992SMatthew G. Knepley 115584f0b6dfSMatthew G. Knepley Input Parameters: 115684f0b6dfSMatthew G. Knepley + label - the DMLabel 115784f0b6dfSMatthew G. Knepley - value - the stratum value 115884f0b6dfSMatthew G. Knepley 115984f0b6dfSMatthew G. Knepley Output Paramater: 116084f0b6dfSMatthew G. Knepley . points - The stratum points 116184f0b6dfSMatthew G. Knepley 116284f0b6dfSMatthew G. Knepley Level: intermediate 116384f0b6dfSMatthew G. Knepley 1164593ce467SVaclav Hapla Notes: 1165593ce467SVaclav Hapla The output IS should be destroyed when no longer needed. 1166593ce467SVaclav Hapla Returns NULL if the stratum is empty. 1167593ce467SVaclav Hapla 116884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 116984f0b6dfSMatthew G. Knepley @*/ 1170c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1171c58f1c22SToby Isaac { 1172c58f1c22SToby Isaac PetscInt v; 1173c58f1c22SToby Isaac PetscErrorCode ierr; 1174c58f1c22SToby Isaac 1175c58f1c22SToby Isaac PetscFunctionBegin; 1176d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1177c58f1c22SToby Isaac PetscValidPointer(points, 3); 1178c58f1c22SToby Isaac *points = NULL; 11790c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 11800c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1181c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 1182ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) label->points[v]);CHKERRQ(ierr); 1183ad8374ffSToby Isaac *points = label->points[v]; 1184c58f1c22SToby Isaac PetscFunctionReturn(0); 1185c58f1c22SToby Isaac } 1186c58f1c22SToby Isaac 118784f0b6dfSMatthew G. Knepley /*@ 118884f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 118984f0b6dfSMatthew G. Knepley 11905b5e7992SMatthew G. Knepley Not collective 11915b5e7992SMatthew G. Knepley 119284f0b6dfSMatthew G. Knepley Input Parameters: 119384f0b6dfSMatthew G. Knepley + label - the DMLabel 119484f0b6dfSMatthew G. Knepley . value - the stratum value 119584f0b6dfSMatthew G. Knepley - points - The stratum points 119684f0b6dfSMatthew G. Knepley 119784f0b6dfSMatthew G. Knepley Level: intermediate 119884f0b6dfSMatthew G. Knepley 119984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 120084f0b6dfSMatthew G. Knepley @*/ 12014de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 12024de306b1SToby Isaac { 12030c3c4a36SLisandro Dalcin PetscInt v; 12044de306b1SToby Isaac PetscErrorCode ierr; 12054de306b1SToby Isaac 12064de306b1SToby Isaac PetscFunctionBegin; 1207d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1208d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 1209b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 12104de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 12114de306b1SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 12124de306b1SToby Isaac ierr = ISGetLocalSize(is, &(label->stratumSizes[v]));CHKERRQ(ierr); 12134de306b1SToby Isaac ierr = PetscObjectReference((PetscObject)is);CHKERRQ(ierr); 12144de306b1SToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 12150c3c4a36SLisandro Dalcin label->points[v] = is; 12160c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 1217277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 12184de306b1SToby Isaac if (label->bt) { 12194de306b1SToby Isaac const PetscInt *points; 12204de306b1SToby Isaac PetscInt p; 12214de306b1SToby Isaac 12224de306b1SToby Isaac ierr = ISGetIndices(is,&points);CHKERRQ(ierr); 12234de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 12244de306b1SToby Isaac const PetscInt point = points[p]; 12254de306b1SToby Isaac 12264de306b1SToby 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); 12274de306b1SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 12284de306b1SToby Isaac } 12294de306b1SToby Isaac } 12304de306b1SToby Isaac PetscFunctionReturn(0); 12314de306b1SToby Isaac } 12324de306b1SToby Isaac 123384f0b6dfSMatthew G. Knepley /*@ 123484f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 12354de306b1SToby Isaac 12365b5e7992SMatthew G. Knepley Not collective 12375b5e7992SMatthew G. Knepley 123884f0b6dfSMatthew G. Knepley Input Parameters: 123984f0b6dfSMatthew G. Knepley + label - the DMLabel 124084f0b6dfSMatthew G. Knepley - value - the stratum value 124184f0b6dfSMatthew G. Knepley 124284f0b6dfSMatthew G. Knepley Level: intermediate 124384f0b6dfSMatthew G. Knepley 124484f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 124584f0b6dfSMatthew G. Knepley @*/ 1246c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1247c58f1c22SToby Isaac { 1248c58f1c22SToby Isaac PetscInt v; 1249c58f1c22SToby Isaac PetscErrorCode ierr; 1250c58f1c22SToby Isaac 1251c58f1c22SToby Isaac PetscFunctionBegin; 1252d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12530c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 12540c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 12554de306b1SToby Isaac if (label->validIS[v]) { 12564de306b1SToby Isaac if (label->bt) { 1257c58f1c22SToby Isaac PetscInt i; 1258ad8374ffSToby Isaac const PetscInt *points; 1259c58f1c22SToby Isaac 1260ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 1261c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1262ad8374ffSToby Isaac const PetscInt point = points[i]; 1263c58f1c22SToby Isaac 1264c58f1c22SToby 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); 1265c58f1c22SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 1266c58f1c22SToby Isaac } 1267ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 1268c58f1c22SToby Isaac } 1269c58f1c22SToby Isaac label->stratumSizes[v] = 0; 12700c3c4a36SLisandro Dalcin ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 1271277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v]);CHKERRQ(ierr); 12720c3c4a36SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr); 1273277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 1274c58f1c22SToby Isaac } else { 1275b9907514SLisandro Dalcin ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr); 1276c58f1c22SToby Isaac } 1277c58f1c22SToby Isaac PetscFunctionReturn(0); 1278c58f1c22SToby Isaac } 1279c58f1c22SToby Isaac 128084f0b6dfSMatthew G. Knepley /*@ 1281412e9a14SMatthew G. Knepley DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value 1282412e9a14SMatthew G. Knepley 1283412e9a14SMatthew G. Knepley Not collective 1284412e9a14SMatthew G. Knepley 1285412e9a14SMatthew G. Knepley Input Parameters: 1286412e9a14SMatthew G. Knepley + label - The DMLabel 1287412e9a14SMatthew G. Knepley . value - The label value for all points 1288412e9a14SMatthew G. Knepley . pStart - The first point 1289412e9a14SMatthew G. Knepley - pEnd - A point beyond all marked points 1290412e9a14SMatthew G. Knepley 1291412e9a14SMatthew G. Knepley Note: The marks points are [pStart, pEnd), and only the bounds are stored. 1292412e9a14SMatthew G. Knepley 1293412e9a14SMatthew G. Knepley Level: intermediate 1294412e9a14SMatthew G. Knepley 1295412e9a14SMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelSetStratumIS(), DMLabelGetStratumIS() 1296412e9a14SMatthew G. Knepley @*/ 1297412e9a14SMatthew G. Knepley PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd) 1298412e9a14SMatthew G. Knepley { 1299412e9a14SMatthew G. Knepley IS pIS; 1300412e9a14SMatthew G. Knepley PetscErrorCode ierr; 1301412e9a14SMatthew G. Knepley 1302412e9a14SMatthew G. Knepley PetscFunctionBegin; 1303412e9a14SMatthew G. Knepley ierr = ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS);CHKERRQ(ierr); 1304412e9a14SMatthew G. Knepley ierr = DMLabelSetStratumIS(label, value, pIS);CHKERRQ(ierr); 1305412e9a14SMatthew G. Knepley ierr = ISDestroy(&pIS);CHKERRQ(ierr); 1306412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 1307412e9a14SMatthew G. Knepley } 1308412e9a14SMatthew G. Knepley 1309412e9a14SMatthew G. Knepley /*@ 131084f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 131184f0b6dfSMatthew G. Knepley 13125b5e7992SMatthew G. Knepley Not collective 13135b5e7992SMatthew G. Knepley 131484f0b6dfSMatthew G. Knepley Input Parameters: 131584f0b6dfSMatthew G. Knepley + label - the DMLabel 131622cd2cdaSVaclav Hapla . start - the first point kept 131722cd2cdaSVaclav Hapla - end - one more than the last point kept 131884f0b6dfSMatthew G. Knepley 131984f0b6dfSMatthew G. Knepley Level: intermediate 132084f0b6dfSMatthew G. Knepley 132184f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 132284f0b6dfSMatthew G. Knepley @*/ 1323c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1324c58f1c22SToby Isaac { 1325c58f1c22SToby Isaac PetscInt v; 1326c58f1c22SToby Isaac PetscErrorCode ierr; 1327c58f1c22SToby Isaac 1328c58f1c22SToby Isaac PetscFunctionBegin; 1329d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 13300c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 1331c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1332c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 13339106b633SVaclav Hapla ierr = ISGeneralFilter(label->points[v], start, end);CHKERRQ(ierr); 1334c58f1c22SToby Isaac } 1335c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, start, end);CHKERRQ(ierr); 1336c58f1c22SToby Isaac PetscFunctionReturn(0); 1337c58f1c22SToby Isaac } 1338c58f1c22SToby Isaac 133984f0b6dfSMatthew G. Knepley /*@ 134084f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 134184f0b6dfSMatthew G. Knepley 13425b5e7992SMatthew G. Knepley Not collective 13435b5e7992SMatthew G. Knepley 134484f0b6dfSMatthew G. Knepley Input Parameters: 134584f0b6dfSMatthew G. Knepley + label - the DMLabel 134684f0b6dfSMatthew G. Knepley - permutation - the point permutation 134784f0b6dfSMatthew G. Knepley 134884f0b6dfSMatthew G. Knepley Output Parameter: 134984f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 135084f0b6dfSMatthew G. Knepley 135184f0b6dfSMatthew G. Knepley Level: intermediate 135284f0b6dfSMatthew G. Knepley 135384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 135484f0b6dfSMatthew G. Knepley @*/ 1355c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1356c58f1c22SToby Isaac { 1357c58f1c22SToby Isaac const PetscInt *perm; 1358c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1359c58f1c22SToby Isaac PetscErrorCode ierr; 1360c58f1c22SToby Isaac 1361c58f1c22SToby Isaac PetscFunctionBegin; 1362d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1363d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 1364c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1365c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, labelNew);CHKERRQ(ierr); 1366c58f1c22SToby Isaac ierr = DMLabelGetNumValues(*labelNew, &numValues);CHKERRQ(ierr); 1367c58f1c22SToby Isaac ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr); 1368c58f1c22SToby Isaac ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr); 1369c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1370c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1371ad8374ffSToby Isaac const PetscInt *points; 1372ad8374ffSToby Isaac PetscInt *pointsNew; 1373c58f1c22SToby Isaac 1374ad8374ffSToby Isaac ierr = ISGetIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1375ad8374ffSToby Isaac ierr = PetscMalloc1(size,&pointsNew);CHKERRQ(ierr); 1376c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1377ad8374ffSToby Isaac const PetscInt point = points[q]; 1378c58f1c22SToby Isaac 1379c58f1c22SToby 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); 1380ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1381c58f1c22SToby Isaac } 1382ad8374ffSToby Isaac ierr = ISRestoreIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1383ad8374ffSToby Isaac ierr = PetscSortInt(size, pointsNew);CHKERRQ(ierr); 1384ad8374ffSToby Isaac ierr = ISDestroy(&((*labelNew)->points[v]));CHKERRQ(ierr); 1385fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 1386fa8e8ae5SToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]));CHKERRQ(ierr); 1387fa8e8ae5SToby Isaac ierr = PetscFree(pointsNew);CHKERRQ(ierr); 1388fa8e8ae5SToby Isaac } else { 1389ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]));CHKERRQ(ierr); 1390fa8e8ae5SToby Isaac } 1391ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices");CHKERRQ(ierr); 1392c58f1c22SToby Isaac } 1393c58f1c22SToby Isaac ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr); 1394c58f1c22SToby Isaac if (label->bt) { 1395c58f1c22SToby Isaac ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 1396c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 1397c58f1c22SToby Isaac } 1398c58f1c22SToby Isaac PetscFunctionReturn(0); 1399c58f1c22SToby Isaac } 1400c58f1c22SToby Isaac 140126c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 140226c55118SMichael Lange { 140326c55118SMichael Lange MPI_Comm comm; 140426c55118SMichael Lange PetscInt s, l, nroots, nleaves, dof, offset, size; 140526c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 140626c55118SMichael Lange PetscSection rootSection; 140726c55118SMichael Lange PetscSF labelSF; 140826c55118SMichael Lange PetscErrorCode ierr; 140926c55118SMichael Lange 141026c55118SMichael Lange PetscFunctionBegin; 141126c55118SMichael Lange if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 141226c55118SMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 141326c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 141426c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 141526c55118SMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL);CHKERRQ(ierr); 141626c55118SMichael Lange ierr = PetscSectionCreate(comm, &rootSection);CHKERRQ(ierr); 141726c55118SMichael Lange ierr = PetscSectionSetChart(rootSection, 0, nroots);CHKERRQ(ierr); 141826c55118SMichael Lange if (label) { 141926c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1420ad8374ffSToby Isaac const PetscInt *points; 1421ad8374ffSToby Isaac 1422ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 142326c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1424ad8374ffSToby Isaac ierr = PetscSectionGetDof(rootSection, points[l], &dof);CHKERRQ(ierr); 1425ad8374ffSToby Isaac ierr = PetscSectionSetDof(rootSection, points[l], dof+1);CHKERRQ(ierr); 142626c55118SMichael Lange } 1427ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 142826c55118SMichael Lange } 142926c55118SMichael Lange } 143026c55118SMichael Lange ierr = PetscSectionSetUp(rootSection);CHKERRQ(ierr); 143126c55118SMichael Lange /* Create a point-wise array of stratum values */ 143226c55118SMichael Lange ierr = PetscSectionGetStorageSize(rootSection, &size);CHKERRQ(ierr); 143326c55118SMichael Lange ierr = PetscMalloc1(size, &rootStrata);CHKERRQ(ierr); 143426c55118SMichael Lange ierr = PetscCalloc1(nroots, &rootIdx);CHKERRQ(ierr); 143526c55118SMichael Lange if (label) { 143626c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1437ad8374ffSToby Isaac const PetscInt *points; 1438ad8374ffSToby Isaac 1439ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 144026c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1441ad8374ffSToby Isaac const PetscInt p = points[l]; 144226c55118SMichael Lange ierr = PetscSectionGetOffset(rootSection, p, &offset);CHKERRQ(ierr); 144326c55118SMichael Lange rootStrata[offset+rootIdx[p]++] = label->stratumValues[s]; 144426c55118SMichael Lange } 1445ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 144626c55118SMichael Lange } 144726c55118SMichael Lange } 144826c55118SMichael Lange /* Build SF that maps label points to remote processes */ 144926c55118SMichael Lange ierr = PetscSectionCreate(comm, leafSection);CHKERRQ(ierr); 145026c55118SMichael Lange ierr = PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection);CHKERRQ(ierr); 145126c55118SMichael Lange ierr = PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF);CHKERRQ(ierr); 145226c55118SMichael Lange ierr = PetscFree(remoteOffsets);CHKERRQ(ierr); 145326c55118SMichael Lange /* Send the strata for each point over the derived SF */ 145426c55118SMichael Lange ierr = PetscSectionGetStorageSize(*leafSection, &size);CHKERRQ(ierr); 145526c55118SMichael Lange ierr = PetscMalloc1(size, leafStrata);CHKERRQ(ierr); 1456ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE);CHKERRQ(ierr); 1457ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE);CHKERRQ(ierr); 145826c55118SMichael Lange /* Clean up */ 145926c55118SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 146026c55118SMichael Lange ierr = PetscFree(rootIdx);CHKERRQ(ierr); 146126c55118SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 146226c55118SMichael Lange ierr = PetscSFDestroy(&labelSF);CHKERRQ(ierr); 146326c55118SMichael Lange PetscFunctionReturn(0); 146426c55118SMichael Lange } 146526c55118SMichael Lange 146684f0b6dfSMatthew G. Knepley /*@ 146784f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 146884f0b6dfSMatthew G. Knepley 14695b5e7992SMatthew G. Knepley Collective on sf 14705b5e7992SMatthew G. Knepley 147184f0b6dfSMatthew G. Knepley Input Parameters: 147284f0b6dfSMatthew G. Knepley + label - the DMLabel 147384f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 147484f0b6dfSMatthew G. Knepley 147584f0b6dfSMatthew G. Knepley Output Parameter: 147684f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 147784f0b6dfSMatthew G. Knepley 147884f0b6dfSMatthew G. Knepley Level: intermediate 147984f0b6dfSMatthew G. Knepley 148084f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 148184f0b6dfSMatthew G. Knepley @*/ 1482c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1483c58f1c22SToby Isaac { 1484c58f1c22SToby Isaac MPI_Comm comm; 148526c55118SMichael Lange PetscSection leafSection; 148626c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 148726c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1488ad8374ffSToby Isaac PetscInt **points; 1489d67d17b1SMatthew G. Knepley const char *lname = NULL; 1490c58f1c22SToby Isaac char *name; 1491c58f1c22SToby Isaac PetscInt nameSize; 1492e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1493c58f1c22SToby Isaac size_t len = 0; 149426c55118SMichael Lange PetscMPIInt rank; 1495c58f1c22SToby Isaac PetscErrorCode ierr; 1496c58f1c22SToby Isaac 1497c58f1c22SToby Isaac PetscFunctionBegin; 1498d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1499f018e600SMatthew G. Knepley if (label) { 1500f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1501f018e600SMatthew G. Knepley ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1502f018e600SMatthew G. Knepley } 1503c58f1c22SToby Isaac ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 1504ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1505c58f1c22SToby Isaac /* Bcast name */ 1506d67d17b1SMatthew G. Knepley if (!rank) { 1507d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 1508d67d17b1SMatthew G. Knepley ierr = PetscStrlen(lname, &len);CHKERRQ(ierr); 1509d67d17b1SMatthew G. Knepley } 1510c58f1c22SToby Isaac nameSize = len; 1511ffc4695bSBarry Smith ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1512c58f1c22SToby Isaac ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1513580bdb30SBarry Smith if (!rank) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);} 1514ffc4695bSBarry Smith ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr); 1515d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr); 1516c58f1c22SToby Isaac ierr = PetscFree(name);CHKERRQ(ierr); 151777d236dfSMichael Lange /* Bcast defaultValue */ 151877d236dfSMichael Lange if (!rank) (*labelNew)->defaultValue = label->defaultValue; 1519ffc4695bSBarry Smith ierr = MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 152026c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 152126c55118SMichael Lange ierr = DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata);CHKERRQ(ierr); 15225cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 1523e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&stratumHash);CHKERRQ(ierr); 152426c55118SMichael Lange ierr = PetscSectionGetStorageSize(leafSection, &size);CHKERRQ(ierr); 1525e8f14785SLisandro Dalcin for (p = 0; p < size; ++p) {ierr = PetscHSetIAdd(stratumHash, leafStrata[p]);CHKERRQ(ierr);} 1526e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata);CHKERRQ(ierr); 1527ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS);CHKERRQ(ierr); 1528ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 15295cbdf6fcSMichael Lange ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues);CHKERRQ(ierr); 15305cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 15315cbdf6fcSMichael Lange offset = 0; 1532e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues);CHKERRQ(ierr); 1533a205f1fdSToby Isaac ierr = PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues);CHKERRQ(ierr); 153490e9b2aeSLisandro Dalcin for (s = 0; s < (*labelNew)->numStrata; ++s) { 153590e9b2aeSLisandro Dalcin ierr = PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s);CHKERRQ(ierr); 153690e9b2aeSLisandro Dalcin } 15375cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1538231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 1539231b9e6fSMatthew G. Knepley if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;} 15405cbdf6fcSMichael Lange } 15415cbdf6fcSMichael Lange } 1542c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 1543c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes);CHKERRQ(ierr); 1544c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1545c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1546c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1547c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1548c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1549c58f1c22SToby Isaac (*labelNew)->stratumSizes[leafStrata[offset+s]]++; 1550c58f1c22SToby Isaac } 1551c58f1c22SToby Isaac } 1552c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht);CHKERRQ(ierr); 1553c58f1c22SToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points);CHKERRQ(ierr); 1554ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&points);CHKERRQ(ierr); 1555c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 1556e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelNew)->ht[s]);CHKERRQ(ierr); 1557ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]));CHKERRQ(ierr); 1558c58f1c22SToby Isaac } 1559c58f1c22SToby Isaac /* Insert points into new strata */ 1560c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata, &strataIdx);CHKERRQ(ierr); 1561c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1562c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1563c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1564c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1565c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1566c58f1c22SToby Isaac stratum = leafStrata[offset+s]; 1567ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1568c58f1c22SToby Isaac } 1569c58f1c22SToby Isaac } 1570ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1571ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]));CHKERRQ(ierr); 1572ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices");CHKERRQ(ierr); 1573ad8374ffSToby Isaac } 1574ad8374ffSToby Isaac ierr = PetscFree(points);CHKERRQ(ierr); 1575e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&stratumHash);CHKERRQ(ierr); 1576c58f1c22SToby Isaac ierr = PetscFree(leafStrata);CHKERRQ(ierr); 1577c58f1c22SToby Isaac ierr = PetscFree(strataIdx);CHKERRQ(ierr); 1578c58f1c22SToby Isaac ierr = PetscSectionDestroy(&leafSection);CHKERRQ(ierr); 1579c58f1c22SToby Isaac PetscFunctionReturn(0); 1580c58f1c22SToby Isaac } 1581c58f1c22SToby Isaac 15827937d9ceSMichael Lange /*@ 15837937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 15847937d9ceSMichael Lange 15855b5e7992SMatthew G. Knepley Collective on sf 15865b5e7992SMatthew G. Knepley 15877937d9ceSMichael Lange Input Parameters: 15887937d9ceSMichael Lange + label - the DMLabel 158984f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 15907937d9ceSMichael Lange 159184f0b6dfSMatthew G. Knepley Output Parameters: 159284f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 15937937d9ceSMichael Lange 15947937d9ceSMichael Lange Level: developer 15957937d9ceSMichael Lange 15967937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 15977937d9ceSMichael Lange 15987937d9ceSMichael Lange .seealso: DMLabelDistribute() 15997937d9ceSMichael Lange @*/ 16007937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 16017937d9ceSMichael Lange { 16027937d9ceSMichael Lange MPI_Comm comm; 16037937d9ceSMichael Lange PetscSection rootSection; 16047937d9ceSMichael Lange PetscSF sfLabel; 16057937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 16067937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 16077937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 16087937d9ceSMichael Lange PetscInt *rootStrata; 1609d67d17b1SMatthew G. Knepley const char *lname; 16107937d9ceSMichael Lange char *name; 16117937d9ceSMichael Lange PetscInt nameSize; 16127937d9ceSMichael Lange size_t len = 0; 16139852e123SBarry Smith PetscMPIInt rank, size; 16147937d9ceSMichael Lange PetscErrorCode ierr; 16157937d9ceSMichael Lange 16167937d9ceSMichael Lange PetscFunctionBegin; 1617d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1618d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 16197937d9ceSMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 1620ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1621ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 16227937d9ceSMichael Lange /* Bcast name */ 1623d67d17b1SMatthew G. Knepley if (!rank) { 1624d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 1625d67d17b1SMatthew G. Knepley ierr = PetscStrlen(lname, &len);CHKERRQ(ierr); 1626d67d17b1SMatthew G. Knepley } 16277937d9ceSMichael Lange nameSize = len; 1628ffc4695bSBarry Smith ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 16297937d9ceSMichael Lange ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1630580bdb30SBarry Smith if (!rank) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);} 1631ffc4695bSBarry Smith ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr); 1632d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr); 16337937d9ceSMichael Lange ierr = PetscFree(name);CHKERRQ(ierr); 16347937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 16357937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 16367937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 16377937d9ceSMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL);CHKERRQ(ierr); 1638dc53bc9bSMatthew G. Knepley ierr = PetscMalloc1(nroots, &leafPoints);CHKERRQ(ierr); 1639dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 16407937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 16418212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 16428212dd46SStefano Zampini 16438212dd46SStefano Zampini leafPoints[ilp].index = ilp; 16448212dd46SStefano Zampini leafPoints[ilp].rank = rank; 16457937d9ceSMichael Lange } 16467937d9ceSMichael Lange ierr = PetscSFComputeDegreeBegin(sf, &rootDegree);CHKERRQ(ierr); 16477937d9ceSMichael Lange ierr = PetscSFComputeDegreeEnd(sf, &rootDegree);CHKERRQ(ierr); 16487937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 16497937d9ceSMichael Lange ierr = PetscMalloc1(nmultiroots, &rootPoints);CHKERRQ(ierr); 16507937d9ceSMichael Lange ierr = PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 16517937d9ceSMichael Lange ierr = PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 16527937d9ceSMichael Lange ierr = PetscSFCreate(comm,& sfLabel);CHKERRQ(ierr); 16537937d9ceSMichael Lange ierr = PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 16547937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 16557937d9ceSMichael Lange ierr = DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata);CHKERRQ(ierr); 16567937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 16577937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 16587937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 16597937d9ceSMichael Lange ierr = PetscSectionGetDof(rootSection, idx+d, &dof);CHKERRQ(ierr); 16607937d9ceSMichael Lange ierr = PetscSectionGetOffset(rootSection, idx+d, &offset);CHKERRQ(ierr); 16617937d9ceSMichael Lange for (s = 0; s < dof; s++) {ierr = DMLabelSetValue(*labelNew, p, rootStrata[offset+s]);CHKERRQ(ierr);} 16627937d9ceSMichael Lange } 16637937d9ceSMichael Lange idx += rootDegree[p]; 16647937d9ceSMichael Lange } 166577e0c0e7SMichael Lange ierr = PetscFree(leafPoints);CHKERRQ(ierr); 166677e0c0e7SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 166777e0c0e7SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 166877e0c0e7SMichael Lange ierr = PetscSFDestroy(&sfLabel);CHKERRQ(ierr); 16697937d9ceSMichael Lange PetscFunctionReturn(0); 16707937d9ceSMichael Lange } 16717937d9ceSMichael Lange 167284f0b6dfSMatthew G. Knepley /*@ 167384f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 167484f0b6dfSMatthew G. Knepley 16755b5e7992SMatthew G. Knepley Not collective 16765b5e7992SMatthew G. Knepley 167784f0b6dfSMatthew G. Knepley Input Parameter: 167884f0b6dfSMatthew G. Knepley . label - the DMLabel 167984f0b6dfSMatthew G. Knepley 168084f0b6dfSMatthew G. Knepley Output Parameters: 168184f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 168284f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 168384f0b6dfSMatthew G. Knepley 168484f0b6dfSMatthew G. Knepley Level: developer 168584f0b6dfSMatthew G. Knepley 168684f0b6dfSMatthew G. Knepley .seealso: DMLabelDistribute() 168784f0b6dfSMatthew G. Knepley @*/ 1688c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 1689c58f1c22SToby Isaac { 1690c58f1c22SToby Isaac IS vIS; 1691c58f1c22SToby Isaac const PetscInt *values; 1692c58f1c22SToby Isaac PetscInt *points; 1693c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 1694c58f1c22SToby Isaac PetscErrorCode ierr; 1695c58f1c22SToby Isaac 1696c58f1c22SToby Isaac PetscFunctionBegin; 1697d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1698c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr); 1699c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr); 1700c58f1c22SToby Isaac ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr); 1701c58f1c22SToby Isaac if (nV) {vS = values[0]; vE = values[0]+1;} 1702c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 1703c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 1704c58f1c22SToby Isaac vE = PetscMax(vE, values[v]+1); 1705c58f1c22SToby Isaac } 1706c58f1c22SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr); 1707c58f1c22SToby Isaac ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr); 1708c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1709c58f1c22SToby Isaac PetscInt n; 1710c58f1c22SToby Isaac 1711c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr); 1712c58f1c22SToby Isaac ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr); 1713c58f1c22SToby Isaac } 1714c58f1c22SToby Isaac ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 1715c58f1c22SToby Isaac ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr); 1716c58f1c22SToby Isaac ierr = PetscMalloc1(N, &points);CHKERRQ(ierr); 1717c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1718c58f1c22SToby Isaac IS is; 1719c58f1c22SToby Isaac const PetscInt *spoints; 1720c58f1c22SToby Isaac PetscInt dof, off, p; 1721c58f1c22SToby Isaac 1722c58f1c22SToby Isaac ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr); 1723c58f1c22SToby Isaac ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr); 1724c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr); 1725c58f1c22SToby Isaac ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr); 1726c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; 1727c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr); 1728c58f1c22SToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 1729c58f1c22SToby Isaac } 1730c58f1c22SToby Isaac ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr); 1731c58f1c22SToby Isaac ierr = ISDestroy(&vIS);CHKERRQ(ierr); 1732c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 1733c58f1c22SToby Isaac PetscFunctionReturn(0); 1734c58f1c22SToby Isaac } 1735c58f1c22SToby Isaac 173684f0b6dfSMatthew G. Knepley /*@ 1737c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 1738c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 1739c58f1c22SToby Isaac 17405b5e7992SMatthew G. Knepley Collective on sf 17415b5e7992SMatthew G. Knepley 1742c58f1c22SToby Isaac Input Parameters: 1743c58f1c22SToby Isaac + s - The PetscSection for the local field layout 1744c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 1745c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 1746c58f1c22SToby Isaac . label - The label specifying the points 1747c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 1748c58f1c22SToby Isaac 1749c58f1c22SToby Isaac Output Parameter: 1750c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 1751c58f1c22SToby Isaac 1752c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 1753c58f1c22SToby Isaac 1754c58f1c22SToby Isaac Level: developer 1755c58f1c22SToby Isaac 1756c58f1c22SToby Isaac .seealso: PetscSectionCreate() 1757c58f1c22SToby Isaac @*/ 1758c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 1759c58f1c22SToby Isaac { 1760c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 1761c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 1762c58f1c22SToby Isaac PetscErrorCode ierr; 1763c58f1c22SToby Isaac 1764c58f1c22SToby Isaac PetscFunctionBegin; 1765d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1766d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1767d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 1768c58f1c22SToby Isaac ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr); 1769c58f1c22SToby Isaac ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1770c58f1c22SToby Isaac ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr); 1771c58f1c22SToby Isaac ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 1772c58f1c22SToby Isaac if (nroots >= 0) { 1773c58f1c22SToby Isaac if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart); 1774c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr); 1775c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1776c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr); 1777c58f1c22SToby Isaac } else { 1778c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 1779c58f1c22SToby Isaac } 1780c58f1c22SToby Isaac } 1781c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 1782c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 1783c58f1c22SToby Isaac PetscInt value; 1784c58f1c22SToby Isaac 1785c58f1c22SToby Isaac ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr); 1786c58f1c22SToby Isaac if (value != labelValue) continue; 1787c58f1c22SToby Isaac ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1788c58f1c22SToby Isaac ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr); 1789c58f1c22SToby Isaac ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1790c58f1c22SToby Isaac if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);} 1791c58f1c22SToby Isaac if (neg) neg[p] = -(dof+1); 1792c58f1c22SToby Isaac } 1793c58f1c22SToby Isaac ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr); 1794c58f1c22SToby Isaac if (nroots >= 0) { 1795ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 1796ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 1797c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1798c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 1799c58f1c22SToby Isaac } 1800c58f1c22SToby Isaac } 1801c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 1802c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1803c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 1804c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 1805c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 1806c58f1c22SToby Isaac } 180755b25c41SPierre Jolivet ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRMPI(ierr); 1808c58f1c22SToby Isaac globalOff -= off; 1809c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1810c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 1811c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 1812c58f1c22SToby Isaac } 1813c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 1814c58f1c22SToby Isaac if (nroots >= 0) { 1815ad227feaSJunchao Zhang ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 1816ad227feaSJunchao Zhang ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr); 1817c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1818c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 1819c58f1c22SToby Isaac } 1820c58f1c22SToby Isaac } 1821c58f1c22SToby Isaac if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);} 1822c58f1c22SToby Isaac ierr = PetscFree(neg);CHKERRQ(ierr); 1823c58f1c22SToby Isaac PetscFunctionReturn(0); 1824c58f1c22SToby Isaac } 1825c58f1c22SToby Isaac 18265fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label 18275fdea053SToby Isaac { 18285fdea053SToby Isaac DMLabel label; 18295fdea053SToby Isaac PetscCopyMode *modes; 18305fdea053SToby Isaac PetscInt *sizes; 18315fdea053SToby Isaac const PetscInt ***perms; 18325fdea053SToby Isaac const PetscScalar ***rots; 18335fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 18345fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 18355fdea053SToby Isaac } PetscSectionSym_Label; 18365fdea053SToby Isaac 18375fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 18385fdea053SToby Isaac { 18395fdea053SToby Isaac PetscInt i, j; 18405fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 18415fdea053SToby Isaac PetscErrorCode ierr; 18425fdea053SToby Isaac 18435fdea053SToby Isaac PetscFunctionBegin; 18445fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 18455fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 18465fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 18475fdea053SToby Isaac if (sl->perms[i]) {ierr = PetscFree(sl->perms[i][j]);CHKERRQ(ierr);} 18485fdea053SToby Isaac if (sl->rots[i]) {ierr = PetscFree(sl->rots[i][j]);CHKERRQ(ierr);} 18495fdea053SToby Isaac } 18505fdea053SToby Isaac if (sl->perms[i]) { 18515fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 18525fdea053SToby Isaac 18535fdea053SToby Isaac ierr = PetscFree(perms);CHKERRQ(ierr); 18545fdea053SToby Isaac } 18555fdea053SToby Isaac if (sl->rots[i]) { 18565fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 18575fdea053SToby Isaac 18585fdea053SToby Isaac ierr = PetscFree(rots);CHKERRQ(ierr); 18595fdea053SToby Isaac } 18605fdea053SToby Isaac } 18615fdea053SToby Isaac } 18625fdea053SToby Isaac ierr = PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients);CHKERRQ(ierr); 18635fdea053SToby Isaac ierr = DMLabelDestroy(&sl->label);CHKERRQ(ierr); 18645fdea053SToby Isaac sl->numStrata = 0; 18655fdea053SToby Isaac PetscFunctionReturn(0); 18665fdea053SToby Isaac } 18675fdea053SToby Isaac 18685fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 18695fdea053SToby Isaac { 18705fdea053SToby Isaac PetscErrorCode ierr; 18715fdea053SToby Isaac 18725fdea053SToby Isaac PetscFunctionBegin; 18735fdea053SToby Isaac ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr); 18745fdea053SToby Isaac ierr = PetscFree(sym->data);CHKERRQ(ierr); 18755fdea053SToby Isaac PetscFunctionReturn(0); 18765fdea053SToby Isaac } 18775fdea053SToby Isaac 18785fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 18795fdea053SToby Isaac { 18805fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 18815fdea053SToby Isaac PetscBool isAscii; 18825fdea053SToby Isaac DMLabel label = sl->label; 1883d67d17b1SMatthew G. Knepley const char *name; 18845fdea053SToby Isaac PetscErrorCode ierr; 18855fdea053SToby Isaac 18865fdea053SToby Isaac PetscFunctionBegin; 18875fdea053SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii);CHKERRQ(ierr); 18885fdea053SToby Isaac if (isAscii) { 18895fdea053SToby Isaac PetscInt i, j, k; 18905fdea053SToby Isaac PetscViewerFormat format; 18915fdea053SToby Isaac 18925fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 18935fdea053SToby Isaac if (label) { 18945fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 18955fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 18965fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 18975fdea053SToby Isaac ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 18985fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 18995fdea053SToby Isaac } else { 1900d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr); 1901d67d17b1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer," Label '%s'\n",name);CHKERRQ(ierr); 19025fdea053SToby Isaac } 19035fdea053SToby Isaac } else { 19045fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "No label given\n");CHKERRQ(ierr); 19055fdea053SToby Isaac } 19065fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 19075fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 19085fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 19095fdea053SToby Isaac 19105fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 19115fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point): no symmetries\n", value, sl->sizes[i]);CHKERRQ(ierr); 19125fdea053SToby Isaac } else { 19135fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point):\n", value, sl->sizes[i]);CHKERRQ(ierr); 19145fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 19155fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation range: [%D, %D)\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1]);CHKERRQ(ierr); 19165fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 19175fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 19185fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 19195fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 19205fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D: identity\n",j);CHKERRQ(ierr); 19215fdea053SToby Isaac } else { 19225fdea053SToby Isaac PetscInt tab; 19235fdea053SToby Isaac 19245fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D:\n",j);CHKERRQ(ierr); 19255fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 19265fdea053SToby Isaac ierr = PetscViewerASCIIGetTab(viewer,&tab);CHKERRQ(ierr); 19275fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 19285fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Permutation:");CHKERRQ(ierr); 19295fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 19305fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %D",sl->perms[i][j][k]);CHKERRQ(ierr);} 19315fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 19325fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 19335fdea053SToby Isaac } 19345fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 19355fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Rotations: ");CHKERRQ(ierr); 19365fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 19375fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 19385fdea053SToby 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);} 19395fdea053SToby Isaac #else 19405fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f",sl->rots[i][j][k]);CHKERRQ(ierr);} 19415fdea053SToby Isaac #endif 19425fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 19435fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 19445fdea053SToby Isaac } 19455fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19465fdea053SToby Isaac } 19475fdea053SToby Isaac } 19485fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19495fdea053SToby Isaac } 19505fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19515fdea053SToby Isaac } 19525fdea053SToby Isaac } 19535fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19545fdea053SToby Isaac } 19555fdea053SToby Isaac PetscFunctionReturn(0); 19565fdea053SToby Isaac } 19575fdea053SToby Isaac 19585fdea053SToby Isaac /*@ 19595fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 19605fdea053SToby Isaac 19615fdea053SToby Isaac Logically collective on sym 19625fdea053SToby Isaac 19635fdea053SToby Isaac Input parameters: 19645fdea053SToby Isaac + sym - the section symmetries 19655fdea053SToby Isaac - label - the DMLabel describing the types of points 19665fdea053SToby Isaac 19675fdea053SToby Isaac Level: developer: 19685fdea053SToby Isaac 19695fdea053SToby Isaac .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreateLabel(), PetscSectionGetPointSyms() 19705fdea053SToby Isaac @*/ 19715fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 19725fdea053SToby Isaac { 19735fdea053SToby Isaac PetscSectionSym_Label *sl; 19745fdea053SToby Isaac PetscErrorCode ierr; 19755fdea053SToby Isaac 19765fdea053SToby Isaac PetscFunctionBegin; 19775fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 19785fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 19795fdea053SToby Isaac if (sl->label && sl->label != label) {ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);} 19805fdea053SToby Isaac if (label) { 19815fdea053SToby Isaac sl->label = label; 1982d67d17b1SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 19835fdea053SToby Isaac ierr = DMLabelGetNumValues(label,&sl->numStrata);CHKERRQ(ierr); 19841a834cf9SToby 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); 19851a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode));CHKERRQ(ierr); 19861a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt));CHKERRQ(ierr); 19871a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **));CHKERRQ(ierr); 19881a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **));CHKERRQ(ierr); 19891a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]));CHKERRQ(ierr); 19905fdea053SToby Isaac } 19915fdea053SToby Isaac PetscFunctionReturn(0); 19925fdea053SToby Isaac } 19935fdea053SToby Isaac 19945fdea053SToby Isaac /*@C 19955fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 19965fdea053SToby Isaac 19975b5e7992SMatthew G. Knepley Logically collective on sym 19985fdea053SToby Isaac 19995fdea053SToby Isaac InputParameters: 20005b5e7992SMatthew G. Knepley + sym - the section symmetries 20015fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 20025fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 20035fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 20045fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 20055fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 20065fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 2007a2b725a8SWilliam 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 20085fdea053SToby Isaac 20095fdea053SToby Isaac Level: developer 20105fdea053SToby Isaac 20115fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel() 20125fdea053SToby Isaac @*/ 20135fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 20145fdea053SToby Isaac { 20155fdea053SToby Isaac PetscSectionSym_Label *sl; 2016d67d17b1SMatthew G. Knepley const char *name; 2017d67d17b1SMatthew G. Knepley PetscInt i, j, k; 20185fdea053SToby Isaac PetscErrorCode ierr; 20195fdea053SToby Isaac 20205fdea053SToby Isaac PetscFunctionBegin; 20215fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 20225fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 20235fdea053SToby Isaac if (!sl->label) SETERRQ(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_WRONGSTATE,"No label set yet"); 20245fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 20255fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 20265fdea053SToby Isaac 20275fdea053SToby Isaac if (stratum == value) break; 20285fdea053SToby Isaac } 2029d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr); 2030d67d17b1SMatthew G. Knepley if (i > sl->numStrata) SETERRQ2(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_OUTOFRANGE,"Stratum %D not found in label %s\n",stratum,name); 20315fdea053SToby Isaac sl->sizes[i] = size; 20325fdea053SToby Isaac sl->modes[i] = mode; 20335fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 20345fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 20355fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 20365fdea053SToby Isaac if (perms) { 20375fdea053SToby Isaac PetscInt **ownPerms; 20385fdea053SToby Isaac 20395fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownPerms);CHKERRQ(ierr); 20405fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 20415fdea053SToby Isaac if (perms[j]) { 20425fdea053SToby Isaac ierr = PetscMalloc1(size,&ownPerms[j]);CHKERRQ(ierr); 20435fdea053SToby Isaac for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];} 20445fdea053SToby Isaac } 20455fdea053SToby Isaac } 20465fdea053SToby Isaac sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient]; 20475fdea053SToby Isaac } 20485fdea053SToby Isaac if (rots) { 20495fdea053SToby Isaac PetscScalar **ownRots; 20505fdea053SToby Isaac 20515fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownRots);CHKERRQ(ierr); 20525fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 20535fdea053SToby Isaac if (rots[j]) { 20545fdea053SToby Isaac ierr = PetscMalloc1(size,&ownRots[j]);CHKERRQ(ierr); 20555fdea053SToby Isaac for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];} 20565fdea053SToby Isaac } 20575fdea053SToby Isaac } 20585fdea053SToby Isaac sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient]; 20595fdea053SToby Isaac } 20605fdea053SToby Isaac } else { 20615fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 20625fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 20635fdea053SToby Isaac } 20645fdea053SToby Isaac PetscFunctionReturn(0); 20655fdea053SToby Isaac } 20665fdea053SToby Isaac 20675fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 20685fdea053SToby Isaac { 20695fdea053SToby Isaac PetscInt i, j, numStrata; 20705fdea053SToby Isaac PetscSectionSym_Label *sl; 20715fdea053SToby Isaac DMLabel label; 20725fdea053SToby Isaac PetscErrorCode ierr; 20735fdea053SToby Isaac 20745fdea053SToby Isaac PetscFunctionBegin; 20755fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 20765fdea053SToby Isaac numStrata = sl->numStrata; 20775fdea053SToby Isaac label = sl->label; 20785fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 20795fdea053SToby Isaac PetscInt point = points[2*i]; 20805fdea053SToby Isaac PetscInt ornt = points[2*i+1]; 20815fdea053SToby Isaac 20825fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 20835fdea053SToby Isaac if (label->validIS[j]) { 20845fdea053SToby Isaac PetscInt k; 20855fdea053SToby Isaac 20865fdea053SToby Isaac ierr = ISLocate(label->points[j],point,&k);CHKERRQ(ierr); 20875fdea053SToby Isaac if (k >= 0) break; 20885fdea053SToby Isaac } else { 20895fdea053SToby Isaac PetscBool has; 20905fdea053SToby Isaac 2091b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[j], point, &has);CHKERRQ(ierr); 20925fdea053SToby Isaac if (has) break; 20935fdea053SToby Isaac } 20945fdea053SToby Isaac } 20955fdea053SToby 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); 20965fdea053SToby Isaac if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;} 20975fdea053SToby Isaac if (rots) {rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL;} 20985fdea053SToby Isaac } 20995fdea053SToby Isaac PetscFunctionReturn(0); 21005fdea053SToby Isaac } 21015fdea053SToby Isaac 21025fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 21035fdea053SToby Isaac { 21045fdea053SToby Isaac PetscSectionSym_Label *sl; 21055fdea053SToby Isaac PetscErrorCode ierr; 21065fdea053SToby Isaac 21075fdea053SToby Isaac PetscFunctionBegin; 21085fdea053SToby Isaac ierr = PetscNewLog(sym,&sl);CHKERRQ(ierr); 21095fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 21105fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 21115fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 21125fdea053SToby Isaac sym->data = (void *) sl; 21135fdea053SToby Isaac PetscFunctionReturn(0); 21145fdea053SToby Isaac } 21155fdea053SToby Isaac 21165fdea053SToby Isaac /*@ 21175fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 21185fdea053SToby Isaac 21195fdea053SToby Isaac Collective 21205fdea053SToby Isaac 21215fdea053SToby Isaac Input Parameters: 21225fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 21235fdea053SToby Isaac - label - the label defining the strata 21245fdea053SToby Isaac 21255fdea053SToby Isaac Output Parameters: 21265fdea053SToby Isaac . sym - the section symmetries 21275fdea053SToby Isaac 21285fdea053SToby Isaac Level: developer 21295fdea053SToby Isaac 21305fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym(), PetscSectionSymLabelSetStratum(), PetscSectionGetPointSyms() 21315fdea053SToby Isaac @*/ 21325fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 21335fdea053SToby Isaac { 21345fdea053SToby Isaac PetscErrorCode ierr; 21355fdea053SToby Isaac 21365fdea053SToby Isaac PetscFunctionBegin; 21375fdea053SToby Isaac ierr = DMInitializePackage();CHKERRQ(ierr); 21385fdea053SToby Isaac ierr = PetscSectionSymCreate(comm,sym);CHKERRQ(ierr); 21395fdea053SToby Isaac ierr = PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL);CHKERRQ(ierr); 21405fdea053SToby Isaac ierr = PetscSectionSymLabelSetLabel(*sym,label);CHKERRQ(ierr); 21415fdea053SToby Isaac PetscFunctionReturn(0); 21425fdea053SToby Isaac } 2143