15fdea053SToby Isaac #include <petscdm.h> 2c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 3c58f1c22SToby Isaac #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 4c58f1c22SToby Isaac #include <petscsf.h> 5c58f1c22SToby Isaac 6c58f1c22SToby Isaac /*@C 7c58f1c22SToby Isaac DMLabelCreate - Create a DMLabel object, which is a multimap 8c58f1c22SToby Isaac 9c58f1c22SToby Isaac Input parameter: 10c58f1c22SToby Isaac . name - The label name 11c58f1c22SToby Isaac 12c58f1c22SToby Isaac Output parameter: 13c58f1c22SToby Isaac . label - The DMLabel 14c58f1c22SToby Isaac 15c58f1c22SToby Isaac Level: beginner 16c58f1c22SToby Isaac 17c58f1c22SToby Isaac .seealso: DMLabelDestroy() 18c58f1c22SToby Isaac @*/ 19c58f1c22SToby Isaac PetscErrorCode DMLabelCreate(const char name[], DMLabel *label) 20c58f1c22SToby Isaac { 21c58f1c22SToby Isaac PetscErrorCode ierr; 22c58f1c22SToby Isaac 23c58f1c22SToby Isaac PetscFunctionBegin; 24c58f1c22SToby Isaac ierr = PetscNew(label);CHKERRQ(ierr); 25c58f1c22SToby Isaac ierr = PetscStrallocpy(name, &(*label)->name);CHKERRQ(ierr); 26c58f1c22SToby Isaac 27c58f1c22SToby Isaac (*label)->refct = 1; 28c58f1c22SToby Isaac (*label)->state = -1; 29c58f1c22SToby Isaac (*label)->numStrata = 0; 305aa44df4SToby Isaac (*label)->defaultValue = -1; 31c58f1c22SToby Isaac (*label)->stratumValues = NULL; 32ad8374ffSToby Isaac (*label)->validIS = NULL; 33c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 34c58f1c22SToby Isaac (*label)->points = NULL; 35c58f1c22SToby Isaac (*label)->ht = NULL; 36c58f1c22SToby Isaac (*label)->pStart = -1; 37c58f1c22SToby Isaac (*label)->pEnd = -1; 38c58f1c22SToby Isaac (*label)->bt = NULL; 39c58f1c22SToby Isaac PetscFunctionReturn(0); 40c58f1c22SToby Isaac } 41c58f1c22SToby Isaac 42c58f1c22SToby Isaac /* 43c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 44c58f1c22SToby Isaac 45c58f1c22SToby Isaac Input parameter: 46c58f1c22SToby Isaac + label - The DMLabel 47c58f1c22SToby Isaac - v - The stratum value 48c58f1c22SToby Isaac 49c58f1c22SToby Isaac Output parameter: 50c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format 51c58f1c22SToby Isaac 52c58f1c22SToby Isaac Level: developer 53c58f1c22SToby Isaac 54c58f1c22SToby Isaac .seealso: DMLabelCreate() 55c58f1c22SToby Isaac */ 56c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) 57c58f1c22SToby Isaac { 580c3c4a36SLisandro Dalcin PetscInt off = 0; 59ad8374ffSToby Isaac PetscInt *pointArray; 60c58f1c22SToby Isaac PetscErrorCode ierr; 61c58f1c22SToby Isaac 62ad8374ffSToby Isaac if (label->validIS[v]) return 0; 63c58f1c22SToby Isaac PetscFunctionBegin; 640c3c4a36SLisandro 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); 65e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v]);CHKERRQ(ierr); 66c58f1c22SToby Isaac 67ad8374ffSToby Isaac ierr = PetscMalloc1(label->stratumSizes[v], &pointArray);CHKERRQ(ierr); 68e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(label->ht[v], &off, pointArray);CHKERRQ(ierr); 69c58f1c22SToby 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]); 70e8f14785SLisandro Dalcin PetscHSetIClear(label->ht[v]); 71ad8374ffSToby Isaac ierr = PetscSortInt(label->stratumSizes[v], pointArray);CHKERRQ(ierr); 72c58f1c22SToby Isaac if (label->bt) { 73c58f1c22SToby Isaac PetscInt p; 74c58f1c22SToby Isaac 75c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 76ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 77c58f1c22SToby Isaac 78c58f1c22SToby 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); 79c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 80c58f1c22SToby Isaac } 81c58f1c22SToby Isaac } 82ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,label->stratumSizes[v],pointArray,PETSC_OWN_POINTER,&(label->points[v]));CHKERRQ(ierr); 83ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) (label->points[v]), "indices");CHKERRQ(ierr); 84ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 85c58f1c22SToby Isaac ++label->state; 86c58f1c22SToby Isaac PetscFunctionReturn(0); 87c58f1c22SToby Isaac } 88c58f1c22SToby Isaac 89c58f1c22SToby Isaac /* 90c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 91c58f1c22SToby Isaac 92c58f1c22SToby Isaac Input parameter: 93c58f1c22SToby Isaac . label - The DMLabel 94c58f1c22SToby Isaac 95c58f1c22SToby Isaac Output parameter: 96c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format 97c58f1c22SToby Isaac 98c58f1c22SToby Isaac Level: developer 99c58f1c22SToby Isaac 100c58f1c22SToby Isaac .seealso: DMLabelCreate() 101c58f1c22SToby Isaac */ 102c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 103c58f1c22SToby Isaac { 104c58f1c22SToby Isaac PetscInt v; 105c58f1c22SToby Isaac PetscErrorCode ierr; 106c58f1c22SToby Isaac 107c58f1c22SToby Isaac PetscFunctionBegin; 108c58f1c22SToby Isaac for (v = 0; v < label->numStrata; v++){ 109c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 110c58f1c22SToby Isaac } 111c58f1c22SToby Isaac PetscFunctionReturn(0); 112c58f1c22SToby Isaac } 113c58f1c22SToby Isaac 114c58f1c22SToby Isaac /* 115c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 116c58f1c22SToby Isaac 117c58f1c22SToby Isaac Input parameter: 118c58f1c22SToby Isaac + label - The DMLabel 119c58f1c22SToby Isaac - v - The stratum value 120c58f1c22SToby Isaac 121c58f1c22SToby Isaac Output parameter: 122c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format 123c58f1c22SToby Isaac 124c58f1c22SToby Isaac Level: developer 125c58f1c22SToby Isaac 126c58f1c22SToby Isaac .seealso: DMLabelCreate() 127c58f1c22SToby Isaac */ 128c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 129c58f1c22SToby Isaac { 130c58f1c22SToby Isaac PetscInt p; 131ad8374ffSToby Isaac const PetscInt *points; 132c58f1c22SToby Isaac PetscErrorCode ierr; 133c58f1c22SToby Isaac 1340c3c4a36SLisandro Dalcin if (!label->validIS[v]) return 0; 135c58f1c22SToby Isaac PetscFunctionBegin; 1360c3c4a36SLisandro 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); 137ad8374ffSToby Isaac if (label->points[v]) { 138ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 139e8f14785SLisandro Dalcin for (p = 0; p < label->stratumSizes[v]; ++p) { 140e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr); 141e8f14785SLisandro Dalcin } 142ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 143ad8374ffSToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 144ad8374ffSToby Isaac } 145ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 146c58f1c22SToby Isaac PetscFunctionReturn(0); 147c58f1c22SToby Isaac } 148c58f1c22SToby Isaac 149c58f1c22SToby Isaac PetscErrorCode DMLabelGetState(DMLabel label, PetscObjectState *state) 150c58f1c22SToby Isaac { 151c58f1c22SToby Isaac PetscFunctionBegin; 152c58f1c22SToby Isaac PetscValidPointer(state, 2); 153c58f1c22SToby Isaac *state = label->state; 154c58f1c22SToby Isaac PetscFunctionReturn(0); 155c58f1c22SToby Isaac } 156c58f1c22SToby Isaac 1570c3c4a36SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 1580c3c4a36SLisandro Dalcin { 1590c3c4a36SLisandro Dalcin PetscInt v; 1600c3c4a36SLisandro Dalcin PetscFunctionBegin; 1610c3c4a36SLisandro Dalcin for (*index = -1, v = 0; v < label->numStrata; ++v) 1620c3c4a36SLisandro Dalcin if (label->stratumValues[v] == value) { *index = v; break; } 1630c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 1640c3c4a36SLisandro Dalcin } 1650c3c4a36SLisandro Dalcin 1660c3c4a36SLisandro Dalcin static PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 167c58f1c22SToby Isaac { 168ad8374ffSToby Isaac PetscInt v, *tmpV, *tmpS; 169ad8374ffSToby Isaac IS *tmpP; 170e8f14785SLisandro Dalcin PetscHSetI *tmpH; 171c58f1c22SToby Isaac PetscBool *tmpB; 172c58f1c22SToby Isaac PetscErrorCode ierr; 173c58f1c22SToby Isaac 174c58f1c22SToby Isaac PetscFunctionBegin; 175c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpV);CHKERRQ(ierr); 176c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpS);CHKERRQ(ierr); 177c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpH);CHKERRQ(ierr); 178c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpP);CHKERRQ(ierr); 179c58f1c22SToby Isaac ierr = PetscMalloc1((label->numStrata+1), &tmpB);CHKERRQ(ierr); 180c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 181c58f1c22SToby Isaac tmpV[v] = label->stratumValues[v]; 182c58f1c22SToby Isaac tmpS[v] = label->stratumSizes[v]; 183c58f1c22SToby Isaac tmpH[v] = label->ht[v]; 184c58f1c22SToby Isaac tmpP[v] = label->points[v]; 185ad8374ffSToby Isaac tmpB[v] = label->validIS[v]; 186c58f1c22SToby Isaac } 187c58f1c22SToby Isaac tmpV[v] = value; 188c58f1c22SToby Isaac tmpS[v] = 0; 189e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&tmpH[v]);CHKERRQ(ierr); 190ecb9a371SToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&tmpP[v]);CHKERRQ(ierr); 191c58f1c22SToby Isaac tmpB[v] = PETSC_TRUE; 1920c3c4a36SLisandro Dalcin 193c58f1c22SToby Isaac ++label->numStrata; 194c58f1c22SToby Isaac ierr = PetscFree(label->stratumValues);CHKERRQ(ierr); 195c58f1c22SToby Isaac ierr = PetscFree(label->stratumSizes);CHKERRQ(ierr); 196c58f1c22SToby Isaac ierr = PetscFree(label->ht);CHKERRQ(ierr); 197c58f1c22SToby Isaac ierr = PetscFree(label->points);CHKERRQ(ierr); 198ad8374ffSToby Isaac ierr = PetscFree(label->validIS);CHKERRQ(ierr); 199c58f1c22SToby Isaac label->stratumValues = tmpV; 200c58f1c22SToby Isaac label->stratumSizes = tmpS; 201c58f1c22SToby Isaac label->ht = tmpH; 202c58f1c22SToby Isaac label->points = tmpP; 203ad8374ffSToby Isaac label->validIS = tmpB; 204c58f1c22SToby Isaac 2050c3c4a36SLisandro Dalcin *index = v; 2060c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 2070c3c4a36SLisandro Dalcin } 2080c3c4a36SLisandro Dalcin 2090c3c4a36SLisandro Dalcin PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 2100c3c4a36SLisandro Dalcin { 2110c3c4a36SLisandro Dalcin PetscInt v; 2120c3c4a36SLisandro Dalcin PetscErrorCode ierr; 2130c3c4a36SLisandro Dalcin 2140c3c4a36SLisandro Dalcin PetscFunctionBegin; 2150c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 2160c3c4a36SLisandro Dalcin if (v < 0) {ierr = DMLabelNewStratum(label, value, &v);CHKERRQ(ierr);} 217c58f1c22SToby Isaac PetscFunctionReturn(0); 218c58f1c22SToby Isaac } 219c58f1c22SToby Isaac 220c58f1c22SToby Isaac /*@C 221c58f1c22SToby Isaac DMLabelGetName - Return the name of a DMLabel object 222c58f1c22SToby Isaac 223c58f1c22SToby Isaac Input parameter: 224c58f1c22SToby Isaac . label - The DMLabel 225c58f1c22SToby Isaac 226c58f1c22SToby Isaac Output parameter: 227c58f1c22SToby Isaac . name - The label name 228c58f1c22SToby Isaac 229c58f1c22SToby Isaac Level: beginner 230c58f1c22SToby Isaac 231c58f1c22SToby Isaac .seealso: DMLabelCreate() 232c58f1c22SToby Isaac @*/ 233c58f1c22SToby Isaac PetscErrorCode DMLabelGetName(DMLabel label, const char **name) 234c58f1c22SToby Isaac { 235c58f1c22SToby Isaac PetscFunctionBegin; 236c58f1c22SToby Isaac PetscValidPointer(name, 2); 237c58f1c22SToby Isaac *name = label->name; 238c58f1c22SToby Isaac PetscFunctionReturn(0); 239c58f1c22SToby Isaac } 240c58f1c22SToby Isaac 241c779d965SMatthew G. Knepley /*@C 242c779d965SMatthew G. Knepley DMLabelSetName - Sets the name of a DMLabel object 243c779d965SMatthew G. Knepley 244c779d965SMatthew G. Knepley Input parameters: 245c779d965SMatthew G. Knepley + label - The DMLabel 246c779d965SMatthew G. Knepley - name - The label name 247c779d965SMatthew G. Knepley 248c779d965SMatthew G. Knepley Level: beginner 249c779d965SMatthew G. Knepley 250c779d965SMatthew G. Knepley .seealso: DMLabelCreate() 251c779d965SMatthew G. Knepley @*/ 252c779d965SMatthew G. Knepley PetscErrorCode DMLabelSetName(DMLabel label, const char *name) 253c779d965SMatthew G. Knepley { 254c779d965SMatthew G. Knepley PetscErrorCode ierr; 255c779d965SMatthew G. Knepley 256c779d965SMatthew G. Knepley PetscFunctionBegin; 257c779d965SMatthew G. Knepley PetscValidPointer(name, 2); 258c779d965SMatthew G. Knepley ierr = PetscFree(label->name);CHKERRQ(ierr); 259c779d965SMatthew G. Knepley ierr = PetscStrallocpy(name, &label->name);CHKERRQ(ierr); 260c779d965SMatthew G. Knepley PetscFunctionReturn(0); 261c779d965SMatthew G. Knepley } 262c779d965SMatthew G. Knepley 263c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) 264c58f1c22SToby Isaac { 265c58f1c22SToby Isaac PetscInt v; 266c58f1c22SToby Isaac PetscMPIInt rank; 267c58f1c22SToby Isaac PetscErrorCode ierr; 268c58f1c22SToby Isaac 269c58f1c22SToby Isaac PetscFunctionBegin; 270c58f1c22SToby Isaac ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRQ(ierr); 271c58f1c22SToby Isaac ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 272c58f1c22SToby Isaac if (label) { 273c58f1c22SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Label '%s':\n", label->name);CHKERRQ(ierr); 274c58f1c22SToby Isaac if (label->bt) {ierr = PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%D, %D)\n", label->pStart, label->pEnd);CHKERRQ(ierr);} 275c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 276c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 277ad8374ffSToby Isaac const PetscInt *points; 278c58f1c22SToby Isaac PetscInt p; 279c58f1c22SToby Isaac 280ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v],&points);CHKERRQ(ierr); 281c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 282ad8374ffSToby Isaac ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\n", rank, points[p], value);CHKERRQ(ierr); 283c58f1c22SToby Isaac } 284ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 285c58f1c22SToby Isaac } 286c58f1c22SToby Isaac } 287c58f1c22SToby Isaac ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 288c58f1c22SToby Isaac ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 289c58f1c22SToby Isaac PetscFunctionReturn(0); 290c58f1c22SToby Isaac } 291c58f1c22SToby Isaac 292c58f1c22SToby Isaac /*@C 293c58f1c22SToby Isaac DMLabelView - View the label 294c58f1c22SToby Isaac 295c58f1c22SToby Isaac Input Parameters: 296c58f1c22SToby Isaac + label - The DMLabel 297c58f1c22SToby Isaac - viewer - The PetscViewer 298c58f1c22SToby Isaac 299c58f1c22SToby Isaac Level: intermediate 300c58f1c22SToby Isaac 301c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelDestroy() 302c58f1c22SToby Isaac @*/ 303c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 304c58f1c22SToby Isaac { 305c58f1c22SToby Isaac PetscBool iascii; 306c58f1c22SToby Isaac PetscErrorCode ierr; 307c58f1c22SToby Isaac 308c58f1c22SToby Isaac PetscFunctionBegin; 309c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 310c58f1c22SToby Isaac if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 311c58f1c22SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 312c58f1c22SToby Isaac if (iascii) { 313c58f1c22SToby Isaac ierr = DMLabelView_Ascii(label, viewer);CHKERRQ(ierr); 314c58f1c22SToby Isaac } 315c58f1c22SToby Isaac PetscFunctionReturn(0); 316c58f1c22SToby Isaac } 317c58f1c22SToby Isaac 31884f0b6dfSMatthew G. Knepley /*@ 31984f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 32084f0b6dfSMatthew G. Knepley 32184f0b6dfSMatthew G. Knepley Input Parameter: 32284f0b6dfSMatthew G. Knepley . label - The DMLabel 32384f0b6dfSMatthew G. Knepley 32484f0b6dfSMatthew G. Knepley Level: beginner 32584f0b6dfSMatthew G. Knepley 32684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate() 32784f0b6dfSMatthew G. Knepley @*/ 328c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label) 329c58f1c22SToby Isaac { 330c58f1c22SToby Isaac PetscInt v; 331c58f1c22SToby Isaac PetscErrorCode ierr; 332c58f1c22SToby Isaac 333c58f1c22SToby Isaac PetscFunctionBegin; 334c58f1c22SToby Isaac if (!(*label)) PetscFunctionReturn(0); 335c58f1c22SToby Isaac if (--(*label)->refct > 0) PetscFunctionReturn(0); 336c58f1c22SToby Isaac ierr = PetscFree((*label)->name);CHKERRQ(ierr); 337c58f1c22SToby Isaac ierr = PetscFree((*label)->stratumValues);CHKERRQ(ierr); 338c58f1c22SToby Isaac ierr = PetscFree((*label)->stratumSizes);CHKERRQ(ierr); 3390c3c4a36SLisandro Dalcin for (v = 0; v < (*label)->numStrata; ++v) { 340e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&(*label)->ht[v]);CHKERRQ(ierr); 341e8f14785SLisandro Dalcin ierr = ISDestroy(&(*label)->points[v]);CHKERRQ(ierr); 3420c3c4a36SLisandro Dalcin } 3430c3c4a36SLisandro Dalcin ierr = PetscFree((*label)->ht);CHKERRQ(ierr); 344c58f1c22SToby Isaac ierr = PetscFree((*label)->points);CHKERRQ(ierr); 345ad8374ffSToby Isaac ierr = PetscFree((*label)->validIS);CHKERRQ(ierr); 346c58f1c22SToby Isaac ierr = PetscBTDestroy(&(*label)->bt);CHKERRQ(ierr); 347c58f1c22SToby Isaac ierr = PetscFree(*label);CHKERRQ(ierr); 348c58f1c22SToby Isaac PetscFunctionReturn(0); 349c58f1c22SToby Isaac } 350c58f1c22SToby Isaac 35184f0b6dfSMatthew G. Knepley /*@ 35284f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 35384f0b6dfSMatthew G. Knepley 35484f0b6dfSMatthew G. Knepley Input Parameter: 35584f0b6dfSMatthew G. Knepley . label - The DMLabel 35684f0b6dfSMatthew G. Knepley 35784f0b6dfSMatthew G. Knepley Output Parameter: 35884f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 35984f0b6dfSMatthew G. Knepley 36084f0b6dfSMatthew G. Knepley Level: intermediate 36184f0b6dfSMatthew G. Knepley 36284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelDestroy() 36384f0b6dfSMatthew G. Knepley @*/ 364c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 365c58f1c22SToby Isaac { 366ad8374ffSToby Isaac PetscInt v; 367c58f1c22SToby Isaac PetscErrorCode ierr; 368c58f1c22SToby Isaac 369c58f1c22SToby Isaac PetscFunctionBegin; 370c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 371c58f1c22SToby Isaac ierr = PetscNew(labelnew);CHKERRQ(ierr); 372c58f1c22SToby Isaac ierr = PetscStrallocpy(label->name, &(*labelnew)->name);CHKERRQ(ierr); 373c58f1c22SToby Isaac 374c58f1c22SToby Isaac (*labelnew)->refct = 1; 375c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 3765aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 377c58f1c22SToby Isaac if (label->numStrata) { 378c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues);CHKERRQ(ierr); 379c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes);CHKERRQ(ierr); 380c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->ht);CHKERRQ(ierr); 381c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->points);CHKERRQ(ierr); 382ad8374ffSToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->validIS);CHKERRQ(ierr); 383c58f1c22SToby Isaac /* Could eliminate unused space here */ 384c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 385e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelnew)->ht[v]);CHKERRQ(ierr); 386ad8374ffSToby Isaac (*labelnew)->validIS[v] = PETSC_TRUE; 387c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 388c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 389ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) (label->points[v]));CHKERRQ(ierr); 390ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 391c58f1c22SToby Isaac } 392c58f1c22SToby Isaac } 393c58f1c22SToby Isaac (*labelnew)->pStart = -1; 394c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 395c58f1c22SToby Isaac (*labelnew)->bt = NULL; 396c58f1c22SToby Isaac PetscFunctionReturn(0); 397c58f1c22SToby Isaac } 398c58f1c22SToby Isaac 399c58f1c22SToby Isaac /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 400c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 401c58f1c22SToby Isaac { 402c58f1c22SToby Isaac PetscInt v; 403c58f1c22SToby Isaac PetscErrorCode ierr; 404c58f1c22SToby Isaac 405c58f1c22SToby Isaac PetscFunctionBegin; 4060c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 407c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 408c58f1c22SToby Isaac label->pStart = pStart; 409c58f1c22SToby Isaac label->pEnd = pEnd; 410c58f1c22SToby Isaac ierr = PetscBTCreate(pEnd - pStart, &label->bt);CHKERRQ(ierr); 411c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 412ad8374ffSToby Isaac const PetscInt *points; 413c58f1c22SToby Isaac PetscInt i; 414c58f1c22SToby Isaac 415ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 416c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 417ad8374ffSToby Isaac const PetscInt point = points[i]; 418c58f1c22SToby Isaac 419c58f1c22SToby 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); 420c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - pStart);CHKERRQ(ierr); 421c58f1c22SToby Isaac } 422ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 423c58f1c22SToby Isaac } 424c58f1c22SToby Isaac PetscFunctionReturn(0); 425c58f1c22SToby Isaac } 426c58f1c22SToby Isaac 427c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label) 428c58f1c22SToby Isaac { 429c58f1c22SToby Isaac PetscErrorCode ierr; 430c58f1c22SToby Isaac 431c58f1c22SToby Isaac PetscFunctionBegin; 432c58f1c22SToby Isaac label->pStart = -1; 433c58f1c22SToby Isaac label->pEnd = -1; 4340c3c4a36SLisandro Dalcin ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 435c58f1c22SToby Isaac PetscFunctionReturn(0); 436c58f1c22SToby Isaac } 437c58f1c22SToby Isaac 438c58f1c22SToby Isaac /*@ 439c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 440c58f1c22SToby Isaac 441c58f1c22SToby Isaac Input Parameters: 442c58f1c22SToby Isaac + label - the DMLabel 443c58f1c22SToby Isaac - value - the value 444c58f1c22SToby Isaac 445c58f1c22SToby Isaac Output Parameter: 446c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 447c58f1c22SToby Isaac 448c58f1c22SToby Isaac Level: developer 449c58f1c22SToby Isaac 450c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue() 451c58f1c22SToby Isaac @*/ 452c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 453c58f1c22SToby Isaac { 454c58f1c22SToby Isaac PetscInt v; 4550c3c4a36SLisandro Dalcin PetscErrorCode ierr; 456c58f1c22SToby Isaac 457c58f1c22SToby Isaac PetscFunctionBegin; 458c58f1c22SToby Isaac PetscValidPointer(contains, 3); 4590c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 4600c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 461c58f1c22SToby Isaac PetscFunctionReturn(0); 462c58f1c22SToby Isaac } 463c58f1c22SToby Isaac 464c58f1c22SToby Isaac /*@ 465c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 466c58f1c22SToby Isaac 467c58f1c22SToby Isaac Input Parameters: 468c58f1c22SToby Isaac + label - the DMLabel 469c58f1c22SToby Isaac - point - the point 470c58f1c22SToby Isaac 471c58f1c22SToby Isaac Output Parameter: 472c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 473c58f1c22SToby Isaac 474c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 475c58f1c22SToby Isaac 476c58f1c22SToby Isaac Level: developer 477c58f1c22SToby Isaac 478c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 479c58f1c22SToby Isaac @*/ 480c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 481c58f1c22SToby Isaac { 482c58f1c22SToby Isaac PetscErrorCode ierr; 483c58f1c22SToby Isaac 484c58f1c22SToby Isaac PetscFunctionBeginHot; 485c58f1c22SToby Isaac PetscValidPointer(contains, 3); 486c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 487c58f1c22SToby Isaac #if defined(PETSC_USE_DEBUG) 488c58f1c22SToby Isaac if (!label->bt) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 489c58f1c22SToby 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); 490c58f1c22SToby Isaac #endif 491c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 492c58f1c22SToby Isaac PetscFunctionReturn(0); 493c58f1c22SToby Isaac } 494c58f1c22SToby Isaac 495c58f1c22SToby Isaac /*@ 496c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 497c58f1c22SToby Isaac 498c58f1c22SToby Isaac Input Parameters: 499c58f1c22SToby Isaac + label - the DMLabel 500c58f1c22SToby Isaac . value - the stratum value 501c58f1c22SToby Isaac - point - the point 502c58f1c22SToby Isaac 503c58f1c22SToby Isaac Output Parameter: 504c58f1c22SToby Isaac . contains - true if the stratum contains the point 505c58f1c22SToby Isaac 506c58f1c22SToby Isaac Level: intermediate 507c58f1c22SToby Isaac 508c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue() 509c58f1c22SToby Isaac @*/ 510c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 511c58f1c22SToby Isaac { 512c58f1c22SToby Isaac PetscInt v; 513c58f1c22SToby Isaac PetscErrorCode ierr; 514c58f1c22SToby Isaac 5150c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 516c58f1c22SToby Isaac PetscValidPointer(contains, 4); 517c58f1c22SToby Isaac *contains = PETSC_FALSE; 5180c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 5190c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 5200c3c4a36SLisandro Dalcin 521ad8374ffSToby Isaac if (label->validIS[v]) { 522c58f1c22SToby Isaac PetscInt i; 523c58f1c22SToby Isaac 524a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 5250c3c4a36SLisandro Dalcin if (i >= 0) *contains = PETSC_TRUE; 526c58f1c22SToby Isaac } else { 527c58f1c22SToby Isaac PetscBool has; 528c58f1c22SToby Isaac 529e8f14785SLisandro Dalcin PetscHSetIHas(label->ht[v], point, &has); 5300c3c4a36SLisandro Dalcin if (has) *contains = PETSC_TRUE; 531c58f1c22SToby Isaac } 532c58f1c22SToby Isaac PetscFunctionReturn(0); 533c58f1c22SToby Isaac } 534c58f1c22SToby Isaac 53584f0b6dfSMatthew G. Knepley /*@ 5365aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 5375aa44df4SToby Isaac When a label is created, it is initialized to -1. 5385aa44df4SToby Isaac 5395aa44df4SToby Isaac Input parameter: 5405aa44df4SToby Isaac . label - a DMLabel object 5415aa44df4SToby Isaac 5425aa44df4SToby Isaac Output parameter: 5435aa44df4SToby Isaac . defaultValue - the default value 5445aa44df4SToby Isaac 5455aa44df4SToby Isaac Level: beginner 5465aa44df4SToby Isaac 5475aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 54884f0b6dfSMatthew G. Knepley @*/ 5495aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 5505aa44df4SToby Isaac { 5515aa44df4SToby Isaac PetscFunctionBegin; 5525aa44df4SToby Isaac *defaultValue = label->defaultValue; 5535aa44df4SToby Isaac PetscFunctionReturn(0); 5545aa44df4SToby Isaac } 5555aa44df4SToby Isaac 55684f0b6dfSMatthew G. Knepley /*@ 5575aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 5585aa44df4SToby Isaac When a label is created, it is initialized to -1. 5595aa44df4SToby Isaac 5605aa44df4SToby Isaac Input parameter: 5615aa44df4SToby Isaac . label - a DMLabel object 5625aa44df4SToby Isaac 5635aa44df4SToby Isaac Output parameter: 5645aa44df4SToby Isaac . defaultValue - the default value 5655aa44df4SToby Isaac 5665aa44df4SToby Isaac Level: beginner 5675aa44df4SToby Isaac 5685aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 56984f0b6dfSMatthew G. Knepley @*/ 5705aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 5715aa44df4SToby Isaac { 5725aa44df4SToby Isaac PetscFunctionBegin; 5735aa44df4SToby Isaac label->defaultValue = defaultValue; 5745aa44df4SToby Isaac PetscFunctionReturn(0); 5755aa44df4SToby Isaac } 5765aa44df4SToby Isaac 577c58f1c22SToby Isaac /*@ 5785aa44df4SToby 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()) 579c58f1c22SToby Isaac 580c58f1c22SToby Isaac Input Parameters: 581c58f1c22SToby Isaac + label - the DMLabel 582c58f1c22SToby Isaac - point - the point 583c58f1c22SToby Isaac 584c58f1c22SToby Isaac Output Parameter: 5858e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 586c58f1c22SToby Isaac 587c58f1c22SToby Isaac Level: intermediate 588c58f1c22SToby Isaac 5895aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 590c58f1c22SToby Isaac @*/ 591c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 592c58f1c22SToby Isaac { 593c58f1c22SToby Isaac PetscInt v; 594c58f1c22SToby Isaac PetscErrorCode ierr; 595c58f1c22SToby Isaac 5960c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 597c58f1c22SToby Isaac PetscValidPointer(value, 3); 5985aa44df4SToby Isaac *value = label->defaultValue; 599c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 600ad8374ffSToby Isaac if (label->validIS[v]) { 601c58f1c22SToby Isaac PetscInt i; 602c58f1c22SToby Isaac 603a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 604c58f1c22SToby Isaac if (i >= 0) { 605c58f1c22SToby Isaac *value = label->stratumValues[v]; 606c58f1c22SToby Isaac break; 607c58f1c22SToby Isaac } 608c58f1c22SToby Isaac } else { 609c58f1c22SToby Isaac PetscBool has; 610c58f1c22SToby Isaac 611e8f14785SLisandro Dalcin PetscHSetIHas(label->ht[v], point, &has); 612c58f1c22SToby Isaac if (has) { 613c58f1c22SToby Isaac *value = label->stratumValues[v]; 614c58f1c22SToby Isaac break; 615c58f1c22SToby Isaac } 616c58f1c22SToby Isaac } 617c58f1c22SToby Isaac } 618c58f1c22SToby Isaac PetscFunctionReturn(0); 619c58f1c22SToby Isaac } 620c58f1c22SToby Isaac 621c58f1c22SToby Isaac /*@ 622*367003a6SStefano 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. 623c58f1c22SToby Isaac 624c58f1c22SToby Isaac Input Parameters: 625c58f1c22SToby Isaac + label - the DMLabel 626c58f1c22SToby Isaac . point - the point 627c58f1c22SToby Isaac - value - The point value 628c58f1c22SToby Isaac 629c58f1c22SToby Isaac Level: intermediate 630c58f1c22SToby Isaac 6315aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 632c58f1c22SToby Isaac @*/ 633c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 634c58f1c22SToby Isaac { 635c58f1c22SToby Isaac PetscInt v; 636c58f1c22SToby Isaac PetscErrorCode ierr; 637c58f1c22SToby Isaac 638c58f1c22SToby Isaac PetscFunctionBegin; 6390c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 6405aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 6410c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 6420c3c4a36SLisandro Dalcin if (v < 0) {ierr = DMLabelNewStratum(label, value, &v);CHKERRQ(ierr);} 643c58f1c22SToby Isaac /* Set key */ 6440c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 645e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(label->ht[v], point);CHKERRQ(ierr); 646c58f1c22SToby Isaac PetscFunctionReturn(0); 647c58f1c22SToby Isaac } 648c58f1c22SToby Isaac 649c58f1c22SToby Isaac /*@ 650c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 651c58f1c22SToby Isaac 652c58f1c22SToby Isaac Input Parameters: 653c58f1c22SToby Isaac + label - the DMLabel 654c58f1c22SToby Isaac . point - the point 655c58f1c22SToby Isaac - value - The point value 656c58f1c22SToby Isaac 657c58f1c22SToby Isaac Level: intermediate 658c58f1c22SToby Isaac 659c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue() 660c58f1c22SToby Isaac @*/ 661c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 662c58f1c22SToby Isaac { 663ad8374ffSToby Isaac PetscInt v; 664c58f1c22SToby Isaac PetscErrorCode ierr; 665c58f1c22SToby Isaac 666c58f1c22SToby Isaac PetscFunctionBegin; 667c58f1c22SToby Isaac /* Find label value */ 6680c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 6690c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 6700c3c4a36SLisandro Dalcin 671eeed21e7SToby Isaac if (label->bt) { 672eeed21e7SToby 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); 673eeed21e7SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 674eeed21e7SToby Isaac } 6750c3c4a36SLisandro Dalcin 6760c3c4a36SLisandro Dalcin /* Delete key */ 6770c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 678e8f14785SLisandro Dalcin ierr = PetscHSetIDel(label->ht[v], point);CHKERRQ(ierr); 679c58f1c22SToby Isaac PetscFunctionReturn(0); 680c58f1c22SToby Isaac } 681c58f1c22SToby Isaac 682c58f1c22SToby Isaac /*@ 683c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 684c58f1c22SToby Isaac 685c58f1c22SToby Isaac Input Parameters: 686c58f1c22SToby Isaac + label - the DMLabel 687c58f1c22SToby Isaac . is - the point IS 688c58f1c22SToby Isaac - value - The point value 689c58f1c22SToby Isaac 690c58f1c22SToby Isaac Level: intermediate 691c58f1c22SToby Isaac 692c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 693c58f1c22SToby Isaac @*/ 694c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 695c58f1c22SToby Isaac { 6960c3c4a36SLisandro Dalcin PetscInt v, n, p; 697c58f1c22SToby Isaac const PetscInt *points; 698c58f1c22SToby Isaac PetscErrorCode ierr; 699c58f1c22SToby Isaac 700c58f1c22SToby Isaac PetscFunctionBegin; 701c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 7020c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 7030c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 7040c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 7050c3c4a36SLisandro Dalcin if (v < 0) {ierr = DMLabelNewStratum(label, value, &v);CHKERRQ(ierr);} 7060c3c4a36SLisandro Dalcin /* Set keys */ 7070c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 708c58f1c22SToby Isaac ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 709c58f1c22SToby Isaac ierr = ISGetIndices(is, &points);CHKERRQ(ierr); 710e8f14785SLisandro Dalcin for (p = 0; p < n; ++p) {ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);} 711c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &points);CHKERRQ(ierr); 712c58f1c22SToby Isaac PetscFunctionReturn(0); 713c58f1c22SToby Isaac } 714c58f1c22SToby Isaac 71584f0b6dfSMatthew G. Knepley /*@ 71684f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 71784f0b6dfSMatthew G. Knepley 71884f0b6dfSMatthew G. Knepley Input Parameter: 71984f0b6dfSMatthew G. Knepley . label - the DMLabel 72084f0b6dfSMatthew G. Knepley 72184f0b6dfSMatthew G. Knepley Output Paramater: 72284f0b6dfSMatthew G. Knepley . numValues - the number of values 72384f0b6dfSMatthew G. Knepley 72484f0b6dfSMatthew G. Knepley Level: intermediate 72584f0b6dfSMatthew G. Knepley 72684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 72784f0b6dfSMatthew G. Knepley @*/ 728c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 729c58f1c22SToby Isaac { 730c58f1c22SToby Isaac PetscFunctionBegin; 731c58f1c22SToby Isaac PetscValidPointer(numValues, 2); 732c58f1c22SToby Isaac *numValues = label->numStrata; 733c58f1c22SToby Isaac PetscFunctionReturn(0); 734c58f1c22SToby Isaac } 735c58f1c22SToby Isaac 73684f0b6dfSMatthew G. Knepley /*@ 73784f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 73884f0b6dfSMatthew G. Knepley 73984f0b6dfSMatthew G. Knepley Input Parameter: 74084f0b6dfSMatthew G. Knepley . label - the DMLabel 74184f0b6dfSMatthew G. Knepley 74284f0b6dfSMatthew G. Knepley Output Paramater: 74384f0b6dfSMatthew G. Knepley . is - the value IS 74484f0b6dfSMatthew G. Knepley 74584f0b6dfSMatthew G. Knepley Level: intermediate 74684f0b6dfSMatthew G. Knepley 74784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 74884f0b6dfSMatthew G. Knepley @*/ 749c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 750c58f1c22SToby Isaac { 751c58f1c22SToby Isaac PetscErrorCode ierr; 752c58f1c22SToby Isaac 753c58f1c22SToby Isaac PetscFunctionBegin; 754c58f1c22SToby Isaac PetscValidPointer(values, 2); 755c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr); 756c58f1c22SToby Isaac PetscFunctionReturn(0); 757c58f1c22SToby Isaac } 758c58f1c22SToby Isaac 75984f0b6dfSMatthew G. Knepley /*@ 76084f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 76184f0b6dfSMatthew G. Knepley 76284f0b6dfSMatthew G. Knepley Input Parameters: 76384f0b6dfSMatthew G. Knepley + label - the DMLabel 76484f0b6dfSMatthew G. Knepley - value - the stratum value 76584f0b6dfSMatthew G. Knepley 76684f0b6dfSMatthew G. Knepley Output Paramater: 76784f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 76884f0b6dfSMatthew G. Knepley 76984f0b6dfSMatthew G. Knepley Level: intermediate 77084f0b6dfSMatthew G. Knepley 77184f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 77284f0b6dfSMatthew G. Knepley @*/ 773fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 774fada774cSMatthew G. Knepley { 775fada774cSMatthew G. Knepley PetscInt v; 7760c3c4a36SLisandro Dalcin PetscErrorCode ierr; 777fada774cSMatthew G. Knepley 778fada774cSMatthew G. Knepley PetscFunctionBegin; 779fada774cSMatthew G. Knepley PetscValidPointer(exists, 3); 7800c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 7810c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 782fada774cSMatthew G. Knepley PetscFunctionReturn(0); 783fada774cSMatthew G. Knepley } 784fada774cSMatthew G. Knepley 78584f0b6dfSMatthew G. Knepley /*@ 78684f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 78784f0b6dfSMatthew G. Knepley 78884f0b6dfSMatthew G. Knepley Input Parameters: 78984f0b6dfSMatthew G. Knepley + label - the DMLabel 79084f0b6dfSMatthew G. Knepley - value - the stratum value 79184f0b6dfSMatthew G. Knepley 79284f0b6dfSMatthew G. Knepley Output Paramater: 79384f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 79484f0b6dfSMatthew G. Knepley 79584f0b6dfSMatthew G. Knepley Level: intermediate 79684f0b6dfSMatthew G. Knepley 79784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 79884f0b6dfSMatthew G. Knepley @*/ 799c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 800c58f1c22SToby Isaac { 801c58f1c22SToby Isaac PetscInt v; 802c58f1c22SToby Isaac PetscErrorCode ierr; 803c58f1c22SToby Isaac 804c58f1c22SToby Isaac PetscFunctionBegin; 805c58f1c22SToby Isaac PetscValidPointer(size, 3); 806c58f1c22SToby Isaac *size = 0; 8070c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 8080c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 809c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 810c58f1c22SToby Isaac *size = label->stratumSizes[v]; 811c58f1c22SToby Isaac PetscFunctionReturn(0); 812c58f1c22SToby Isaac } 813c58f1c22SToby Isaac 81484f0b6dfSMatthew G. Knepley /*@ 81584f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 81684f0b6dfSMatthew G. Knepley 81784f0b6dfSMatthew G. Knepley Input Parameters: 81884f0b6dfSMatthew G. Knepley + label - the DMLabel 81984f0b6dfSMatthew G. Knepley - value - the stratum value 82084f0b6dfSMatthew G. Knepley 82184f0b6dfSMatthew G. Knepley Output Paramaters: 82284f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 82384f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 82484f0b6dfSMatthew G. Knepley 82584f0b6dfSMatthew G. Knepley Level: intermediate 82684f0b6dfSMatthew G. Knepley 82784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 82884f0b6dfSMatthew G. Knepley @*/ 829c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 830c58f1c22SToby Isaac { 8310c3c4a36SLisandro Dalcin PetscInt v, min, max; 832c58f1c22SToby Isaac PetscErrorCode ierr; 833c58f1c22SToby Isaac 834c58f1c22SToby Isaac PetscFunctionBegin; 835c58f1c22SToby Isaac if (start) {PetscValidPointer(start, 3); *start = 0;} 836c58f1c22SToby Isaac if (end) {PetscValidPointer(end, 4); *end = 0;} 8370c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 8380c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 839c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 8400c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 841d6cb179aSToby Isaac ierr = ISGetMinMax(label->points[v], &min, &max);CHKERRQ(ierr); 842d6cb179aSToby Isaac if (start) *start = min; 843d6cb179aSToby Isaac if (end) *end = max+1; 844c58f1c22SToby Isaac PetscFunctionReturn(0); 845c58f1c22SToby Isaac } 846c58f1c22SToby Isaac 84784f0b6dfSMatthew G. Knepley /*@ 84884f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 84984f0b6dfSMatthew G. Knepley 85084f0b6dfSMatthew G. Knepley Input Parameters: 85184f0b6dfSMatthew G. Knepley + label - the DMLabel 85284f0b6dfSMatthew G. Knepley - value - the stratum value 85384f0b6dfSMatthew G. Knepley 85484f0b6dfSMatthew G. Knepley Output Paramater: 85584f0b6dfSMatthew G. Knepley . points - The stratum points 85684f0b6dfSMatthew G. Knepley 85784f0b6dfSMatthew G. Knepley Level: intermediate 85884f0b6dfSMatthew G. Knepley 85984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 86084f0b6dfSMatthew G. Knepley @*/ 861c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 862c58f1c22SToby Isaac { 863c58f1c22SToby Isaac PetscInt v; 864c58f1c22SToby Isaac PetscErrorCode ierr; 865c58f1c22SToby Isaac 866c58f1c22SToby Isaac PetscFunctionBegin; 867c58f1c22SToby Isaac PetscValidPointer(points, 3); 868c58f1c22SToby Isaac *points = NULL; 8690c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 8700c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 871c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 872ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) label->points[v]);CHKERRQ(ierr); 873ad8374ffSToby Isaac *points = label->points[v]; 874c58f1c22SToby Isaac PetscFunctionReturn(0); 875c58f1c22SToby Isaac } 876c58f1c22SToby Isaac 87784f0b6dfSMatthew G. Knepley /*@ 87884f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 87984f0b6dfSMatthew G. Knepley 88084f0b6dfSMatthew G. Knepley Input Parameters: 88184f0b6dfSMatthew G. Knepley + label - the DMLabel 88284f0b6dfSMatthew G. Knepley . value - the stratum value 88384f0b6dfSMatthew G. Knepley - points - The stratum points 88484f0b6dfSMatthew G. Knepley 88584f0b6dfSMatthew G. Knepley Level: intermediate 88684f0b6dfSMatthew G. Knepley 88784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 88884f0b6dfSMatthew G. Knepley @*/ 8894de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 8904de306b1SToby Isaac { 8910c3c4a36SLisandro Dalcin PetscInt v; 8924de306b1SToby Isaac PetscErrorCode ierr; 8934de306b1SToby Isaac 8944de306b1SToby Isaac PetscFunctionBegin; 8950c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 8960c3c4a36SLisandro Dalcin if (v < 0) {ierr = DMLabelNewStratum(label, value, &v);CHKERRQ(ierr);} 8974de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 8984de306b1SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 8994de306b1SToby Isaac ierr = ISGetLocalSize(is, &(label->stratumSizes[v]));CHKERRQ(ierr); 9004de306b1SToby Isaac ierr = PetscObjectReference((PetscObject)is);CHKERRQ(ierr); 9014de306b1SToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 9020c3c4a36SLisandro Dalcin label->points[v] = is; 9030c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 9044de306b1SToby Isaac if (label->bt) { 9054de306b1SToby Isaac const PetscInt *points; 9064de306b1SToby Isaac PetscInt p; 9074de306b1SToby Isaac 9084de306b1SToby Isaac ierr = ISGetIndices(is,&points);CHKERRQ(ierr); 9094de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 9104de306b1SToby Isaac const PetscInt point = points[p]; 9114de306b1SToby Isaac 9124de306b1SToby 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); 9134de306b1SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 9144de306b1SToby Isaac } 9154de306b1SToby Isaac } 9164de306b1SToby Isaac PetscFunctionReturn(0); 9174de306b1SToby Isaac } 9184de306b1SToby Isaac 91984f0b6dfSMatthew G. Knepley /*@ 92084f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 9214de306b1SToby Isaac 92284f0b6dfSMatthew G. Knepley Input Parameters: 92384f0b6dfSMatthew G. Knepley + label - the DMLabel 92484f0b6dfSMatthew G. Knepley - value - the stratum value 92584f0b6dfSMatthew G. Knepley 92684f0b6dfSMatthew G. Knepley Level: intermediate 92784f0b6dfSMatthew G. Knepley 92884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 92984f0b6dfSMatthew G. Knepley @*/ 930c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 931c58f1c22SToby Isaac { 932c58f1c22SToby Isaac PetscInt v; 933c58f1c22SToby Isaac PetscErrorCode ierr; 934c58f1c22SToby Isaac 935c58f1c22SToby Isaac PetscFunctionBegin; 9360c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 9370c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 9384de306b1SToby Isaac if (label->validIS[v]) { 9394de306b1SToby Isaac if (label->bt) { 940c58f1c22SToby Isaac PetscInt i; 941ad8374ffSToby Isaac const PetscInt *points; 942c58f1c22SToby Isaac 943ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 944c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 945ad8374ffSToby Isaac const PetscInt point = points[i]; 946c58f1c22SToby Isaac 947c58f1c22SToby 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); 948c58f1c22SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 949c58f1c22SToby Isaac } 950ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 951c58f1c22SToby Isaac } 952c58f1c22SToby Isaac label->stratumSizes[v] = 0; 9530c3c4a36SLisandro Dalcin ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 9540c3c4a36SLisandro Dalcin ierr = ISCreateGeneral(PETSC_COMM_SELF, 0, NULL, PETSC_OWN_POINTER, &label->points[v]);CHKERRQ(ierr); 9550c3c4a36SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr); 956c58f1c22SToby Isaac } else { 957e8f14785SLisandro Dalcin PetscHSetIClear(label->ht[v]); 958c58f1c22SToby Isaac } 959c58f1c22SToby Isaac PetscFunctionReturn(0); 960c58f1c22SToby Isaac } 961c58f1c22SToby Isaac 96284f0b6dfSMatthew G. Knepley /*@ 96384f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 96484f0b6dfSMatthew G. Knepley 96584f0b6dfSMatthew G. Knepley Input Parameters: 96684f0b6dfSMatthew G. Knepley + label - the DMLabel 96784f0b6dfSMatthew G. Knepley . start - the first point 96884f0b6dfSMatthew G. Knepley - end - the last point 96984f0b6dfSMatthew G. Knepley 97084f0b6dfSMatthew G. Knepley Level: intermediate 97184f0b6dfSMatthew G. Knepley 97284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 97384f0b6dfSMatthew G. Knepley @*/ 974c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 975c58f1c22SToby Isaac { 976c58f1c22SToby Isaac PetscInt v; 977c58f1c22SToby Isaac PetscErrorCode ierr; 978c58f1c22SToby Isaac 979c58f1c22SToby Isaac PetscFunctionBegin; 9800c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 981c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 982c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 983c58f1c22SToby Isaac PetscInt off, q; 984ad8374ffSToby Isaac const PetscInt *points; 985033405d5SLisandro Dalcin PetscInt numPointsNew = 0, *pointsNew = NULL; 986c58f1c22SToby Isaac 987ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 988033405d5SLisandro Dalcin for (q = 0; q < label->stratumSizes[v]; ++q) 989033405d5SLisandro Dalcin if (points[q] >= start && points[q] < end) 990033405d5SLisandro Dalcin numPointsNew++; 991033405d5SLisandro Dalcin ierr = PetscMalloc1(numPointsNew, &pointsNew);CHKERRQ(ierr); 992c58f1c22SToby Isaac for (off = 0, q = 0; q < label->stratumSizes[v]; ++q) { 993033405d5SLisandro Dalcin if (points[q] >= start && points[q] < end) 994033405d5SLisandro Dalcin pointsNew[off++] = points[q]; 995ad8374ffSToby Isaac } 996ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 997033405d5SLisandro Dalcin 998033405d5SLisandro Dalcin label->stratumSizes[v] = numPointsNew; 999033405d5SLisandro Dalcin ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 1000033405d5SLisandro Dalcin ierr = ISCreateGeneral(PETSC_COMM_SELF,numPointsNew, pointsNew, PETSC_OWN_POINTER, &label->points[v]);CHKERRQ(ierr); 1001033405d5SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr); 1002c58f1c22SToby Isaac } 1003c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, start, end);CHKERRQ(ierr); 1004c58f1c22SToby Isaac PetscFunctionReturn(0); 1005c58f1c22SToby Isaac } 1006c58f1c22SToby Isaac 100784f0b6dfSMatthew G. Knepley /*@ 100884f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 100984f0b6dfSMatthew G. Knepley 101084f0b6dfSMatthew G. Knepley Input Parameters: 101184f0b6dfSMatthew G. Knepley + label - the DMLabel 101284f0b6dfSMatthew G. Knepley - permutation - the point permutation 101384f0b6dfSMatthew G. Knepley 101484f0b6dfSMatthew G. Knepley Output Parameter: 101584f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 101684f0b6dfSMatthew G. Knepley 101784f0b6dfSMatthew G. Knepley Level: intermediate 101884f0b6dfSMatthew G. Knepley 101984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 102084f0b6dfSMatthew G. Knepley @*/ 1021c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1022c58f1c22SToby Isaac { 1023c58f1c22SToby Isaac const PetscInt *perm; 1024c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1025c58f1c22SToby Isaac PetscErrorCode ierr; 1026c58f1c22SToby Isaac 1027c58f1c22SToby Isaac PetscFunctionBegin; 1028c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1029c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, labelNew);CHKERRQ(ierr); 1030c58f1c22SToby Isaac ierr = DMLabelGetNumValues(*labelNew, &numValues);CHKERRQ(ierr); 1031c58f1c22SToby Isaac ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr); 1032c58f1c22SToby Isaac ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr); 1033c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1034c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1035ad8374ffSToby Isaac const PetscInt *points; 1036ad8374ffSToby Isaac PetscInt *pointsNew; 1037c58f1c22SToby Isaac 1038ad8374ffSToby Isaac ierr = ISGetIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1039ad8374ffSToby Isaac ierr = PetscMalloc1(size,&pointsNew);CHKERRQ(ierr); 1040c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1041ad8374ffSToby Isaac const PetscInt point = points[q]; 1042c58f1c22SToby Isaac 1043c58f1c22SToby 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); 1044ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1045c58f1c22SToby Isaac } 1046ad8374ffSToby Isaac ierr = ISRestoreIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1047ad8374ffSToby Isaac ierr = PetscSortInt(size, pointsNew);CHKERRQ(ierr); 1048ad8374ffSToby Isaac ierr = ISDestroy(&((*labelNew)->points[v]));CHKERRQ(ierr); 1049fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 1050fa8e8ae5SToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]));CHKERRQ(ierr); 1051fa8e8ae5SToby Isaac ierr = PetscFree(pointsNew);CHKERRQ(ierr); 1052fa8e8ae5SToby Isaac } else { 1053ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]));CHKERRQ(ierr); 1054fa8e8ae5SToby Isaac } 1055ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices");CHKERRQ(ierr); 1056c58f1c22SToby Isaac } 1057c58f1c22SToby Isaac ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr); 1058c58f1c22SToby Isaac if (label->bt) { 1059c58f1c22SToby Isaac ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 1060c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 1061c58f1c22SToby Isaac } 1062c58f1c22SToby Isaac PetscFunctionReturn(0); 1063c58f1c22SToby Isaac } 1064c58f1c22SToby Isaac 106526c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 106626c55118SMichael Lange { 106726c55118SMichael Lange MPI_Comm comm; 106826c55118SMichael Lange PetscInt s, l, nroots, nleaves, dof, offset, size; 106926c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 107026c55118SMichael Lange PetscSection rootSection; 107126c55118SMichael Lange PetscSF labelSF; 107226c55118SMichael Lange PetscErrorCode ierr; 107326c55118SMichael Lange 107426c55118SMichael Lange PetscFunctionBegin; 107526c55118SMichael Lange if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 107626c55118SMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 107726c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 107826c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 107926c55118SMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL);CHKERRQ(ierr); 108026c55118SMichael Lange ierr = PetscSectionCreate(comm, &rootSection);CHKERRQ(ierr); 108126c55118SMichael Lange ierr = PetscSectionSetChart(rootSection, 0, nroots);CHKERRQ(ierr); 108226c55118SMichael Lange if (label) { 108326c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1084ad8374ffSToby Isaac const PetscInt *points; 1085ad8374ffSToby Isaac 1086ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 108726c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1088ad8374ffSToby Isaac ierr = PetscSectionGetDof(rootSection, points[l], &dof);CHKERRQ(ierr); 1089ad8374ffSToby Isaac ierr = PetscSectionSetDof(rootSection, points[l], dof+1);CHKERRQ(ierr); 109026c55118SMichael Lange } 1091ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 109226c55118SMichael Lange } 109326c55118SMichael Lange } 109426c55118SMichael Lange ierr = PetscSectionSetUp(rootSection);CHKERRQ(ierr); 109526c55118SMichael Lange /* Create a point-wise array of stratum values */ 109626c55118SMichael Lange ierr = PetscSectionGetStorageSize(rootSection, &size);CHKERRQ(ierr); 109726c55118SMichael Lange ierr = PetscMalloc1(size, &rootStrata);CHKERRQ(ierr); 109826c55118SMichael Lange ierr = PetscCalloc1(nroots, &rootIdx);CHKERRQ(ierr); 109926c55118SMichael Lange if (label) { 110026c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1101ad8374ffSToby Isaac const PetscInt *points; 1102ad8374ffSToby Isaac 1103ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 110426c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1105ad8374ffSToby Isaac const PetscInt p = points[l]; 110626c55118SMichael Lange ierr = PetscSectionGetOffset(rootSection, p, &offset);CHKERRQ(ierr); 110726c55118SMichael Lange rootStrata[offset+rootIdx[p]++] = label->stratumValues[s]; 110826c55118SMichael Lange } 1109ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 111026c55118SMichael Lange } 111126c55118SMichael Lange } 111226c55118SMichael Lange /* Build SF that maps label points to remote processes */ 111326c55118SMichael Lange ierr = PetscSectionCreate(comm, leafSection);CHKERRQ(ierr); 111426c55118SMichael Lange ierr = PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection);CHKERRQ(ierr); 111526c55118SMichael Lange ierr = PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF);CHKERRQ(ierr); 111626c55118SMichael Lange ierr = PetscFree(remoteOffsets);CHKERRQ(ierr); 111726c55118SMichael Lange /* Send the strata for each point over the derived SF */ 111826c55118SMichael Lange ierr = PetscSectionGetStorageSize(*leafSection, &size);CHKERRQ(ierr); 111926c55118SMichael Lange ierr = PetscMalloc1(size, leafStrata);CHKERRQ(ierr); 112026c55118SMichael Lange ierr = PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr); 112126c55118SMichael Lange ierr = PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr); 112226c55118SMichael Lange /* Clean up */ 112326c55118SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 112426c55118SMichael Lange ierr = PetscFree(rootIdx);CHKERRQ(ierr); 112526c55118SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 112626c55118SMichael Lange ierr = PetscSFDestroy(&labelSF);CHKERRQ(ierr); 112726c55118SMichael Lange PetscFunctionReturn(0); 112826c55118SMichael Lange } 112926c55118SMichael Lange 113084f0b6dfSMatthew G. Knepley /*@ 113184f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 113284f0b6dfSMatthew G. Knepley 113384f0b6dfSMatthew G. Knepley Input Parameters: 113484f0b6dfSMatthew G. Knepley + label - the DMLabel 113584f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 113684f0b6dfSMatthew G. Knepley 113784f0b6dfSMatthew G. Knepley Output Parameter: 113884f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 113984f0b6dfSMatthew G. Knepley 114084f0b6dfSMatthew G. Knepley Level: intermediate 114184f0b6dfSMatthew G. Knepley 114284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 114384f0b6dfSMatthew G. Knepley @*/ 1144c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1145c58f1c22SToby Isaac { 1146c58f1c22SToby Isaac MPI_Comm comm; 114726c55118SMichael Lange PetscSection leafSection; 114826c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 114926c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1150ad8374ffSToby Isaac PetscInt **points; 1151c58f1c22SToby Isaac char *name; 1152c58f1c22SToby Isaac PetscInt nameSize; 1153e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1154c58f1c22SToby Isaac size_t len = 0; 115526c55118SMichael Lange PetscMPIInt rank; 1156c58f1c22SToby Isaac PetscErrorCode ierr; 1157c58f1c22SToby Isaac 1158c58f1c22SToby Isaac PetscFunctionBegin; 1159c58f1c22SToby Isaac if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 1160c58f1c22SToby Isaac ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 1161c58f1c22SToby Isaac ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1162c58f1c22SToby Isaac /* Bcast name */ 1163c58f1c22SToby Isaac if (!rank) {ierr = PetscStrlen(label->name, &len);CHKERRQ(ierr);} 1164c58f1c22SToby Isaac nameSize = len; 1165c58f1c22SToby Isaac ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1166c58f1c22SToby Isaac ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1167c58f1c22SToby Isaac if (!rank) {ierr = PetscMemcpy(name, label->name, nameSize+1);CHKERRQ(ierr);} 1168c58f1c22SToby Isaac ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 1169c58f1c22SToby Isaac ierr = DMLabelCreate(name, labelNew);CHKERRQ(ierr); 1170c58f1c22SToby Isaac ierr = PetscFree(name);CHKERRQ(ierr); 117177d236dfSMichael Lange /* Bcast defaultValue */ 117277d236dfSMichael Lange if (!rank) (*labelNew)->defaultValue = label->defaultValue; 117377d236dfSMichael Lange ierr = MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 117426c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 117526c55118SMichael Lange ierr = DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata);CHKERRQ(ierr); 11765cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 1177e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&stratumHash);CHKERRQ(ierr); 117826c55118SMichael Lange ierr = PetscSectionGetStorageSize(leafSection, &size);CHKERRQ(ierr); 1179e8f14785SLisandro Dalcin for (p = 0; p < size; ++p) {ierr = PetscHSetIAdd(stratumHash, leafStrata[p]);CHKERRQ(ierr);} 1180e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata);CHKERRQ(ierr); 1181ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS);CHKERRQ(ierr); 1182ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 11835cbdf6fcSMichael Lange ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues);CHKERRQ(ierr); 11845cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 11855cbdf6fcSMichael Lange offset = 0; 1186e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues);CHKERRQ(ierr); 1187a205f1fdSToby Isaac ierr = PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues);CHKERRQ(ierr); 11885cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1189231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 1190231b9e6fSMatthew G. Knepley if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;} 11915cbdf6fcSMichael Lange } 11925cbdf6fcSMichael Lange } 1193c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 1194c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes);CHKERRQ(ierr); 1195c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1196c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1197c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1198c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1199c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1200c58f1c22SToby Isaac (*labelNew)->stratumSizes[leafStrata[offset+s]]++; 1201c58f1c22SToby Isaac } 1202c58f1c22SToby Isaac } 1203c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht);CHKERRQ(ierr); 1204c58f1c22SToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points);CHKERRQ(ierr); 1205ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&points);CHKERRQ(ierr); 1206c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 1207e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelNew)->ht[s]);CHKERRQ(ierr); 1208ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]));CHKERRQ(ierr); 1209c58f1c22SToby Isaac } 1210c58f1c22SToby Isaac /* Insert points into new strata */ 1211c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata, &strataIdx);CHKERRQ(ierr); 1212c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1213c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1214c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1215c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1216c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1217c58f1c22SToby Isaac stratum = leafStrata[offset+s]; 1218ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1219c58f1c22SToby Isaac } 1220c58f1c22SToby Isaac } 1221ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1222ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]));CHKERRQ(ierr); 1223ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices");CHKERRQ(ierr); 1224ad8374ffSToby Isaac } 1225ad8374ffSToby Isaac ierr = PetscFree(points);CHKERRQ(ierr); 1226e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&stratumHash);CHKERRQ(ierr); 1227c58f1c22SToby Isaac ierr = PetscFree(leafStrata);CHKERRQ(ierr); 1228c58f1c22SToby Isaac ierr = PetscFree(strataIdx);CHKERRQ(ierr); 1229c58f1c22SToby Isaac ierr = PetscSectionDestroy(&leafSection);CHKERRQ(ierr); 1230c58f1c22SToby Isaac PetscFunctionReturn(0); 1231c58f1c22SToby Isaac } 1232c58f1c22SToby Isaac 12337937d9ceSMichael Lange /*@ 12347937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 12357937d9ceSMichael Lange 12367937d9ceSMichael Lange Input Parameters: 12377937d9ceSMichael Lange + label - the DMLabel 123884f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 12397937d9ceSMichael Lange 124084f0b6dfSMatthew G. Knepley Output Parameters: 124184f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 12427937d9ceSMichael Lange 12437937d9ceSMichael Lange Level: developer 12447937d9ceSMichael Lange 12457937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 12467937d9ceSMichael Lange 12477937d9ceSMichael Lange .seealso: DMLabelDistribute() 12487937d9ceSMichael Lange @*/ 12497937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 12507937d9ceSMichael Lange { 12517937d9ceSMichael Lange MPI_Comm comm; 12527937d9ceSMichael Lange PetscSection rootSection; 12537937d9ceSMichael Lange PetscSF sfLabel; 12547937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 12557937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 12567937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 12577937d9ceSMichael Lange PetscInt *rootStrata; 12587937d9ceSMichael Lange char *name; 12597937d9ceSMichael Lange PetscInt nameSize; 12607937d9ceSMichael Lange size_t len = 0; 12619852e123SBarry Smith PetscMPIInt rank, size; 12627937d9ceSMichael Lange PetscErrorCode ierr; 12637937d9ceSMichael Lange 12647937d9ceSMichael Lange PetscFunctionBegin; 12657937d9ceSMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 12667937d9ceSMichael Lange ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 12679852e123SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 12687937d9ceSMichael Lange /* Bcast name */ 12697937d9ceSMichael Lange if (!rank) {ierr = PetscStrlen(label->name, &len);CHKERRQ(ierr);} 12707937d9ceSMichael Lange nameSize = len; 12717937d9ceSMichael Lange ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 12727937d9ceSMichael Lange ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 12737937d9ceSMichael Lange if (!rank) {ierr = PetscMemcpy(name, label->name, nameSize+1);CHKERRQ(ierr);} 12747937d9ceSMichael Lange ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 12757937d9ceSMichael Lange ierr = DMLabelCreate(name, labelNew);CHKERRQ(ierr); 12767937d9ceSMichael Lange ierr = PetscFree(name);CHKERRQ(ierr); 12777937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 12787937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 12797937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 12807937d9ceSMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL);CHKERRQ(ierr); 1281dc53bc9bSMatthew G. Knepley ierr = PetscMalloc1(nroots, &leafPoints);CHKERRQ(ierr); 1282dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 12837937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 1284dc53bc9bSMatthew G. Knepley leafPoints[ilocal[p]].index = ilocal[p]; 1285dc53bc9bSMatthew G. Knepley leafPoints[ilocal[p]].rank = rank; 12867937d9ceSMichael Lange } 12877937d9ceSMichael Lange ierr = PetscSFComputeDegreeBegin(sf, &rootDegree);CHKERRQ(ierr); 12887937d9ceSMichael Lange ierr = PetscSFComputeDegreeEnd(sf, &rootDegree);CHKERRQ(ierr); 12897937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 12907937d9ceSMichael Lange ierr = PetscMalloc1(nmultiroots, &rootPoints);CHKERRQ(ierr); 12917937d9ceSMichael Lange ierr = PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 12927937d9ceSMichael Lange ierr = PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 12937937d9ceSMichael Lange ierr = PetscSFCreate(comm,& sfLabel);CHKERRQ(ierr); 12947937d9ceSMichael Lange ierr = PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 12957937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 12967937d9ceSMichael Lange ierr = DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata);CHKERRQ(ierr); 12977937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 12987937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 12997937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 13007937d9ceSMichael Lange ierr = PetscSectionGetDof(rootSection, idx+d, &dof);CHKERRQ(ierr); 13017937d9ceSMichael Lange ierr = PetscSectionGetOffset(rootSection, idx+d, &offset);CHKERRQ(ierr); 13027937d9ceSMichael Lange for (s = 0; s < dof; s++) {ierr = DMLabelSetValue(*labelNew, p, rootStrata[offset+s]);CHKERRQ(ierr);} 13037937d9ceSMichael Lange } 13047937d9ceSMichael Lange idx += rootDegree[p]; 13057937d9ceSMichael Lange } 130677e0c0e7SMichael Lange ierr = PetscFree(leafPoints);CHKERRQ(ierr); 130777e0c0e7SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 130877e0c0e7SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 130977e0c0e7SMichael Lange ierr = PetscSFDestroy(&sfLabel);CHKERRQ(ierr); 13107937d9ceSMichael Lange PetscFunctionReturn(0); 13117937d9ceSMichael Lange } 13127937d9ceSMichael Lange 131384f0b6dfSMatthew G. Knepley /*@ 131484f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 131584f0b6dfSMatthew G. Knepley 131684f0b6dfSMatthew G. Knepley Input Parameter: 131784f0b6dfSMatthew G. Knepley . label - the DMLabel 131884f0b6dfSMatthew G. Knepley 131984f0b6dfSMatthew G. Knepley Output Parameters: 132084f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 132184f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 132284f0b6dfSMatthew G. Knepley 132384f0b6dfSMatthew G. Knepley Level: developer 132484f0b6dfSMatthew G. Knepley 132584f0b6dfSMatthew G. Knepley .seealso: DMLabelDistribute() 132684f0b6dfSMatthew G. Knepley @*/ 1327c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 1328c58f1c22SToby Isaac { 1329c58f1c22SToby Isaac IS vIS; 1330c58f1c22SToby Isaac const PetscInt *values; 1331c58f1c22SToby Isaac PetscInt *points; 1332c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 1333c58f1c22SToby Isaac PetscErrorCode ierr; 1334c58f1c22SToby Isaac 1335c58f1c22SToby Isaac PetscFunctionBegin; 1336c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr); 1337c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr); 1338c58f1c22SToby Isaac ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr); 1339c58f1c22SToby Isaac if (nV) {vS = values[0]; vE = values[0]+1;} 1340c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 1341c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 1342c58f1c22SToby Isaac vE = PetscMax(vE, values[v]+1); 1343c58f1c22SToby Isaac } 1344c58f1c22SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr); 1345c58f1c22SToby Isaac ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr); 1346c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1347c58f1c22SToby Isaac PetscInt n; 1348c58f1c22SToby Isaac 1349c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr); 1350c58f1c22SToby Isaac ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr); 1351c58f1c22SToby Isaac } 1352c58f1c22SToby Isaac ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 1353c58f1c22SToby Isaac ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr); 1354c58f1c22SToby Isaac ierr = PetscMalloc1(N, &points);CHKERRQ(ierr); 1355c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1356c58f1c22SToby Isaac IS is; 1357c58f1c22SToby Isaac const PetscInt *spoints; 1358c58f1c22SToby Isaac PetscInt dof, off, p; 1359c58f1c22SToby Isaac 1360c58f1c22SToby Isaac ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr); 1361c58f1c22SToby Isaac ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr); 1362c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr); 1363c58f1c22SToby Isaac ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr); 1364c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; 1365c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr); 1366c58f1c22SToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 1367c58f1c22SToby Isaac } 1368c58f1c22SToby Isaac ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr); 1369c58f1c22SToby Isaac ierr = ISDestroy(&vIS);CHKERRQ(ierr); 1370c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 1371c58f1c22SToby Isaac PetscFunctionReturn(0); 1372c58f1c22SToby Isaac } 1373c58f1c22SToby Isaac 137484f0b6dfSMatthew G. Knepley /*@ 1375c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 1376c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 1377c58f1c22SToby Isaac 1378c58f1c22SToby Isaac Input Parameters: 1379c58f1c22SToby Isaac + s - The PetscSection for the local field layout 1380c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 1381c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 1382c58f1c22SToby Isaac . label - The label specifying the points 1383c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 1384c58f1c22SToby Isaac 1385c58f1c22SToby Isaac Output Parameter: 1386c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 1387c58f1c22SToby Isaac 1388c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 1389c58f1c22SToby Isaac 1390c58f1c22SToby Isaac Level: developer 1391c58f1c22SToby Isaac 1392c58f1c22SToby Isaac .seealso: PetscSectionCreate() 1393c58f1c22SToby Isaac @*/ 1394c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 1395c58f1c22SToby Isaac { 1396c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 1397c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 1398c58f1c22SToby Isaac PetscErrorCode ierr; 1399c58f1c22SToby Isaac 1400c58f1c22SToby Isaac PetscFunctionBegin; 1401c58f1c22SToby Isaac ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr); 1402c58f1c22SToby Isaac ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1403c58f1c22SToby Isaac ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr); 1404c58f1c22SToby Isaac ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 1405c58f1c22SToby Isaac if (nroots >= 0) { 1406c58f1c22SToby Isaac if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart); 1407c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr); 1408c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1409c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr); 1410c58f1c22SToby Isaac } else { 1411c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 1412c58f1c22SToby Isaac } 1413c58f1c22SToby Isaac } 1414c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 1415c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 1416c58f1c22SToby Isaac PetscInt value; 1417c58f1c22SToby Isaac 1418c58f1c22SToby Isaac ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr); 1419c58f1c22SToby Isaac if (value != labelValue) continue; 1420c58f1c22SToby Isaac ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1421c58f1c22SToby Isaac ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr); 1422c58f1c22SToby Isaac ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1423c58f1c22SToby Isaac if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);} 1424c58f1c22SToby Isaac if (neg) neg[p] = -(dof+1); 1425c58f1c22SToby Isaac } 1426c58f1c22SToby Isaac ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr); 1427c58f1c22SToby Isaac if (nroots >= 0) { 1428c58f1c22SToby Isaac ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1429c58f1c22SToby Isaac ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1430c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1431c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 1432c58f1c22SToby Isaac } 1433c58f1c22SToby Isaac } 1434c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 1435c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1436c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 1437c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 1438c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 1439c58f1c22SToby Isaac } 1440c58f1c22SToby Isaac ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRQ(ierr); 1441c58f1c22SToby Isaac globalOff -= off; 1442c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1443c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 1444c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 1445c58f1c22SToby Isaac } 1446c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 1447c58f1c22SToby Isaac if (nroots >= 0) { 1448c58f1c22SToby Isaac ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1449c58f1c22SToby Isaac ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1450c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1451c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 1452c58f1c22SToby Isaac } 1453c58f1c22SToby Isaac } 1454c58f1c22SToby Isaac if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);} 1455c58f1c22SToby Isaac ierr = PetscFree(neg);CHKERRQ(ierr); 1456c58f1c22SToby Isaac PetscFunctionReturn(0); 1457c58f1c22SToby Isaac } 1458c58f1c22SToby Isaac 14595fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label 14605fdea053SToby Isaac { 14615fdea053SToby Isaac DMLabel label; 14625fdea053SToby Isaac PetscCopyMode *modes; 14635fdea053SToby Isaac PetscInt *sizes; 14645fdea053SToby Isaac const PetscInt ***perms; 14655fdea053SToby Isaac const PetscScalar ***rots; 14665fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 14675fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 14685fdea053SToby Isaac } PetscSectionSym_Label; 14695fdea053SToby Isaac 14705fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 14715fdea053SToby Isaac { 14725fdea053SToby Isaac PetscInt i, j; 14735fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 14745fdea053SToby Isaac PetscErrorCode ierr; 14755fdea053SToby Isaac 14765fdea053SToby Isaac PetscFunctionBegin; 14775fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 14785fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 14795fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 14805fdea053SToby Isaac if (sl->perms[i]) {ierr = PetscFree(sl->perms[i][j]);CHKERRQ(ierr);} 14815fdea053SToby Isaac if (sl->rots[i]) {ierr = PetscFree(sl->rots[i][j]);CHKERRQ(ierr);} 14825fdea053SToby Isaac } 14835fdea053SToby Isaac if (sl->perms[i]) { 14845fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 14855fdea053SToby Isaac 14865fdea053SToby Isaac ierr = PetscFree(perms);CHKERRQ(ierr); 14875fdea053SToby Isaac } 14885fdea053SToby Isaac if (sl->rots[i]) { 14895fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 14905fdea053SToby Isaac 14915fdea053SToby Isaac ierr = PetscFree(rots);CHKERRQ(ierr); 14925fdea053SToby Isaac } 14935fdea053SToby Isaac } 14945fdea053SToby Isaac } 14955fdea053SToby Isaac ierr = PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients);CHKERRQ(ierr); 14965fdea053SToby Isaac ierr = DMLabelDestroy(&sl->label);CHKERRQ(ierr); 14975fdea053SToby Isaac sl->numStrata = 0; 14985fdea053SToby Isaac PetscFunctionReturn(0); 14995fdea053SToby Isaac } 15005fdea053SToby Isaac 15015fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 15025fdea053SToby Isaac { 15035fdea053SToby Isaac PetscErrorCode ierr; 15045fdea053SToby Isaac 15055fdea053SToby Isaac PetscFunctionBegin; 15065fdea053SToby Isaac ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr); 15075fdea053SToby Isaac ierr = PetscFree(sym->data);CHKERRQ(ierr); 15085fdea053SToby Isaac PetscFunctionReturn(0); 15095fdea053SToby Isaac } 15105fdea053SToby Isaac 15115fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 15125fdea053SToby Isaac { 15135fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 15145fdea053SToby Isaac PetscBool isAscii; 15155fdea053SToby Isaac DMLabel label = sl->label; 15165fdea053SToby Isaac PetscErrorCode ierr; 15175fdea053SToby Isaac 15185fdea053SToby Isaac PetscFunctionBegin; 15195fdea053SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii);CHKERRQ(ierr); 15205fdea053SToby Isaac if (isAscii) { 15215fdea053SToby Isaac PetscInt i, j, k; 15225fdea053SToby Isaac PetscViewerFormat format; 15235fdea053SToby Isaac 15245fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 15255fdea053SToby Isaac if (label) { 15265fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 15275fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 15285fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 15295fdea053SToby Isaac ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 15305fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 15315fdea053SToby Isaac } else { 15325fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer," Label '%s'\n",sl->label->name);CHKERRQ(ierr); 15335fdea053SToby Isaac } 15345fdea053SToby Isaac } else { 15355fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "No label given\n");CHKERRQ(ierr); 15365fdea053SToby Isaac } 15375fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 15385fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 15395fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 15405fdea053SToby Isaac 15415fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 15425fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point): no symmetries\n", value, sl->sizes[i]);CHKERRQ(ierr); 15435fdea053SToby Isaac } else { 15445fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point):\n", value, sl->sizes[i]);CHKERRQ(ierr); 15455fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 15465fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation range: [%D, %D)\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1]);CHKERRQ(ierr); 15475fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 15485fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 15495fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 15505fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 15515fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D: identity\n",j);CHKERRQ(ierr); 15525fdea053SToby Isaac } else { 15535fdea053SToby Isaac PetscInt tab; 15545fdea053SToby Isaac 15555fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D:\n",j);CHKERRQ(ierr); 15565fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 15575fdea053SToby Isaac ierr = PetscViewerASCIIGetTab(viewer,&tab);CHKERRQ(ierr); 15585fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 15595fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Permutation:");CHKERRQ(ierr); 15605fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 15615fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %D",sl->perms[i][j][k]);CHKERRQ(ierr);} 15625fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 15635fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 15645fdea053SToby Isaac } 15655fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 15665fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Rotations: ");CHKERRQ(ierr); 15675fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 15685fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 15695fdea053SToby 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);} 15705fdea053SToby Isaac #else 15715fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f",sl->rots[i][j][k]);CHKERRQ(ierr);} 15725fdea053SToby Isaac #endif 15735fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 15745fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 15755fdea053SToby Isaac } 15765fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 15775fdea053SToby Isaac } 15785fdea053SToby Isaac } 15795fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 15805fdea053SToby Isaac } 15815fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 15825fdea053SToby Isaac } 15835fdea053SToby Isaac } 15845fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 15855fdea053SToby Isaac } 15865fdea053SToby Isaac PetscFunctionReturn(0); 15875fdea053SToby Isaac } 15885fdea053SToby Isaac 15895fdea053SToby Isaac /*@ 15905fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 15915fdea053SToby Isaac 15925fdea053SToby Isaac Logically collective on sym 15935fdea053SToby Isaac 15945fdea053SToby Isaac Input parameters: 15955fdea053SToby Isaac + sym - the section symmetries 15965fdea053SToby Isaac - label - the DMLabel describing the types of points 15975fdea053SToby Isaac 15985fdea053SToby Isaac Level: developer: 15995fdea053SToby Isaac 16005fdea053SToby Isaac .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreateLabel(), PetscSectionGetPointSyms() 16015fdea053SToby Isaac @*/ 16025fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 16035fdea053SToby Isaac { 16045fdea053SToby Isaac PetscSectionSym_Label *sl; 16055fdea053SToby Isaac PetscErrorCode ierr; 16065fdea053SToby Isaac 16075fdea053SToby Isaac PetscFunctionBegin; 16085fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 16095fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 16105fdea053SToby Isaac if (sl->label && sl->label != label) {ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);} 16115fdea053SToby Isaac if (label) { 16125fdea053SToby Isaac label->refct++; 16135fdea053SToby Isaac sl->label = label; 16145fdea053SToby Isaac ierr = DMLabelGetNumValues(label,&sl->numStrata);CHKERRQ(ierr); 16151a834cf9SToby 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); 16161a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode));CHKERRQ(ierr); 16171a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt));CHKERRQ(ierr); 16181a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **));CHKERRQ(ierr); 16191a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **));CHKERRQ(ierr); 16201a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]));CHKERRQ(ierr); 16215fdea053SToby Isaac } 16225fdea053SToby Isaac PetscFunctionReturn(0); 16235fdea053SToby Isaac } 16245fdea053SToby Isaac 16255fdea053SToby Isaac /*@C 16265fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 16275fdea053SToby Isaac 16285fdea053SToby Isaac Logically collective on PetscSectionSym 16295fdea053SToby Isaac 16305fdea053SToby Isaac InputParameters: 16315fdea053SToby Isaac + sys - the section symmetries 16325fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 16335fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 16345fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 16355fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 16365fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 16375fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 16385fdea053SToby Isaac + 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 16395fdea053SToby Isaac 16405fdea053SToby Isaac Level: developer 16415fdea053SToby Isaac 16425fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel() 16435fdea053SToby Isaac @*/ 16445fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 16455fdea053SToby Isaac { 16465fdea053SToby Isaac PetscInt i, j, k; 16475fdea053SToby Isaac PetscSectionSym_Label *sl; 16485fdea053SToby Isaac PetscErrorCode ierr; 16495fdea053SToby Isaac 16505fdea053SToby Isaac PetscFunctionBegin; 16515fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 16525fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 16535fdea053SToby Isaac if (!sl->label) SETERRQ(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_WRONGSTATE,"No label set yet"); 16545fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 16555fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 16565fdea053SToby Isaac 16575fdea053SToby Isaac if (stratum == value) break; 16585fdea053SToby Isaac } 16595fdea053SToby Isaac if (i > sl->numStrata) SETERRQ2(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_OUTOFRANGE,"Stratum %D not found in label %s\n",stratum,sl->label->name); 16605fdea053SToby Isaac sl->sizes[i] = size; 16615fdea053SToby Isaac sl->modes[i] = mode; 16625fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 16635fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 16645fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 16655fdea053SToby Isaac if (perms) { 16665fdea053SToby Isaac PetscInt **ownPerms; 16675fdea053SToby Isaac 16685fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownPerms);CHKERRQ(ierr); 16695fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 16705fdea053SToby Isaac if (perms[j]) { 16715fdea053SToby Isaac ierr = PetscMalloc1(size,&ownPerms[j]);CHKERRQ(ierr); 16725fdea053SToby Isaac for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];} 16735fdea053SToby Isaac } 16745fdea053SToby Isaac } 16755fdea053SToby Isaac sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient]; 16765fdea053SToby Isaac } 16775fdea053SToby Isaac if (rots) { 16785fdea053SToby Isaac PetscScalar **ownRots; 16795fdea053SToby Isaac 16805fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownRots);CHKERRQ(ierr); 16815fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 16825fdea053SToby Isaac if (rots[j]) { 16835fdea053SToby Isaac ierr = PetscMalloc1(size,&ownRots[j]);CHKERRQ(ierr); 16845fdea053SToby Isaac for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];} 16855fdea053SToby Isaac } 16865fdea053SToby Isaac } 16875fdea053SToby Isaac sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient]; 16885fdea053SToby Isaac } 16895fdea053SToby Isaac } else { 16905fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 16915fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 16925fdea053SToby Isaac } 16935fdea053SToby Isaac PetscFunctionReturn(0); 16945fdea053SToby Isaac } 16955fdea053SToby Isaac 16965fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 16975fdea053SToby Isaac { 16985fdea053SToby Isaac PetscInt i, j, numStrata; 16995fdea053SToby Isaac PetscSectionSym_Label *sl; 17005fdea053SToby Isaac DMLabel label; 17015fdea053SToby Isaac PetscErrorCode ierr; 17025fdea053SToby Isaac 17035fdea053SToby Isaac PetscFunctionBegin; 17045fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 17055fdea053SToby Isaac numStrata = sl->numStrata; 17065fdea053SToby Isaac label = sl->label; 17075fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 17085fdea053SToby Isaac PetscInt point = points[2*i]; 17095fdea053SToby Isaac PetscInt ornt = points[2*i+1]; 17105fdea053SToby Isaac 17115fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 17125fdea053SToby Isaac if (label->validIS[j]) { 17135fdea053SToby Isaac PetscInt k; 17145fdea053SToby Isaac 17155fdea053SToby Isaac ierr = ISLocate(label->points[j],point,&k);CHKERRQ(ierr); 17165fdea053SToby Isaac if (k >= 0) break; 17175fdea053SToby Isaac } else { 17185fdea053SToby Isaac PetscBool has; 17195fdea053SToby Isaac 1720e8f14785SLisandro Dalcin PetscHSetIHas(label->ht[j], point, &has); 17215fdea053SToby Isaac if (has) break; 17225fdea053SToby Isaac } 17235fdea053SToby Isaac } 17245fdea053SToby 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); 17255fdea053SToby Isaac if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;} 17265fdea053SToby Isaac if (rots) {rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL;} 17275fdea053SToby Isaac } 17285fdea053SToby Isaac PetscFunctionReturn(0); 17295fdea053SToby Isaac } 17305fdea053SToby Isaac 17315fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 17325fdea053SToby Isaac { 17335fdea053SToby Isaac PetscSectionSym_Label *sl; 17345fdea053SToby Isaac PetscErrorCode ierr; 17355fdea053SToby Isaac 17365fdea053SToby Isaac PetscFunctionBegin; 17375fdea053SToby Isaac ierr = PetscNewLog(sym,&sl);CHKERRQ(ierr); 17385fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 17395fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 17405fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 17415fdea053SToby Isaac sym->data = (void *) sl; 17425fdea053SToby Isaac PetscFunctionReturn(0); 17435fdea053SToby Isaac } 17445fdea053SToby Isaac 17455fdea053SToby Isaac /*@ 17465fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 17475fdea053SToby Isaac 17485fdea053SToby Isaac Collective 17495fdea053SToby Isaac 17505fdea053SToby Isaac Input Parameters: 17515fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 17525fdea053SToby Isaac - label - the label defining the strata 17535fdea053SToby Isaac 17545fdea053SToby Isaac Output Parameters: 17555fdea053SToby Isaac . sym - the section symmetries 17565fdea053SToby Isaac 17575fdea053SToby Isaac Level: developer 17585fdea053SToby Isaac 17595fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym(), PetscSectionSymLabelSetStratum(), PetscSectionGetPointSyms() 17605fdea053SToby Isaac @*/ 17615fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 17625fdea053SToby Isaac { 17635fdea053SToby Isaac PetscErrorCode ierr; 17645fdea053SToby Isaac 17655fdea053SToby Isaac PetscFunctionBegin; 17665fdea053SToby Isaac ierr = DMInitializePackage();CHKERRQ(ierr); 17675fdea053SToby Isaac ierr = PetscSectionSymCreate(comm,sym);CHKERRQ(ierr); 17685fdea053SToby Isaac ierr = PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL);CHKERRQ(ierr); 17695fdea053SToby Isaac ierr = PetscSectionSymLabelSetLabel(*sym,label);CHKERRQ(ierr); 17705fdea053SToby Isaac PetscFunctionReturn(0); 17715fdea053SToby Isaac } 1772