1c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 2c58f1c22SToby Isaac #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 3c58f1c22SToby Isaac #include <petscsf.h> 4c58f1c22SToby Isaac 5c58f1c22SToby Isaac #undef __FUNCT__ 6c58f1c22SToby Isaac #define __FUNCT__ "DMLabelCreate" 7c58f1c22SToby Isaac /*@C 8c58f1c22SToby Isaac DMLabelCreate - Create a DMLabel object, which is a multimap 9c58f1c22SToby Isaac 10c58f1c22SToby Isaac Input parameter: 11c58f1c22SToby Isaac . name - The label name 12c58f1c22SToby Isaac 13c58f1c22SToby Isaac Output parameter: 14c58f1c22SToby Isaac . label - The DMLabel 15c58f1c22SToby Isaac 16c58f1c22SToby Isaac Level: beginner 17c58f1c22SToby Isaac 18c58f1c22SToby Isaac .seealso: DMLabelDestroy() 19c58f1c22SToby Isaac @*/ 20c58f1c22SToby Isaac PetscErrorCode DMLabelCreate(const char name[], DMLabel *label) 21c58f1c22SToby Isaac { 22c58f1c22SToby Isaac PetscErrorCode ierr; 23c58f1c22SToby Isaac 24c58f1c22SToby Isaac PetscFunctionBegin; 25c58f1c22SToby Isaac ierr = PetscNew(label);CHKERRQ(ierr); 26c58f1c22SToby Isaac ierr = PetscStrallocpy(name, &(*label)->name);CHKERRQ(ierr); 27c58f1c22SToby Isaac 28c58f1c22SToby Isaac (*label)->refct = 1; 29c58f1c22SToby Isaac (*label)->state = -1; 30c58f1c22SToby Isaac (*label)->numStrata = 0; 315aa44df4SToby Isaac (*label)->defaultValue = -1; 32c58f1c22SToby Isaac (*label)->stratumValues = NULL; 33*ad8374ffSToby Isaac (*label)->validIS = NULL; 34c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 35c58f1c22SToby Isaac (*label)->points = NULL; 36c58f1c22SToby Isaac (*label)->ht = NULL; 37c58f1c22SToby Isaac (*label)->pStart = -1; 38c58f1c22SToby Isaac (*label)->pEnd = -1; 39c58f1c22SToby Isaac (*label)->bt = NULL; 40c58f1c22SToby Isaac PetscFunctionReturn(0); 41c58f1c22SToby Isaac } 42c58f1c22SToby Isaac 43c58f1c22SToby Isaac #undef __FUNCT__ 44c58f1c22SToby Isaac #define __FUNCT__ "DMLabelMakeValid_Private" 45c58f1c22SToby Isaac /* 46c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 47c58f1c22SToby Isaac 48c58f1c22SToby Isaac Input parameter: 49c58f1c22SToby Isaac + label - The DMLabel 50c58f1c22SToby Isaac - v - The stratum value 51c58f1c22SToby Isaac 52c58f1c22SToby Isaac Output parameter: 53c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format 54c58f1c22SToby Isaac 55c58f1c22SToby Isaac Level: developer 56c58f1c22SToby Isaac 57c58f1c22SToby Isaac .seealso: DMLabelCreate() 58c58f1c22SToby Isaac */ 59c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) 60c58f1c22SToby Isaac { 61c58f1c22SToby Isaac PetscInt off; 62*ad8374ffSToby Isaac PetscInt *pointArray; 63c58f1c22SToby Isaac PetscErrorCode ierr; 64c58f1c22SToby Isaac 65*ad8374ffSToby Isaac if (label->validIS[v]) return 0; 66c58f1c22SToby Isaac if (v >= label->numStrata) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D in DMLabelMakeValid_Private\n", v); 67c58f1c22SToby Isaac PetscFunctionBegin; 68c58f1c22SToby Isaac PetscHashISize(label->ht[v], label->stratumSizes[v]); 69c58f1c22SToby Isaac 70*ad8374ffSToby Isaac ierr = PetscMalloc1(label->stratumSizes[v], &pointArray);CHKERRQ(ierr); 71c58f1c22SToby Isaac off = 0; 72*ad8374ffSToby Isaac ierr = PetscHashIGetKeys(label->ht[v], &off, pointArray);CHKERRQ(ierr); 73c58f1c22SToby Isaac if (off != label->stratumSizes[v]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid number of contributed points %D from value %D should be %D", off, label->stratumValues[v], label->stratumSizes[v]); 74c58f1c22SToby Isaac PetscHashIClear(label->ht[v]); 75*ad8374ffSToby Isaac ierr = PetscSortInt(label->stratumSizes[v], pointArray);CHKERRQ(ierr); 76c58f1c22SToby Isaac if (label->bt) { 77c58f1c22SToby Isaac PetscInt p; 78c58f1c22SToby Isaac 79c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 80*ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 81c58f1c22SToby Isaac 82c58f1c22SToby 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); 83c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 84c58f1c22SToby Isaac } 85c58f1c22SToby Isaac } 86*ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,label->stratumSizes[v],pointArray,PETSC_OWN_POINTER,&(label->points[v]));CHKERRQ(ierr); 87*ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) (label->points[v]), "indices");CHKERRQ(ierr); 88*ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 89c58f1c22SToby Isaac ++label->state; 90c58f1c22SToby Isaac PetscFunctionReturn(0); 91c58f1c22SToby Isaac } 92c58f1c22SToby Isaac 93c58f1c22SToby Isaac #undef __FUNCT__ 94c58f1c22SToby Isaac #define __FUNCT__ "DMLabelMakeAllValid_Private" 95c58f1c22SToby Isaac /* 96c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 97c58f1c22SToby Isaac 98c58f1c22SToby Isaac Input parameter: 99c58f1c22SToby Isaac . label - The DMLabel 100c58f1c22SToby Isaac 101c58f1c22SToby Isaac Output parameter: 102c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format 103c58f1c22SToby Isaac 104c58f1c22SToby Isaac Level: developer 105c58f1c22SToby Isaac 106c58f1c22SToby Isaac .seealso: DMLabelCreate() 107c58f1c22SToby Isaac */ 108c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 109c58f1c22SToby Isaac { 110c58f1c22SToby Isaac PetscInt v; 111c58f1c22SToby Isaac PetscErrorCode ierr; 112c58f1c22SToby Isaac 113c58f1c22SToby Isaac PetscFunctionBegin; 114c58f1c22SToby Isaac for (v = 0; v < label->numStrata; v++){ 115c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 116c58f1c22SToby Isaac } 117c58f1c22SToby Isaac PetscFunctionReturn(0); 118c58f1c22SToby Isaac } 119c58f1c22SToby Isaac 120c58f1c22SToby Isaac #undef __FUNCT__ 121c58f1c22SToby Isaac #define __FUNCT__ "DMLabelMakeInvalid_Private" 122c58f1c22SToby Isaac /* 123c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 124c58f1c22SToby Isaac 125c58f1c22SToby Isaac Input parameter: 126c58f1c22SToby Isaac + label - The DMLabel 127c58f1c22SToby Isaac - v - The stratum value 128c58f1c22SToby Isaac 129c58f1c22SToby Isaac Output parameter: 130c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format 131c58f1c22SToby Isaac 132c58f1c22SToby Isaac Level: developer 133c58f1c22SToby Isaac 134c58f1c22SToby Isaac .seealso: DMLabelCreate() 135c58f1c22SToby Isaac */ 136c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 137c58f1c22SToby Isaac { 138c58f1c22SToby Isaac PETSC_UNUSED PetscHashIIter ret, iter; 139c58f1c22SToby Isaac PetscInt p; 140*ad8374ffSToby Isaac const PetscInt *points; 141c58f1c22SToby Isaac PetscErrorCode ierr; 142c58f1c22SToby Isaac 143c58f1c22SToby Isaac PetscFunctionBegin; 144*ad8374ffSToby Isaac if (!label->validIS[v]) PetscFunctionReturn(0); 145*ad8374ffSToby Isaac if (label->points[v]) { 146*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 147*ad8374ffSToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) PetscHashIPut(label->ht[v], points[p], ret, iter); 148*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 149*ad8374ffSToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 150*ad8374ffSToby Isaac } 151*ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 152c58f1c22SToby Isaac PetscFunctionReturn(0); 153c58f1c22SToby Isaac } 154c58f1c22SToby Isaac 155c58f1c22SToby Isaac #undef __FUNCT__ 156c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetState" 157c58f1c22SToby Isaac PetscErrorCode DMLabelGetState(DMLabel label, PetscObjectState *state) 158c58f1c22SToby Isaac { 159c58f1c22SToby Isaac PetscFunctionBegin; 160c58f1c22SToby Isaac PetscValidPointer(state, 2); 161c58f1c22SToby Isaac *state = label->state; 162c58f1c22SToby Isaac PetscFunctionReturn(0); 163c58f1c22SToby Isaac } 164c58f1c22SToby Isaac 165c58f1c22SToby Isaac #undef __FUNCT__ 166c58f1c22SToby Isaac #define __FUNCT__ "DMLabelAddStratum" 167c58f1c22SToby Isaac PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 168c58f1c22SToby Isaac { 169*ad8374ffSToby Isaac PetscInt v, *tmpV, *tmpS; 170*ad8374ffSToby Isaac IS *tmpP; 171c58f1c22SToby Isaac PetscHashI *tmpH; 172c58f1c22SToby Isaac PetscBool *tmpB; 173c58f1c22SToby Isaac PetscErrorCode ierr; 174c58f1c22SToby Isaac 175c58f1c22SToby Isaac PetscFunctionBegin; 176c58f1c22SToby Isaac 177*ad8374ffSToby Isaac for (v = 0; v < label->numStrata; v++) { 178*ad8374ffSToby Isaac if (label->stratumValues[v] == value) PetscFunctionReturn(0); 179*ad8374ffSToby Isaac } 180c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpV);CHKERRQ(ierr); 181c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpS);CHKERRQ(ierr); 182c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpH);CHKERRQ(ierr); 183c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpP);CHKERRQ(ierr); 184c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpB);CHKERRQ(ierr); 185c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 186c58f1c22SToby Isaac tmpV[v] = label->stratumValues[v]; 187c58f1c22SToby Isaac tmpS[v] = label->stratumSizes[v]; 188c58f1c22SToby Isaac tmpH[v] = label->ht[v]; 189c58f1c22SToby Isaac tmpP[v] = label->points[v]; 190*ad8374ffSToby Isaac tmpB[v] = label->validIS[v]; 191c58f1c22SToby Isaac } 192c58f1c22SToby Isaac tmpV[v] = value; 193c58f1c22SToby Isaac tmpS[v] = 0; 194c58f1c22SToby Isaac PetscHashICreate(tmpH[v]); 195*ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_OWN_POINTER,&tmpP[v]);CHKERRQ(ierr); 196c58f1c22SToby Isaac tmpB[v] = PETSC_TRUE; 197c58f1c22SToby Isaac ++label->numStrata; 198c58f1c22SToby Isaac ierr = PetscFree(label->stratumValues);CHKERRQ(ierr); 199c58f1c22SToby Isaac ierr = PetscFree(label->stratumSizes);CHKERRQ(ierr); 200c58f1c22SToby Isaac ierr = PetscFree(label->ht);CHKERRQ(ierr); 201c58f1c22SToby Isaac ierr = PetscFree(label->points);CHKERRQ(ierr); 202*ad8374ffSToby Isaac ierr = PetscFree(label->validIS);CHKERRQ(ierr); 203c58f1c22SToby Isaac label->stratumValues = tmpV; 204c58f1c22SToby Isaac label->stratumSizes = tmpS; 205c58f1c22SToby Isaac label->ht = tmpH; 206c58f1c22SToby Isaac label->points = tmpP; 207*ad8374ffSToby Isaac label->validIS = tmpB; 208c58f1c22SToby Isaac 209c58f1c22SToby Isaac PetscFunctionReturn(0); 210c58f1c22SToby Isaac } 211c58f1c22SToby Isaac 212c58f1c22SToby Isaac #undef __FUNCT__ 213c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetName" 214c58f1c22SToby Isaac /*@C 215c58f1c22SToby Isaac DMLabelGetName - Return the name of a DMLabel object 216c58f1c22SToby Isaac 217c58f1c22SToby Isaac Input parameter: 218c58f1c22SToby Isaac . label - The DMLabel 219c58f1c22SToby Isaac 220c58f1c22SToby Isaac Output parameter: 221c58f1c22SToby Isaac . name - The label name 222c58f1c22SToby Isaac 223c58f1c22SToby Isaac Level: beginner 224c58f1c22SToby Isaac 225c58f1c22SToby Isaac .seealso: DMLabelCreate() 226c58f1c22SToby Isaac @*/ 227c58f1c22SToby Isaac PetscErrorCode DMLabelGetName(DMLabel label, const char **name) 228c58f1c22SToby Isaac { 229c58f1c22SToby Isaac PetscFunctionBegin; 230c58f1c22SToby Isaac PetscValidPointer(name, 2); 231c58f1c22SToby Isaac *name = label->name; 232c58f1c22SToby Isaac PetscFunctionReturn(0); 233c58f1c22SToby Isaac } 234c58f1c22SToby Isaac 235c58f1c22SToby Isaac #undef __FUNCT__ 236c58f1c22SToby Isaac #define __FUNCT__ "DMLabelView_Ascii" 237c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) 238c58f1c22SToby Isaac { 239c58f1c22SToby Isaac PetscInt v; 240c58f1c22SToby Isaac PetscMPIInt rank; 241c58f1c22SToby Isaac PetscErrorCode ierr; 242c58f1c22SToby Isaac 243c58f1c22SToby Isaac PetscFunctionBegin; 244c58f1c22SToby Isaac ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRQ(ierr); 245c58f1c22SToby Isaac ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 246c58f1c22SToby Isaac if (label) { 247c58f1c22SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Label '%s':\n", label->name);CHKERRQ(ierr); 248c58f1c22SToby Isaac if (label->bt) {ierr = PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%D, %D)\n", label->pStart, label->pEnd);CHKERRQ(ierr);} 249c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 250c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 251*ad8374ffSToby Isaac const PetscInt *points; 252c58f1c22SToby Isaac PetscInt p; 253c58f1c22SToby Isaac 254*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 255c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 256*ad8374ffSToby Isaac ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\n", rank, points[p], value);CHKERRQ(ierr); 257c58f1c22SToby Isaac } 258*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 259c58f1c22SToby Isaac } 260c58f1c22SToby Isaac } 261c58f1c22SToby Isaac ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 262c58f1c22SToby Isaac ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 263c58f1c22SToby Isaac PetscFunctionReturn(0); 264c58f1c22SToby Isaac } 265c58f1c22SToby Isaac 266c58f1c22SToby Isaac #undef __FUNCT__ 267c58f1c22SToby Isaac #define __FUNCT__ "DMLabelView" 268c58f1c22SToby Isaac /*@C 269c58f1c22SToby Isaac DMLabelView - View the label 270c58f1c22SToby Isaac 271c58f1c22SToby Isaac Input Parameters: 272c58f1c22SToby Isaac + label - The DMLabel 273c58f1c22SToby Isaac - viewer - The PetscViewer 274c58f1c22SToby Isaac 275c58f1c22SToby Isaac Level: intermediate 276c58f1c22SToby Isaac 277c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelDestroy() 278c58f1c22SToby Isaac @*/ 279c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 280c58f1c22SToby Isaac { 281c58f1c22SToby Isaac PetscBool iascii; 282c58f1c22SToby Isaac PetscErrorCode ierr; 283c58f1c22SToby Isaac 284c58f1c22SToby Isaac PetscFunctionBegin; 285c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 286c58f1c22SToby Isaac if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 287c58f1c22SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 288c58f1c22SToby Isaac if (iascii) { 289c58f1c22SToby Isaac ierr = DMLabelView_Ascii(label, viewer);CHKERRQ(ierr); 290c58f1c22SToby Isaac } 291c58f1c22SToby Isaac PetscFunctionReturn(0); 292c58f1c22SToby Isaac } 293c58f1c22SToby Isaac 294c58f1c22SToby Isaac #undef __FUNCT__ 295c58f1c22SToby Isaac #define __FUNCT__ "DMLabelDestroy" 296c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label) 297c58f1c22SToby Isaac { 298c58f1c22SToby Isaac PetscInt v; 299c58f1c22SToby Isaac PetscErrorCode ierr; 300c58f1c22SToby Isaac 301c58f1c22SToby Isaac PetscFunctionBegin; 302c58f1c22SToby Isaac if (!(*label)) PetscFunctionReturn(0); 303c58f1c22SToby Isaac if (--(*label)->refct > 0) PetscFunctionReturn(0); 304c58f1c22SToby Isaac ierr = PetscFree((*label)->name);CHKERRQ(ierr); 305c58f1c22SToby Isaac ierr = PetscFree((*label)->stratumValues);CHKERRQ(ierr); 306c58f1c22SToby Isaac ierr = PetscFree((*label)->stratumSizes);CHKERRQ(ierr); 307*ad8374ffSToby Isaac for (v = 0; v < (*label)->numStrata; ++v) {ierr = ISDestroy(&((*label)->points[v]));CHKERRQ(ierr);} 308c58f1c22SToby Isaac ierr = PetscFree((*label)->points);CHKERRQ(ierr); 309*ad8374ffSToby Isaac ierr = PetscFree((*label)->validIS);CHKERRQ(ierr); 310c58f1c22SToby Isaac if ((*label)->ht) { 311c58f1c22SToby Isaac for (v = 0; v < (*label)->numStrata; ++v) {PetscHashIDestroy((*label)->ht[v]);} 312c58f1c22SToby Isaac ierr = PetscFree((*label)->ht);CHKERRQ(ierr); 313c58f1c22SToby Isaac } 314c58f1c22SToby Isaac ierr = PetscBTDestroy(&(*label)->bt);CHKERRQ(ierr); 315c58f1c22SToby Isaac ierr = PetscFree(*label);CHKERRQ(ierr); 316c58f1c22SToby Isaac PetscFunctionReturn(0); 317c58f1c22SToby Isaac } 318c58f1c22SToby Isaac 319c58f1c22SToby Isaac #undef __FUNCT__ 320c58f1c22SToby Isaac #define __FUNCT__ "DMLabelDuplicate" 321c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 322c58f1c22SToby Isaac { 323*ad8374ffSToby Isaac PetscInt v; 324c58f1c22SToby Isaac PetscErrorCode ierr; 325c58f1c22SToby Isaac 326c58f1c22SToby Isaac PetscFunctionBegin; 327c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 328c58f1c22SToby Isaac ierr = PetscNew(labelnew);CHKERRQ(ierr); 329c58f1c22SToby Isaac ierr = PetscStrallocpy(label->name, &(*labelnew)->name);CHKERRQ(ierr); 330c58f1c22SToby Isaac 331c58f1c22SToby Isaac (*labelnew)->refct = 1; 332c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 3335aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 334c58f1c22SToby Isaac if (label->numStrata) { 335c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues);CHKERRQ(ierr); 336c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes);CHKERRQ(ierr); 337c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->ht);CHKERRQ(ierr); 338c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->points);CHKERRQ(ierr); 339*ad8374ffSToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->validIS);CHKERRQ(ierr); 340c58f1c22SToby Isaac /* Could eliminate unused space here */ 341c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 342c58f1c22SToby Isaac PetscHashICreate((*labelnew)->ht[v]); 343*ad8374ffSToby Isaac (*labelnew)->validIS[v] = PETSC_TRUE; 344c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 345c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 346*ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) (label->points[v]));CHKERRQ(ierr); 347*ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 348c58f1c22SToby Isaac } 349c58f1c22SToby Isaac } 350c58f1c22SToby Isaac (*labelnew)->pStart = -1; 351c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 352c58f1c22SToby Isaac (*labelnew)->bt = NULL; 353c58f1c22SToby Isaac PetscFunctionReturn(0); 354c58f1c22SToby Isaac } 355c58f1c22SToby Isaac 356c58f1c22SToby Isaac #undef __FUNCT__ 357c58f1c22SToby Isaac #define __FUNCT__ "DMLabelCreateIndex" 358c58f1c22SToby Isaac /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 359c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 360c58f1c22SToby Isaac { 361c58f1c22SToby Isaac PetscInt v; 362c58f1c22SToby Isaac PetscErrorCode ierr; 363c58f1c22SToby Isaac 364c58f1c22SToby Isaac PetscFunctionBegin; 365c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 366c58f1c22SToby Isaac if (label->bt) {ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);} 367c58f1c22SToby Isaac label->pStart = pStart; 368c58f1c22SToby Isaac label->pEnd = pEnd; 369c58f1c22SToby Isaac ierr = PetscBTCreate(pEnd - pStart, &label->bt);CHKERRQ(ierr); 370c58f1c22SToby Isaac ierr = PetscBTMemzero(pEnd - pStart, label->bt);CHKERRQ(ierr); 371c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 372*ad8374ffSToby Isaac const PetscInt *points; 373c58f1c22SToby Isaac PetscInt i; 374c58f1c22SToby Isaac 375*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 376c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 377*ad8374ffSToby Isaac const PetscInt point = points[i]; 378c58f1c22SToby Isaac 379c58f1c22SToby 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); 380c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - pStart);CHKERRQ(ierr); 381c58f1c22SToby Isaac } 382*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 383c58f1c22SToby Isaac } 384c58f1c22SToby Isaac PetscFunctionReturn(0); 385c58f1c22SToby Isaac } 386c58f1c22SToby Isaac 387c58f1c22SToby Isaac #undef __FUNCT__ 388c58f1c22SToby Isaac #define __FUNCT__ "DMLabelDestroyIndex" 389c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label) 390c58f1c22SToby Isaac { 391c58f1c22SToby Isaac PetscErrorCode ierr; 392c58f1c22SToby Isaac 393c58f1c22SToby Isaac PetscFunctionBegin; 394c58f1c22SToby Isaac label->pStart = -1; 395c58f1c22SToby Isaac label->pEnd = -1; 396c58f1c22SToby Isaac if (label->bt) {ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);} 397c58f1c22SToby Isaac PetscFunctionReturn(0); 398c58f1c22SToby Isaac } 399c58f1c22SToby Isaac 400c58f1c22SToby Isaac #undef __FUNCT__ 401c58f1c22SToby Isaac #define __FUNCT__ "DMLabelHasValue" 402c58f1c22SToby Isaac /*@ 403c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 404c58f1c22SToby Isaac 405c58f1c22SToby Isaac Input Parameters: 406c58f1c22SToby Isaac + label - the DMLabel 407c58f1c22SToby Isaac - value - the value 408c58f1c22SToby Isaac 409c58f1c22SToby Isaac Output Parameter: 410c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 411c58f1c22SToby Isaac 412c58f1c22SToby Isaac Level: developer 413c58f1c22SToby Isaac 414c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue() 415c58f1c22SToby Isaac @*/ 416c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 417c58f1c22SToby Isaac { 418c58f1c22SToby Isaac PetscInt v; 419c58f1c22SToby Isaac 420c58f1c22SToby Isaac PetscFunctionBegin; 421c58f1c22SToby Isaac PetscValidPointer(contains, 3); 422c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 423c58f1c22SToby Isaac if (value == label->stratumValues[v]) break; 424c58f1c22SToby Isaac } 425c58f1c22SToby Isaac *contains = (v < label->numStrata ? PETSC_TRUE : PETSC_FALSE); 426c58f1c22SToby Isaac PetscFunctionReturn(0); 427c58f1c22SToby Isaac } 428c58f1c22SToby Isaac 429c58f1c22SToby Isaac #undef __FUNCT__ 430c58f1c22SToby Isaac #define __FUNCT__ "DMLabelHasPoint" 431c58f1c22SToby Isaac /*@ 432c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 433c58f1c22SToby Isaac 434c58f1c22SToby Isaac Input Parameters: 435c58f1c22SToby Isaac + label - the DMLabel 436c58f1c22SToby Isaac - point - the point 437c58f1c22SToby Isaac 438c58f1c22SToby Isaac Output Parameter: 439c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 440c58f1c22SToby Isaac 441c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 442c58f1c22SToby Isaac 443c58f1c22SToby Isaac Level: developer 444c58f1c22SToby Isaac 445c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 446c58f1c22SToby Isaac @*/ 447c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 448c58f1c22SToby Isaac { 449c58f1c22SToby Isaac PetscErrorCode ierr; 450c58f1c22SToby Isaac 451c58f1c22SToby Isaac PetscFunctionBeginHot; 452c58f1c22SToby Isaac PetscValidPointer(contains, 3); 453c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 454c58f1c22SToby Isaac #if defined(PETSC_USE_DEBUG) 455c58f1c22SToby Isaac if (!label->bt) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 456c58f1c22SToby 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); 457c58f1c22SToby Isaac #endif 458c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 459c58f1c22SToby Isaac PetscFunctionReturn(0); 460c58f1c22SToby Isaac } 461c58f1c22SToby Isaac 462c58f1c22SToby Isaac #undef __FUNCT__ 463c58f1c22SToby Isaac #define __FUNCT__ "DMLabelStratumHasPoint" 464c58f1c22SToby Isaac /*@ 465c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 466c58f1c22SToby Isaac 467c58f1c22SToby Isaac Input Parameters: 468c58f1c22SToby Isaac + label - the DMLabel 469c58f1c22SToby Isaac . value - the stratum value 470c58f1c22SToby Isaac - point - the point 471c58f1c22SToby Isaac 472c58f1c22SToby Isaac Output Parameter: 473c58f1c22SToby Isaac . contains - true if the stratum contains the point 474c58f1c22SToby Isaac 475c58f1c22SToby Isaac Level: intermediate 476c58f1c22SToby Isaac 477c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue() 478c58f1c22SToby Isaac @*/ 479c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 480c58f1c22SToby Isaac { 481c58f1c22SToby Isaac PetscInt v; 482c58f1c22SToby Isaac PetscErrorCode ierr; 483c58f1c22SToby Isaac 484c58f1c22SToby Isaac PetscFunctionBegin; 485c58f1c22SToby Isaac PetscValidPointer(contains, 4); 486c58f1c22SToby Isaac *contains = PETSC_FALSE; 487c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 488c58f1c22SToby Isaac if (label->stratumValues[v] == value) { 489*ad8374ffSToby Isaac if (label->validIS[v]) { 490*ad8374ffSToby Isaac const PetscInt *points; 491c58f1c22SToby Isaac PetscInt i; 492c58f1c22SToby Isaac 493*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 494*ad8374ffSToby Isaac ierr = PetscFindInt(point, label->stratumSizes[v], points, &i);CHKERRQ(ierr); 495*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 496c58f1c22SToby Isaac if (i >= 0) { 497c58f1c22SToby Isaac *contains = PETSC_TRUE; 498c58f1c22SToby Isaac break; 499c58f1c22SToby Isaac } 500c58f1c22SToby Isaac } else { 501c58f1c22SToby Isaac PetscBool has; 502c58f1c22SToby Isaac 503c58f1c22SToby Isaac PetscHashIHasKey(label->ht[v], point, has); 504c58f1c22SToby Isaac if (has) { 505c58f1c22SToby Isaac *contains = PETSC_TRUE; 506c58f1c22SToby Isaac break; 507c58f1c22SToby Isaac } 508c58f1c22SToby Isaac } 509c58f1c22SToby Isaac } 510c58f1c22SToby Isaac } 511c58f1c22SToby Isaac PetscFunctionReturn(0); 512c58f1c22SToby Isaac } 513c58f1c22SToby Isaac 514c58f1c22SToby Isaac #undef __FUNCT__ 5155aa44df4SToby Isaac #define __FUNCT__ "DMLabelGetDefaultValue" 5165aa44df4SToby Isaac /* 5175aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 5185aa44df4SToby Isaac When a label is created, it is initialized to -1. 5195aa44df4SToby Isaac 5205aa44df4SToby Isaac Input parameter: 5215aa44df4SToby Isaac . label - a DMLabel object 5225aa44df4SToby Isaac 5235aa44df4SToby Isaac Output parameter: 5245aa44df4SToby Isaac . defaultValue - the default value 5255aa44df4SToby Isaac 5265aa44df4SToby Isaac Level: beginner 5275aa44df4SToby Isaac 5285aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 5295aa44df4SToby Isaac */ 5305aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 5315aa44df4SToby Isaac { 5325aa44df4SToby Isaac PetscFunctionBegin; 5335aa44df4SToby Isaac *defaultValue = label->defaultValue; 5345aa44df4SToby Isaac PetscFunctionReturn(0); 5355aa44df4SToby Isaac } 5365aa44df4SToby Isaac 5375aa44df4SToby Isaac #undef __FUNCT__ 5385aa44df4SToby Isaac #define __FUNCT__ "DMLabelSetDefaultValue" 5395aa44df4SToby Isaac /* 5405aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 5415aa44df4SToby Isaac When a label is created, it is initialized to -1. 5425aa44df4SToby Isaac 5435aa44df4SToby Isaac Input parameter: 5445aa44df4SToby Isaac . label - a DMLabel object 5455aa44df4SToby Isaac 5465aa44df4SToby Isaac Output parameter: 5475aa44df4SToby Isaac . defaultValue - the default value 5485aa44df4SToby Isaac 5495aa44df4SToby Isaac Level: beginner 5505aa44df4SToby Isaac 5515aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 5525aa44df4SToby Isaac */ 5535aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 5545aa44df4SToby Isaac { 5555aa44df4SToby Isaac PetscFunctionBegin; 5565aa44df4SToby Isaac label->defaultValue = defaultValue; 5575aa44df4SToby Isaac PetscFunctionReturn(0); 5585aa44df4SToby Isaac } 5595aa44df4SToby Isaac 5605aa44df4SToby Isaac #undef __FUNCT__ 561c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetValue" 562c58f1c22SToby Isaac /*@ 5635aa44df4SToby 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()) 564c58f1c22SToby Isaac 565c58f1c22SToby Isaac Input Parameters: 566c58f1c22SToby Isaac + label - the DMLabel 567c58f1c22SToby Isaac - point - the point 568c58f1c22SToby Isaac 569c58f1c22SToby Isaac Output Parameter: 570c58f1c22SToby Isaac . value - The point value, or -1 571c58f1c22SToby Isaac 572c58f1c22SToby Isaac Level: intermediate 573c58f1c22SToby Isaac 5745aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 575c58f1c22SToby Isaac @*/ 576c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 577c58f1c22SToby Isaac { 578c58f1c22SToby Isaac PetscInt v; 579c58f1c22SToby Isaac PetscErrorCode ierr; 580c58f1c22SToby Isaac 581c58f1c22SToby Isaac PetscFunctionBegin; 582c58f1c22SToby Isaac PetscValidPointer(value, 3); 5835aa44df4SToby Isaac *value = label->defaultValue; 584c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 585*ad8374ffSToby Isaac if (label->validIS[v]) { 586*ad8374ffSToby Isaac const PetscInt *points; 587c58f1c22SToby Isaac PetscInt i; 588c58f1c22SToby Isaac 589*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 590*ad8374ffSToby Isaac ierr = PetscFindInt(point, label->stratumSizes[v], points, &i);CHKERRQ(ierr); 591*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 592c58f1c22SToby Isaac if (i >= 0) { 593c58f1c22SToby Isaac *value = label->stratumValues[v]; 594c58f1c22SToby Isaac break; 595c58f1c22SToby Isaac } 596c58f1c22SToby Isaac } else { 597c58f1c22SToby Isaac PetscBool has; 598c58f1c22SToby Isaac 599c58f1c22SToby Isaac PetscHashIHasKey(label->ht[v], point, has); 600c58f1c22SToby Isaac if (has) { 601c58f1c22SToby Isaac *value = label->stratumValues[v]; 602c58f1c22SToby Isaac break; 603c58f1c22SToby Isaac } 604c58f1c22SToby Isaac } 605c58f1c22SToby Isaac } 606c58f1c22SToby Isaac PetscFunctionReturn(0); 607c58f1c22SToby Isaac } 608c58f1c22SToby Isaac 609c58f1c22SToby Isaac #undef __FUNCT__ 610c58f1c22SToby Isaac #define __FUNCT__ "DMLabelSetValue" 611c58f1c22SToby Isaac /*@ 6125aa44df4SToby Isaac 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 somethingg different), then this function will do nothing. 613c58f1c22SToby Isaac 614c58f1c22SToby Isaac Input Parameters: 615c58f1c22SToby Isaac + label - the DMLabel 616c58f1c22SToby Isaac . point - the point 617c58f1c22SToby Isaac - value - The point value 618c58f1c22SToby Isaac 619c58f1c22SToby Isaac Level: intermediate 620c58f1c22SToby Isaac 6215aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 622c58f1c22SToby Isaac @*/ 623c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 624c58f1c22SToby Isaac { 625c58f1c22SToby Isaac PETSC_UNUSED PetscHashIIter iter, ret; 626c58f1c22SToby Isaac PetscInt v; 627c58f1c22SToby Isaac PetscErrorCode ierr; 628c58f1c22SToby Isaac 629c58f1c22SToby Isaac PetscFunctionBegin; 630c58f1c22SToby Isaac /* Find, or add, label value */ 6315aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 632c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 633c58f1c22SToby Isaac if (label->stratumValues[v] == value) break; 634c58f1c22SToby Isaac } 635c58f1c22SToby Isaac /* Create new table */ 636c58f1c22SToby Isaac if (v >= label->numStrata) {ierr = DMLabelAddStratum(label, value);CHKERRQ(ierr);} 637c58f1c22SToby Isaac ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 638c58f1c22SToby Isaac /* Set key */ 639c58f1c22SToby Isaac PetscHashIPut(label->ht[v], point, ret, iter); 640c58f1c22SToby Isaac PetscFunctionReturn(0); 641c58f1c22SToby Isaac } 642c58f1c22SToby Isaac 643c58f1c22SToby Isaac #undef __FUNCT__ 644c58f1c22SToby Isaac #define __FUNCT__ "DMLabelClearValue" 645c58f1c22SToby Isaac /*@ 646c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 647c58f1c22SToby Isaac 648c58f1c22SToby Isaac Input Parameters: 649c58f1c22SToby Isaac + label - the DMLabel 650c58f1c22SToby Isaac . point - the point 651c58f1c22SToby Isaac - value - The point value 652c58f1c22SToby Isaac 653c58f1c22SToby Isaac Level: intermediate 654c58f1c22SToby Isaac 655c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue() 656c58f1c22SToby Isaac @*/ 657c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 658c58f1c22SToby Isaac { 659*ad8374ffSToby Isaac PetscInt v; 660c58f1c22SToby Isaac PetscErrorCode ierr; 661c58f1c22SToby Isaac 662c58f1c22SToby Isaac PetscFunctionBegin; 663c58f1c22SToby Isaac /* Find label value */ 664c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 665c58f1c22SToby Isaac if (label->stratumValues[v] == value) break; 666c58f1c22SToby Isaac } 667c58f1c22SToby Isaac if (v >= label->numStrata) PetscFunctionReturn(0); 668*ad8374ffSToby Isaac if (label->validIS[v]) {ierr = DMLabelMakeInvalid_Private(label,v);CHKERRQ(ierr);} 669c58f1c22SToby Isaac ierr = PetscHashIDelKey(label->ht[v], point);CHKERRQ(ierr); 670c58f1c22SToby Isaac PetscFunctionReturn(0); 671c58f1c22SToby Isaac } 672c58f1c22SToby Isaac 673c58f1c22SToby Isaac #undef __FUNCT__ 674c58f1c22SToby Isaac #define __FUNCT__ "DMLabelInsertIS" 675c58f1c22SToby Isaac /*@ 676c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 677c58f1c22SToby Isaac 678c58f1c22SToby Isaac Input Parameters: 679c58f1c22SToby Isaac + label - the DMLabel 680c58f1c22SToby Isaac . is - the point IS 681c58f1c22SToby Isaac - value - The point value 682c58f1c22SToby Isaac 683c58f1c22SToby Isaac Level: intermediate 684c58f1c22SToby Isaac 685c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 686c58f1c22SToby Isaac @*/ 687c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 688c58f1c22SToby Isaac { 689c58f1c22SToby Isaac const PetscInt *points; 690c58f1c22SToby Isaac PetscInt n, p; 691c58f1c22SToby Isaac PetscErrorCode ierr; 692c58f1c22SToby Isaac 693c58f1c22SToby Isaac PetscFunctionBegin; 694c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 695c58f1c22SToby Isaac ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 696c58f1c22SToby Isaac ierr = ISGetIndices(is, &points);CHKERRQ(ierr); 697c58f1c22SToby Isaac for (p = 0; p < n; ++p) {ierr = DMLabelSetValue(label, points[p], value);CHKERRQ(ierr);} 698c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &points);CHKERRQ(ierr); 699c58f1c22SToby Isaac PetscFunctionReturn(0); 700c58f1c22SToby Isaac } 701c58f1c22SToby Isaac 702c58f1c22SToby Isaac #undef __FUNCT__ 703c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetNumValues" 704c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 705c58f1c22SToby Isaac { 706c58f1c22SToby Isaac PetscFunctionBegin; 707c58f1c22SToby Isaac PetscValidPointer(numValues, 2); 708c58f1c22SToby Isaac *numValues = label->numStrata; 709c58f1c22SToby Isaac PetscFunctionReturn(0); 710c58f1c22SToby Isaac } 711c58f1c22SToby Isaac 712c58f1c22SToby Isaac #undef __FUNCT__ 713c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetValueIS" 714c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 715c58f1c22SToby Isaac { 716c58f1c22SToby Isaac PetscErrorCode ierr; 717c58f1c22SToby Isaac 718c58f1c22SToby Isaac PetscFunctionBegin; 719c58f1c22SToby Isaac PetscValidPointer(values, 2); 720c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr); 721c58f1c22SToby Isaac PetscFunctionReturn(0); 722c58f1c22SToby Isaac } 723c58f1c22SToby Isaac 724c58f1c22SToby Isaac #undef __FUNCT__ 725fada774cSMatthew G. Knepley #define __FUNCT__ "DMLabelHasStratum" 726fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 727fada774cSMatthew G. Knepley { 728fada774cSMatthew G. Knepley PetscInt v; 729fada774cSMatthew G. Knepley 730fada774cSMatthew G. Knepley PetscFunctionBegin; 731fada774cSMatthew G. Knepley PetscValidPointer(exists, 3); 732fada774cSMatthew G. Knepley *exists = PETSC_FALSE; 733fada774cSMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 734fada774cSMatthew G. Knepley if (label->stratumValues[v] == value) { 735fada774cSMatthew G. Knepley *exists = PETSC_TRUE; 736fada774cSMatthew G. Knepley break; 737fada774cSMatthew G. Knepley } 738fada774cSMatthew G. Knepley } 739fada774cSMatthew G. Knepley PetscFunctionReturn(0); 740fada774cSMatthew G. Knepley } 741fada774cSMatthew G. Knepley 742fada774cSMatthew G. Knepley #undef __FUNCT__ 743c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetStratumSize" 744c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 745c58f1c22SToby Isaac { 746c58f1c22SToby Isaac PetscInt v; 747c58f1c22SToby Isaac PetscErrorCode ierr; 748c58f1c22SToby Isaac 749c58f1c22SToby Isaac PetscFunctionBegin; 750c58f1c22SToby Isaac PetscValidPointer(size, 3); 751c58f1c22SToby Isaac *size = 0; 752c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 753c58f1c22SToby Isaac if (label->stratumValues[v] == value) { 754c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 755c58f1c22SToby Isaac *size = label->stratumSizes[v]; 756c58f1c22SToby Isaac break; 757c58f1c22SToby Isaac } 758c58f1c22SToby Isaac } 759c58f1c22SToby Isaac PetscFunctionReturn(0); 760c58f1c22SToby Isaac } 761c58f1c22SToby Isaac 762c58f1c22SToby Isaac #undef __FUNCT__ 763c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetStratumBounds" 764c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 765c58f1c22SToby Isaac { 766c58f1c22SToby Isaac PetscInt v; 767c58f1c22SToby Isaac PetscErrorCode ierr; 768c58f1c22SToby Isaac 769c58f1c22SToby Isaac PetscFunctionBegin; 770c58f1c22SToby Isaac if (start) {PetscValidPointer(start, 3); *start = 0;} 771c58f1c22SToby Isaac if (end) {PetscValidPointer(end, 4); *end = 0;} 772c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 773*ad8374ffSToby Isaac const PetscInt *points; 774*ad8374ffSToby Isaac 775c58f1c22SToby Isaac if (label->stratumValues[v] != value) continue; 776c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 777c58f1c22SToby Isaac if (label->stratumSizes[v] <= 0) break; 778*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 779*ad8374ffSToby Isaac if (start) *start = points[0]; 780*ad8374ffSToby Isaac if (end) *end = points[label->stratumSizes[v]-1]+1; 781*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 782c58f1c22SToby Isaac break; 783c58f1c22SToby Isaac } 784c58f1c22SToby Isaac PetscFunctionReturn(0); 785c58f1c22SToby Isaac } 786c58f1c22SToby Isaac 787c58f1c22SToby Isaac #undef __FUNCT__ 788c58f1c22SToby Isaac #define __FUNCT__ "DMLabelGetStratumIS" 789c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 790c58f1c22SToby Isaac { 791c58f1c22SToby Isaac PetscInt v; 792c58f1c22SToby Isaac PetscErrorCode ierr; 793c58f1c22SToby Isaac 794c58f1c22SToby Isaac PetscFunctionBegin; 795c58f1c22SToby Isaac PetscValidPointer(points, 3); 796c58f1c22SToby Isaac *points = NULL; 797c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 798c58f1c22SToby Isaac if (label->stratumValues[v] == value) { 799c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 800*ad8374ffSToby Isaac if (label->validIS[v]) { 801*ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) label->points[v]);CHKERRQ(ierr); 802*ad8374ffSToby Isaac *points = label->points[v]; 803c58f1c22SToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Need to implement this to speedup Stratify"); 804c58f1c22SToby Isaac break; 805c58f1c22SToby Isaac } 806c58f1c22SToby Isaac } 807c58f1c22SToby Isaac PetscFunctionReturn(0); 808c58f1c22SToby Isaac } 809c58f1c22SToby Isaac 810c58f1c22SToby Isaac #undef __FUNCT__ 811c58f1c22SToby Isaac #define __FUNCT__ "DMLabelClearStratum" 812c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 813c58f1c22SToby Isaac { 814c58f1c22SToby Isaac PetscInt v; 815c58f1c22SToby Isaac PetscErrorCode ierr; 816c58f1c22SToby Isaac 817c58f1c22SToby Isaac PetscFunctionBegin; 818c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 819c58f1c22SToby Isaac if (label->stratumValues[v] == value) break; 820c58f1c22SToby Isaac } 821c58f1c22SToby Isaac if (v >= label->numStrata) PetscFunctionReturn(0); 822*ad8374ffSToby Isaac if (label->bt && label->validIS[v]) { 823c58f1c22SToby Isaac PetscInt i; 824*ad8374ffSToby Isaac const PetscInt *points; 825c58f1c22SToby Isaac 826*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 827c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 828*ad8374ffSToby Isaac const PetscInt point = points[i]; 829c58f1c22SToby Isaac 830c58f1c22SToby 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); 831c58f1c22SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 832c58f1c22SToby Isaac } 833*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 834c58f1c22SToby Isaac } 835*ad8374ffSToby Isaac if (label->validIS[v]) { 836*ad8374ffSToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 837c58f1c22SToby Isaac label->stratumSizes[v] = 0; 838*ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,0,NULL,PETSC_OWN_POINTER,&(label->points[v]));CHKERRQ(ierr); 839*ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) (label->points[v]), "indices");CHKERRQ(ierr); 840c58f1c22SToby Isaac } else { 841c58f1c22SToby Isaac PetscHashIClear(label->ht[v]); 842c58f1c22SToby Isaac } 843c58f1c22SToby Isaac PetscFunctionReturn(0); 844c58f1c22SToby Isaac } 845c58f1c22SToby Isaac 846c58f1c22SToby Isaac #undef __FUNCT__ 847c58f1c22SToby Isaac #define __FUNCT__ "DMLabelFilter" 848c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 849c58f1c22SToby Isaac { 850c58f1c22SToby Isaac PetscInt v; 851c58f1c22SToby Isaac PetscErrorCode ierr; 852c58f1c22SToby Isaac 853c58f1c22SToby Isaac PetscFunctionBegin; 854c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 855c58f1c22SToby Isaac label->pStart = start; 856c58f1c22SToby Isaac label->pEnd = end; 857c58f1c22SToby Isaac if (label->bt) {ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);} 858c58f1c22SToby Isaac /* Could squish offsets, but would only make sense if I reallocate the storage */ 859c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 860c58f1c22SToby Isaac PetscInt off, q; 861*ad8374ffSToby Isaac const PetscInt *points; 862*ad8374ffSToby Isaac PetscInt *pointsNew = NULL; 863c58f1c22SToby Isaac 864*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 865c58f1c22SToby Isaac for (off = 0, q = 0; q < label->stratumSizes[v]; ++q) { 866*ad8374ffSToby Isaac const PetscInt point = points[q]; 867c58f1c22SToby Isaac 868*ad8374ffSToby Isaac if ((point < start) || (point >= end)) { 869*ad8374ffSToby Isaac if (!pointsNew) { 870*ad8374ffSToby Isaac ierr = PetscMalloc1(label->stratumSizes[v],&pointsNew);CHKERRQ(ierr); 871*ad8374ffSToby Isaac ierr = PetscMemcpy(pointsNew,points,(size_t) off * sizeof(PetscInt));CHKERRQ(ierr); 872*ad8374ffSToby Isaac } 873*ad8374ffSToby Isaac continue; 874*ad8374ffSToby Isaac } 875*ad8374ffSToby Isaac if (pointsNew) { 876*ad8374ffSToby Isaac pointsNew[off++] = point; 877*ad8374ffSToby Isaac } 878*ad8374ffSToby Isaac } 879*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 880*ad8374ffSToby Isaac if (pointsNew) { 881*ad8374ffSToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 882*ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,off,pointsNew,PETSC_OWN_POINTER,&(label->points[v]));CHKERRQ(ierr); 883*ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) (label->points[v]), "indices");CHKERRQ(ierr); 884c58f1c22SToby Isaac } 885c58f1c22SToby Isaac label->stratumSizes[v] = off; 886c58f1c22SToby Isaac } 887c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, start, end);CHKERRQ(ierr); 888c58f1c22SToby Isaac PetscFunctionReturn(0); 889c58f1c22SToby Isaac } 890c58f1c22SToby Isaac 891c58f1c22SToby Isaac #undef __FUNCT__ 892c58f1c22SToby Isaac #define __FUNCT__ "DMLabelPermute" 893c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 894c58f1c22SToby Isaac { 895c58f1c22SToby Isaac const PetscInt *perm; 896c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 897c58f1c22SToby Isaac PetscErrorCode ierr; 898c58f1c22SToby Isaac 899c58f1c22SToby Isaac PetscFunctionBegin; 900c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 901c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, labelNew);CHKERRQ(ierr); 902c58f1c22SToby Isaac ierr = DMLabelGetNumValues(*labelNew, &numValues);CHKERRQ(ierr); 903c58f1c22SToby Isaac ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr); 904c58f1c22SToby Isaac ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr); 905c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 906c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 907*ad8374ffSToby Isaac const PetscInt *points; 908*ad8374ffSToby Isaac PetscInt *pointsNew; 909c58f1c22SToby Isaac 910*ad8374ffSToby Isaac ierr = ISGetIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 911*ad8374ffSToby Isaac ierr = PetscMalloc1(size,&pointsNew);CHKERRQ(ierr); 912c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 913*ad8374ffSToby Isaac const PetscInt point = points[q]; 914c58f1c22SToby Isaac 915c58f1c22SToby 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); 916*ad8374ffSToby Isaac pointsNew[q] = perm[point]; 917c58f1c22SToby Isaac } 918*ad8374ffSToby Isaac ierr = ISRestoreIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 919*ad8374ffSToby Isaac ierr = PetscSortInt(size, pointsNew);CHKERRQ(ierr); 920*ad8374ffSToby Isaac ierr = ISDestroy(&((*labelNew)->points[v]));CHKERRQ(ierr); 921*ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]));CHKERRQ(ierr); 922*ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices");CHKERRQ(ierr); 923c58f1c22SToby Isaac } 924c58f1c22SToby Isaac ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr); 925c58f1c22SToby Isaac if (label->bt) { 926c58f1c22SToby Isaac ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 927c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 928c58f1c22SToby Isaac } 929c58f1c22SToby Isaac PetscFunctionReturn(0); 930c58f1c22SToby Isaac } 931c58f1c22SToby Isaac 932c58f1c22SToby Isaac #undef __FUNCT__ 93326c55118SMichael Lange #define __FUNCT__ "DMLabelDistribute_Internal" 93426c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 93526c55118SMichael Lange { 93626c55118SMichael Lange MPI_Comm comm; 93726c55118SMichael Lange PetscInt s, l, nroots, nleaves, dof, offset, size; 93826c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 93926c55118SMichael Lange PetscSection rootSection; 94026c55118SMichael Lange PetscSF labelSF; 94126c55118SMichael Lange PetscErrorCode ierr; 94226c55118SMichael Lange 94326c55118SMichael Lange PetscFunctionBegin; 94426c55118SMichael Lange if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 94526c55118SMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 94626c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 94726c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 94826c55118SMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL);CHKERRQ(ierr); 94926c55118SMichael Lange ierr = PetscSectionCreate(comm, &rootSection);CHKERRQ(ierr); 95026c55118SMichael Lange ierr = PetscSectionSetChart(rootSection, 0, nroots);CHKERRQ(ierr); 95126c55118SMichael Lange if (label) { 95226c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 953*ad8374ffSToby Isaac const PetscInt *points; 954*ad8374ffSToby Isaac 955*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 95626c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 957*ad8374ffSToby Isaac ierr = PetscSectionGetDof(rootSection, points[l], &dof);CHKERRQ(ierr); 958*ad8374ffSToby Isaac ierr = PetscSectionSetDof(rootSection, points[l], dof+1);CHKERRQ(ierr); 95926c55118SMichael Lange } 960*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 96126c55118SMichael Lange } 96226c55118SMichael Lange } 96326c55118SMichael Lange ierr = PetscSectionSetUp(rootSection);CHKERRQ(ierr); 96426c55118SMichael Lange /* Create a point-wise array of stratum values */ 96526c55118SMichael Lange ierr = PetscSectionGetStorageSize(rootSection, &size);CHKERRQ(ierr); 96626c55118SMichael Lange ierr = PetscMalloc1(size, &rootStrata);CHKERRQ(ierr); 96726c55118SMichael Lange ierr = PetscCalloc1(nroots, &rootIdx);CHKERRQ(ierr); 96826c55118SMichael Lange if (label) { 96926c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 970*ad8374ffSToby Isaac const PetscInt *points; 971*ad8374ffSToby Isaac 972*ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 97326c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 974*ad8374ffSToby Isaac const PetscInt p = points[l]; 97526c55118SMichael Lange ierr = PetscSectionGetOffset(rootSection, p, &offset);CHKERRQ(ierr); 97626c55118SMichael Lange rootStrata[offset+rootIdx[p]++] = label->stratumValues[s]; 97726c55118SMichael Lange } 978*ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 97926c55118SMichael Lange } 98026c55118SMichael Lange } 98126c55118SMichael Lange /* Build SF that maps label points to remote processes */ 98226c55118SMichael Lange ierr = PetscSectionCreate(comm, leafSection);CHKERRQ(ierr); 98326c55118SMichael Lange ierr = PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection);CHKERRQ(ierr); 98426c55118SMichael Lange ierr = PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF);CHKERRQ(ierr); 98526c55118SMichael Lange ierr = PetscFree(remoteOffsets);CHKERRQ(ierr); 98626c55118SMichael Lange /* Send the strata for each point over the derived SF */ 98726c55118SMichael Lange ierr = PetscSectionGetStorageSize(*leafSection, &size);CHKERRQ(ierr); 98826c55118SMichael Lange ierr = PetscMalloc1(size, leafStrata);CHKERRQ(ierr); 98926c55118SMichael Lange ierr = PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr); 99026c55118SMichael Lange ierr = PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr); 99126c55118SMichael Lange /* Clean up */ 99226c55118SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 99326c55118SMichael Lange ierr = PetscFree(rootIdx);CHKERRQ(ierr); 99426c55118SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 99526c55118SMichael Lange ierr = PetscSFDestroy(&labelSF);CHKERRQ(ierr); 99626c55118SMichael Lange PetscFunctionReturn(0); 99726c55118SMichael Lange } 99826c55118SMichael Lange 99926c55118SMichael Lange #undef __FUNCT__ 1000c58f1c22SToby Isaac #define __FUNCT__ "DMLabelDistribute" 1001c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1002c58f1c22SToby Isaac { 1003c58f1c22SToby Isaac MPI_Comm comm; 100426c55118SMichael Lange PetscSection leafSection; 100526c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 100626c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1007*ad8374ffSToby Isaac PetscInt **points; 1008c58f1c22SToby Isaac char *name; 1009c58f1c22SToby Isaac PetscInt nameSize; 10105cbdf6fcSMichael Lange PetscHashI stratumHash; 10115cbdf6fcSMichael Lange PETSC_UNUSED PetscHashIIter ret, iter; 1012c58f1c22SToby Isaac size_t len = 0; 101326c55118SMichael Lange PetscMPIInt rank; 1014c58f1c22SToby Isaac PetscErrorCode ierr; 1015c58f1c22SToby Isaac 1016c58f1c22SToby Isaac PetscFunctionBegin; 1017c58f1c22SToby Isaac if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 1018c58f1c22SToby Isaac ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 1019c58f1c22SToby Isaac ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1020c58f1c22SToby Isaac /* Bcast name */ 1021c58f1c22SToby Isaac if (!rank) {ierr = PetscStrlen(label->name, &len);CHKERRQ(ierr);} 1022c58f1c22SToby Isaac nameSize = len; 1023c58f1c22SToby Isaac ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1024c58f1c22SToby Isaac ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1025c58f1c22SToby Isaac if (!rank) {ierr = PetscMemcpy(name, label->name, nameSize+1);CHKERRQ(ierr);} 1026c58f1c22SToby Isaac ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 1027c58f1c22SToby Isaac ierr = DMLabelCreate(name, labelNew);CHKERRQ(ierr); 1028c58f1c22SToby Isaac ierr = PetscFree(name);CHKERRQ(ierr); 102977d236dfSMichael Lange /* Bcast defaultValue */ 103077d236dfSMichael Lange if (!rank) (*labelNew)->defaultValue = label->defaultValue; 103177d236dfSMichael Lange ierr = MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 103226c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 103326c55118SMichael Lange ierr = DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata);CHKERRQ(ierr); 10345cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 10355cbdf6fcSMichael Lange PetscHashICreate(stratumHash); 103626c55118SMichael Lange ierr = PetscSectionGetStorageSize(leafSection, &size);CHKERRQ(ierr); 10375cbdf6fcSMichael Lange for (p = 0; p < size; ++p) PetscHashIPut(stratumHash, leafStrata[p], ret, iter); 10385cbdf6fcSMichael Lange PetscHashISize(stratumHash, (*labelNew)->numStrata); 1039*ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS);CHKERRQ(ierr); 1040*ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 10415cbdf6fcSMichael Lange ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues);CHKERRQ(ierr); 10425cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 10435cbdf6fcSMichael Lange offset = 0; 10445cbdf6fcSMichael Lange ierr = PetscHashIGetKeys(stratumHash, &offset, (*labelNew)->stratumValues);CHKERRQ(ierr); 10455cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1046231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 1047231b9e6fSMatthew G. Knepley if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;} 10485cbdf6fcSMichael Lange } 10495cbdf6fcSMichael Lange } 1050c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 1051c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes);CHKERRQ(ierr); 1052c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1053c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1054c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1055c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1056c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1057c58f1c22SToby Isaac (*labelNew)->stratumSizes[leafStrata[offset+s]]++; 1058c58f1c22SToby Isaac } 1059c58f1c22SToby Isaac } 1060c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht);CHKERRQ(ierr); 1061c58f1c22SToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points);CHKERRQ(ierr); 1062*ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&points);CHKERRQ(ierr); 1063c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 1064c58f1c22SToby Isaac PetscHashICreate((*labelNew)->ht[s]); 1065*ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]));CHKERRQ(ierr); 1066c58f1c22SToby Isaac } 1067c58f1c22SToby Isaac /* Insert points into new strata */ 1068c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata, &strataIdx);CHKERRQ(ierr); 1069c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1070c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1071c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1072c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1073c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1074c58f1c22SToby Isaac stratum = leafStrata[offset+s]; 1075*ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1076c58f1c22SToby Isaac } 1077c58f1c22SToby Isaac } 1078*ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1079*ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]));CHKERRQ(ierr); 1080*ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices");CHKERRQ(ierr); 1081*ad8374ffSToby Isaac } 1082*ad8374ffSToby Isaac ierr = PetscFree(points);CHKERRQ(ierr); 10835cbdf6fcSMichael Lange PetscHashIDestroy(stratumHash); 1084c58f1c22SToby Isaac ierr = PetscFree(leafStrata);CHKERRQ(ierr); 1085c58f1c22SToby Isaac ierr = PetscFree(strataIdx);CHKERRQ(ierr); 1086c58f1c22SToby Isaac ierr = PetscSectionDestroy(&leafSection);CHKERRQ(ierr); 1087c58f1c22SToby Isaac PetscFunctionReturn(0); 1088c58f1c22SToby Isaac } 1089c58f1c22SToby Isaac 1090c58f1c22SToby Isaac #undef __FUNCT__ 10917937d9ceSMichael Lange #define __FUNCT__ "DMLabelGather" 10927937d9ceSMichael Lange /*@ 10937937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 10947937d9ceSMichael Lange 10957937d9ceSMichael Lange Input Parameters: 10967937d9ceSMichael Lange + label - the DMLabel 10977937d9ceSMichael Lange . point - the Star Forest point communication map 10987937d9ceSMichael Lange 10997937d9ceSMichael Lange Input Parameters: 11007937d9ceSMichael Lange + label - the new DMLabel with localised leaf values 11017937d9ceSMichael Lange 11027937d9ceSMichael Lange Level: developer 11037937d9ceSMichael Lange 11047937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 11057937d9ceSMichael Lange 11067937d9ceSMichael Lange .seealso: DMLabelDistribute() 11077937d9ceSMichael Lange @*/ 11087937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 11097937d9ceSMichael Lange { 11107937d9ceSMichael Lange MPI_Comm comm; 11117937d9ceSMichael Lange PetscSection rootSection; 11127937d9ceSMichael Lange PetscSF sfLabel; 11137937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 11147937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 11157937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 11167937d9ceSMichael Lange PetscInt *rootStrata; 11177937d9ceSMichael Lange char *name; 11187937d9ceSMichael Lange PetscInt nameSize; 11197937d9ceSMichael Lange size_t len = 0; 11207937d9ceSMichael Lange PetscMPIInt rank, numProcs; 11217937d9ceSMichael Lange PetscErrorCode ierr; 11227937d9ceSMichael Lange 11237937d9ceSMichael Lange PetscFunctionBegin; 11247937d9ceSMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 11257937d9ceSMichael Lange ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 11267937d9ceSMichael Lange ierr = MPI_Comm_size(comm, &numProcs);CHKERRQ(ierr); 11277937d9ceSMichael Lange /* Bcast name */ 11287937d9ceSMichael Lange if (!rank) {ierr = PetscStrlen(label->name, &len);CHKERRQ(ierr);} 11297937d9ceSMichael Lange nameSize = len; 11307937d9ceSMichael Lange ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 11317937d9ceSMichael Lange ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 11327937d9ceSMichael Lange if (!rank) {ierr = PetscMemcpy(name, label->name, nameSize+1);CHKERRQ(ierr);} 11337937d9ceSMichael Lange ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 11347937d9ceSMichael Lange ierr = DMLabelCreate(name, labelNew);CHKERRQ(ierr); 11357937d9ceSMichael Lange ierr = PetscFree(name);CHKERRQ(ierr); 11367937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 11377937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 11387937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 11397937d9ceSMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL);CHKERRQ(ierr); 1140dc53bc9bSMatthew G. Knepley ierr = PetscMalloc1(nroots, &leafPoints);CHKERRQ(ierr); 1141dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 11427937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 1143dc53bc9bSMatthew G. Knepley leafPoints[ilocal[p]].index = ilocal[p]; 1144dc53bc9bSMatthew G. Knepley leafPoints[ilocal[p]].rank = rank; 11457937d9ceSMichael Lange } 11467937d9ceSMichael Lange ierr = PetscSFComputeDegreeBegin(sf, &rootDegree);CHKERRQ(ierr); 11477937d9ceSMichael Lange ierr = PetscSFComputeDegreeEnd(sf, &rootDegree);CHKERRQ(ierr); 11487937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 11497937d9ceSMichael Lange ierr = PetscMalloc1(nmultiroots, &rootPoints);CHKERRQ(ierr); 11507937d9ceSMichael Lange ierr = PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 11517937d9ceSMichael Lange ierr = PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 11527937d9ceSMichael Lange ierr = PetscSFCreate(comm,& sfLabel);CHKERRQ(ierr); 11537937d9ceSMichael Lange ierr = PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 11547937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 11557937d9ceSMichael Lange ierr = DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata);CHKERRQ(ierr); 11567937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 11577937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 11587937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 11597937d9ceSMichael Lange ierr = PetscSectionGetDof(rootSection, idx+d, &dof);CHKERRQ(ierr); 11607937d9ceSMichael Lange ierr = PetscSectionGetOffset(rootSection, idx+d, &offset);CHKERRQ(ierr); 11617937d9ceSMichael Lange for (s = 0; s < dof; s++) {ierr = DMLabelSetValue(*labelNew, p, rootStrata[offset+s]);CHKERRQ(ierr);} 11627937d9ceSMichael Lange } 11637937d9ceSMichael Lange idx += rootDegree[p]; 11647937d9ceSMichael Lange } 116577e0c0e7SMichael Lange ierr = PetscFree(leafPoints);CHKERRQ(ierr); 116677e0c0e7SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 116777e0c0e7SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 116877e0c0e7SMichael Lange ierr = PetscSFDestroy(&sfLabel);CHKERRQ(ierr); 11697937d9ceSMichael Lange PetscFunctionReturn(0); 11707937d9ceSMichael Lange } 11717937d9ceSMichael Lange 11727937d9ceSMichael Lange #undef __FUNCT__ 1173c58f1c22SToby Isaac #define __FUNCT__ "DMLabelConvertToSection" 1174c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 1175c58f1c22SToby Isaac { 1176c58f1c22SToby Isaac IS vIS; 1177c58f1c22SToby Isaac const PetscInt *values; 1178c58f1c22SToby Isaac PetscInt *points; 1179c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 1180c58f1c22SToby Isaac PetscErrorCode ierr; 1181c58f1c22SToby Isaac 1182c58f1c22SToby Isaac PetscFunctionBegin; 1183c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr); 1184c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr); 1185c58f1c22SToby Isaac ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr); 1186c58f1c22SToby Isaac if (nV) {vS = values[0]; vE = values[0]+1;} 1187c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 1188c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 1189c58f1c22SToby Isaac vE = PetscMax(vE, values[v]+1); 1190c58f1c22SToby Isaac } 1191c58f1c22SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr); 1192c58f1c22SToby Isaac ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr); 1193c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1194c58f1c22SToby Isaac PetscInt n; 1195c58f1c22SToby Isaac 1196c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr); 1197c58f1c22SToby Isaac ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr); 1198c58f1c22SToby Isaac } 1199c58f1c22SToby Isaac ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 1200c58f1c22SToby Isaac ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr); 1201c58f1c22SToby Isaac ierr = PetscMalloc1(N, &points);CHKERRQ(ierr); 1202c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1203c58f1c22SToby Isaac IS is; 1204c58f1c22SToby Isaac const PetscInt *spoints; 1205c58f1c22SToby Isaac PetscInt dof, off, p; 1206c58f1c22SToby Isaac 1207c58f1c22SToby Isaac ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr); 1208c58f1c22SToby Isaac ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr); 1209c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr); 1210c58f1c22SToby Isaac ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr); 1211c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; 1212c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr); 1213c58f1c22SToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 1214c58f1c22SToby Isaac } 1215c58f1c22SToby Isaac ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr); 1216c58f1c22SToby Isaac ierr = ISDestroy(&vIS);CHKERRQ(ierr); 1217c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 1218c58f1c22SToby Isaac PetscFunctionReturn(0); 1219c58f1c22SToby Isaac } 1220c58f1c22SToby Isaac 1221c58f1c22SToby Isaac #undef __FUNCT__ 1222c58f1c22SToby Isaac #define __FUNCT__ "PetscSectionCreateGlobalSectionLabel" 1223c58f1c22SToby Isaac /*@C 1224c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 1225c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 1226c58f1c22SToby Isaac 1227c58f1c22SToby Isaac Input Parameters: 1228c58f1c22SToby Isaac + s - The PetscSection for the local field layout 1229c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 1230c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 1231c58f1c22SToby Isaac . label - The label specifying the points 1232c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 1233c58f1c22SToby Isaac 1234c58f1c22SToby Isaac Output Parameter: 1235c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 1236c58f1c22SToby Isaac 1237c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 1238c58f1c22SToby Isaac 1239c58f1c22SToby Isaac Level: developer 1240c58f1c22SToby Isaac 1241c58f1c22SToby Isaac .seealso: PetscSectionCreate() 1242c58f1c22SToby Isaac @*/ 1243c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 1244c58f1c22SToby Isaac { 1245c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 1246c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 1247c58f1c22SToby Isaac PetscErrorCode ierr; 1248c58f1c22SToby Isaac 1249c58f1c22SToby Isaac PetscFunctionBegin; 1250c58f1c22SToby Isaac ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr); 1251c58f1c22SToby Isaac ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1252c58f1c22SToby Isaac ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr); 1253c58f1c22SToby Isaac ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 1254c58f1c22SToby Isaac if (nroots >= 0) { 1255c58f1c22SToby Isaac if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart); 1256c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr); 1257c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1258c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr); 1259c58f1c22SToby Isaac } else { 1260c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 1261c58f1c22SToby Isaac } 1262c58f1c22SToby Isaac } 1263c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 1264c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 1265c58f1c22SToby Isaac PetscInt value; 1266c58f1c22SToby Isaac 1267c58f1c22SToby Isaac ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr); 1268c58f1c22SToby Isaac if (value != labelValue) continue; 1269c58f1c22SToby Isaac ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1270c58f1c22SToby Isaac ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr); 1271c58f1c22SToby Isaac ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1272c58f1c22SToby Isaac if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);} 1273c58f1c22SToby Isaac if (neg) neg[p] = -(dof+1); 1274c58f1c22SToby Isaac } 1275c58f1c22SToby Isaac ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr); 1276c58f1c22SToby Isaac if (nroots >= 0) { 1277c58f1c22SToby Isaac ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1278c58f1c22SToby Isaac ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1279c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1280c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 1281c58f1c22SToby Isaac } 1282c58f1c22SToby Isaac } 1283c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 1284c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1285c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 1286c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 1287c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 1288c58f1c22SToby Isaac } 1289c58f1c22SToby Isaac ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRQ(ierr); 1290c58f1c22SToby Isaac globalOff -= off; 1291c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1292c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 1293c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 1294c58f1c22SToby Isaac } 1295c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 1296c58f1c22SToby Isaac if (nroots >= 0) { 1297c58f1c22SToby Isaac ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1298c58f1c22SToby Isaac ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1299c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1300c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 1301c58f1c22SToby Isaac } 1302c58f1c22SToby Isaac } 1303c58f1c22SToby Isaac if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);} 1304c58f1c22SToby Isaac ierr = PetscFree(neg);CHKERRQ(ierr); 1305c58f1c22SToby Isaac PetscFunctionReturn(0); 1306c58f1c22SToby Isaac } 1307c58f1c22SToby Isaac 1308