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 9*5b5e7992SMatthew G. Knepley Collective 10*5b5e7992SMatthew G. Knepley 11d67d17b1SMatthew G. Knepley Input parameters: 12d67d17b1SMatthew G. Knepley + comm - The communicator, usually PETSC_COMM_SELF 13d67d17b1SMatthew G. Knepley - name - The label name 14c58f1c22SToby Isaac 15c58f1c22SToby Isaac Output parameter: 16c58f1c22SToby Isaac . label - The DMLabel 17c58f1c22SToby Isaac 18c58f1c22SToby Isaac Level: beginner 19c58f1c22SToby Isaac 20c58f1c22SToby Isaac .seealso: DMLabelDestroy() 21c58f1c22SToby Isaac @*/ 22d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelCreate(MPI_Comm comm, const char name[], DMLabel *label) 23c58f1c22SToby Isaac { 24c58f1c22SToby Isaac PetscErrorCode ierr; 25c58f1c22SToby Isaac 26c58f1c22SToby Isaac PetscFunctionBegin; 27d67d17b1SMatthew G. Knepley PetscValidPointer(label,2); 28d67d17b1SMatthew G. Knepley ierr = DMInitializePackage();CHKERRQ(ierr); 29c58f1c22SToby Isaac 30d67d17b1SMatthew G. Knepley ierr = PetscHeaderCreate(*label,DMLABEL_CLASSID,"DMLabel","DMLabel","DM",comm,DMLabelDestroy,DMLabelView);CHKERRQ(ierr); 31d67d17b1SMatthew G. Knepley 32c58f1c22SToby Isaac (*label)->numStrata = 0; 335aa44df4SToby Isaac (*label)->defaultValue = -1; 34c58f1c22SToby Isaac (*label)->stratumValues = NULL; 35ad8374ffSToby Isaac (*label)->validIS = NULL; 36c58f1c22SToby Isaac (*label)->stratumSizes = NULL; 37c58f1c22SToby Isaac (*label)->points = NULL; 38c58f1c22SToby Isaac (*label)->ht = NULL; 39c58f1c22SToby Isaac (*label)->pStart = -1; 40c58f1c22SToby Isaac (*label)->pEnd = -1; 41c58f1c22SToby Isaac (*label)->bt = NULL; 42b9907514SLisandro Dalcin ierr = PetscHMapICreate(&(*label)->hmap);CHKERRQ(ierr); 43d67d17b1SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *label, name);CHKERRQ(ierr); 44c58f1c22SToby Isaac PetscFunctionReturn(0); 45c58f1c22SToby Isaac } 46c58f1c22SToby Isaac 47c58f1c22SToby Isaac /* 48c58f1c22SToby Isaac DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format 49c58f1c22SToby Isaac 50*5b5e7992SMatthew G. Knepley Not collective 51*5b5e7992SMatthew G. Knepley 52c58f1c22SToby Isaac Input parameter: 53c58f1c22SToby Isaac + label - The DMLabel 54c58f1c22SToby Isaac - v - The stratum value 55c58f1c22SToby Isaac 56c58f1c22SToby Isaac Output parameter: 57c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format 58c58f1c22SToby Isaac 59c58f1c22SToby Isaac Level: developer 60c58f1c22SToby Isaac 61c58f1c22SToby Isaac .seealso: DMLabelCreate() 62c58f1c22SToby Isaac */ 63c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v) 64c58f1c22SToby Isaac { 65277ea44aSLisandro Dalcin IS is; 66b9907514SLisandro Dalcin PetscInt off = 0, *pointArray, p; 67c58f1c22SToby Isaac PetscErrorCode ierr; 68c58f1c22SToby Isaac 69b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) return 0; 70c58f1c22SToby Isaac PetscFunctionBegin; 710c3c4a36SLisandro 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); 72e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v]);CHKERRQ(ierr); 73ad8374ffSToby Isaac ierr = PetscMalloc1(label->stratumSizes[v], &pointArray);CHKERRQ(ierr); 74e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(label->ht[v], &off, pointArray);CHKERRQ(ierr); 75b9907514SLisandro Dalcin ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr); 76ad8374ffSToby Isaac ierr = PetscSortInt(label->stratumSizes[v], pointArray);CHKERRQ(ierr); 77c58f1c22SToby Isaac if (label->bt) { 78c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 79ad8374ffSToby Isaac const PetscInt point = pointArray[p]; 80c58f1c22SToby 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); 81c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 82c58f1c22SToby Isaac } 83c58f1c22SToby Isaac } 84277ea44aSLisandro Dalcin ierr = ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is);CHKERRQ(ierr); 85277ea44aSLisandro Dalcin ierr = PetscObjectSetName((PetscObject) is, "indices");CHKERRQ(ierr); 86277ea44aSLisandro Dalcin label->points[v] = is; 87ad8374ffSToby Isaac label->validIS[v] = PETSC_TRUE; 88d67d17b1SMatthew G. Knepley ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 89c58f1c22SToby Isaac PetscFunctionReturn(0); 90c58f1c22SToby Isaac } 91c58f1c22SToby Isaac 92c58f1c22SToby Isaac /* 93c58f1c22SToby Isaac DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format 94c58f1c22SToby Isaac 95*5b5e7992SMatthew G. Knepley Not collective 96*5b5e7992SMatthew G. Knepley 97c58f1c22SToby Isaac Input parameter: 98c58f1c22SToby Isaac . label - The DMLabel 99c58f1c22SToby Isaac 100c58f1c22SToby Isaac Output parameter: 101c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format 102c58f1c22SToby Isaac 103c58f1c22SToby Isaac Level: developer 104c58f1c22SToby Isaac 105c58f1c22SToby Isaac .seealso: DMLabelCreate() 106c58f1c22SToby Isaac */ 107c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label) 108c58f1c22SToby Isaac { 109c58f1c22SToby Isaac PetscInt v; 110c58f1c22SToby Isaac PetscErrorCode ierr; 111c58f1c22SToby Isaac 112c58f1c22SToby Isaac PetscFunctionBegin; 113c58f1c22SToby Isaac for (v = 0; v < label->numStrata; v++){ 114c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 115c58f1c22SToby Isaac } 116c58f1c22SToby Isaac PetscFunctionReturn(0); 117c58f1c22SToby Isaac } 118c58f1c22SToby Isaac 119c58f1c22SToby Isaac /* 120c58f1c22SToby Isaac DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format 121c58f1c22SToby Isaac 122*5b5e7992SMatthew G. Knepley Not collective 123*5b5e7992SMatthew G. Knepley 124c58f1c22SToby Isaac Input parameter: 125c58f1c22SToby Isaac + label - The DMLabel 126c58f1c22SToby Isaac - v - The stratum value 127c58f1c22SToby Isaac 128c58f1c22SToby Isaac Output parameter: 129c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format 130c58f1c22SToby Isaac 131c58f1c22SToby Isaac Level: developer 132c58f1c22SToby Isaac 133c58f1c22SToby Isaac .seealso: DMLabelCreate() 134c58f1c22SToby Isaac */ 135c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v) 136c58f1c22SToby Isaac { 137c58f1c22SToby Isaac PetscInt p; 138ad8374ffSToby Isaac const PetscInt *points; 139c58f1c22SToby Isaac PetscErrorCode ierr; 140c58f1c22SToby Isaac 141b9907514SLisandro Dalcin if (PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) return 0; 142c58f1c22SToby Isaac PetscFunctionBegin; 1430c3c4a36SLisandro 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); 144ad8374ffSToby Isaac if (label->points[v]) { 145ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 146e8f14785SLisandro Dalcin for (p = 0; p < label->stratumSizes[v]; ++p) { 147e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr); 148e8f14785SLisandro Dalcin } 149ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 150ad8374ffSToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 151ad8374ffSToby Isaac } 152ad8374ffSToby Isaac label->validIS[v] = PETSC_FALSE; 153c58f1c22SToby Isaac PetscFunctionReturn(0); 154c58f1c22SToby Isaac } 155c58f1c22SToby Isaac 156b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD) 157b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16 158b9907514SLisandro Dalcin #endif 159b9907514SLisandro Dalcin 1600c3c4a36SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index) 1610c3c4a36SLisandro Dalcin { 1620c3c4a36SLisandro Dalcin PetscInt v; 163b9907514SLisandro Dalcin PetscErrorCode ierr; 1640e79e033SBarry Smith 1650c3c4a36SLisandro Dalcin PetscFunctionBegin; 1660e79e033SBarry Smith *index = -1; 167b9907514SLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 168b9907514SLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 169b9907514SLisandro Dalcin if (label->stratumValues[v] == value) {*index = v; break;} 170b9907514SLisandro Dalcin } else { 171b9907514SLisandro Dalcin ierr = PetscHMapIGet(label->hmap, value, index);CHKERRQ(ierr); 1720e79e033SBarry Smith } 17390e9b2aeSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 17490e9b2aeSLisandro Dalcin { /* Check strata hash map consistency */ 17590e9b2aeSLisandro Dalcin PetscInt len, loc = -1; 17690e9b2aeSLisandro Dalcin ierr = PetscHMapIGetSize(label->hmap, &len);CHKERRQ(ierr); 17790e9b2aeSLisandro Dalcin if (len != label->numStrata) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size"); 17890e9b2aeSLisandro Dalcin if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) { 17990e9b2aeSLisandro Dalcin ierr = PetscHMapIGet(label->hmap, value, &loc);CHKERRQ(ierr); 18090e9b2aeSLisandro Dalcin } else { 18190e9b2aeSLisandro Dalcin for (v = 0; v < label->numStrata; ++v) 18290e9b2aeSLisandro Dalcin if (label->stratumValues[v] == value) {loc = v; break;} 18390e9b2aeSLisandro Dalcin } 18490e9b2aeSLisandro Dalcin if (loc != *index) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup"); 18590e9b2aeSLisandro Dalcin } 18690e9b2aeSLisandro Dalcin #endif 1870c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 1880c3c4a36SLisandro Dalcin } 1890c3c4a36SLisandro Dalcin 190b9907514SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index) 191c58f1c22SToby Isaac { 192b9907514SLisandro Dalcin PetscInt v; 193b9907514SLisandro Dalcin PetscInt *tmpV; 194b9907514SLisandro Dalcin PetscInt *tmpS; 195b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 196b9907514SLisandro Dalcin IS *tmpP, is; 197c58f1c22SToby Isaac PetscBool *tmpB; 198b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 199c58f1c22SToby Isaac PetscErrorCode ierr; 200c58f1c22SToby Isaac 201c58f1c22SToby Isaac PetscFunctionBegin; 202b9907514SLisandro Dalcin v = label->numStrata; 203b9907514SLisandro Dalcin tmpV = label->stratumValues; 204b9907514SLisandro Dalcin tmpS = label->stratumSizes; 205b9907514SLisandro Dalcin tmpH = label->ht; 206b9907514SLisandro Dalcin tmpP = label->points; 207b9907514SLisandro Dalcin tmpB = label->validIS; 2088e1f8cf0SLisandro Dalcin { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free */ 2098e1f8cf0SLisandro Dalcin PetscInt *oldV = tmpV; 2108e1f8cf0SLisandro Dalcin PetscInt *oldS = tmpS; 2118e1f8cf0SLisandro Dalcin PetscHSetI *oldH = tmpH; 2128e1f8cf0SLisandro Dalcin IS *oldP = tmpP; 2138e1f8cf0SLisandro Dalcin PetscBool *oldB = tmpB; 2148e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpV), &tmpV);CHKERRQ(ierr); 2158e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpS), &tmpS);CHKERRQ(ierr); 2168e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpH), &tmpH);CHKERRQ(ierr); 2178e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpP), &tmpP);CHKERRQ(ierr); 2188e1f8cf0SLisandro Dalcin ierr = PetscMalloc((v+1)*sizeof(*tmpB), &tmpB);CHKERRQ(ierr); 2198e1f8cf0SLisandro Dalcin ierr = PetscMemcpy(tmpV, oldV, v*sizeof(*tmpV));CHKERRQ(ierr); 2208e1f8cf0SLisandro Dalcin ierr = PetscMemcpy(tmpS, oldS, v*sizeof(*tmpS));CHKERRQ(ierr); 2218e1f8cf0SLisandro Dalcin ierr = PetscMemcpy(tmpH, oldH, v*sizeof(*tmpH));CHKERRQ(ierr); 2228e1f8cf0SLisandro Dalcin ierr = PetscMemcpy(tmpP, oldP, v*sizeof(*tmpP));CHKERRQ(ierr); 2238e1f8cf0SLisandro Dalcin ierr = PetscMemcpy(tmpB, oldB, v*sizeof(*tmpB));CHKERRQ(ierr); 2248e1f8cf0SLisandro Dalcin ierr = PetscFree(oldV);CHKERRQ(ierr); 2258e1f8cf0SLisandro Dalcin ierr = PetscFree(oldS);CHKERRQ(ierr); 2268e1f8cf0SLisandro Dalcin ierr = PetscFree(oldH);CHKERRQ(ierr); 2278e1f8cf0SLisandro Dalcin ierr = PetscFree(oldP);CHKERRQ(ierr); 2288e1f8cf0SLisandro Dalcin ierr = PetscFree(oldB);CHKERRQ(ierr); 2298e1f8cf0SLisandro Dalcin } 230b9907514SLisandro Dalcin label->numStrata = v+1; 231c58f1c22SToby Isaac label->stratumValues = tmpV; 232c58f1c22SToby Isaac label->stratumSizes = tmpS; 233c58f1c22SToby Isaac label->ht = tmpH; 234c58f1c22SToby Isaac label->points = tmpP; 235ad8374ffSToby Isaac label->validIS = tmpB; 236b9907514SLisandro Dalcin ierr = PetscHSetICreate(&ht);CHKERRQ(ierr); 237b9907514SLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr); 238b9907514SLisandro Dalcin ierr = PetscHMapISet(hmap, value, v);CHKERRQ(ierr); 239b9907514SLisandro Dalcin tmpV[v] = value; 240b9907514SLisandro Dalcin tmpS[v] = 0; 241b9907514SLisandro Dalcin tmpH[v] = ht; 242b9907514SLisandro Dalcin tmpP[v] = is; 243b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 244277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 2450c3c4a36SLisandro Dalcin *index = v; 2460c3c4a36SLisandro Dalcin PetscFunctionReturn(0); 2470c3c4a36SLisandro Dalcin } 2480c3c4a36SLisandro Dalcin 249b9907514SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index) 250b9907514SLisandro Dalcin { 251b9907514SLisandro Dalcin PetscErrorCode ierr; 252b9907514SLisandro Dalcin PetscFunctionBegin; 253b9907514SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, index);CHKERRQ(ierr); 254b9907514SLisandro Dalcin if (*index < 0) {ierr = DMLabelNewStratum(label, value, index);CHKERRQ(ierr);} 255b9907514SLisandro Dalcin PetscFunctionReturn(0); 256b9907514SLisandro Dalcin } 257b9907514SLisandro Dalcin 258b9907514SLisandro Dalcin /*@ 259b9907514SLisandro Dalcin DMLabelAddStratum - Adds a new stratum value in a DMLabel 260b9907514SLisandro Dalcin 261b9907514SLisandro Dalcin Input Parameter: 262b9907514SLisandro Dalcin + label - The DMLabel 263b9907514SLisandro Dalcin - value - The stratum value 264b9907514SLisandro Dalcin 265b9907514SLisandro Dalcin Level: beginner 266b9907514SLisandro Dalcin 267b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 268b9907514SLisandro Dalcin @*/ 2690c3c4a36SLisandro Dalcin PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value) 2700c3c4a36SLisandro Dalcin { 2710c3c4a36SLisandro Dalcin PetscInt v; 2720c3c4a36SLisandro Dalcin PetscErrorCode ierr; 2730c3c4a36SLisandro Dalcin 2740c3c4a36SLisandro Dalcin PetscFunctionBegin; 275d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 276b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 277b9907514SLisandro Dalcin PetscFunctionReturn(0); 278b9907514SLisandro Dalcin } 279b9907514SLisandro Dalcin 280b9907514SLisandro Dalcin /*@ 281b9907514SLisandro Dalcin DMLabelAddStrata - Adds new stratum values in a DMLabel 282b9907514SLisandro Dalcin 283*5b5e7992SMatthew G. Knepley Not collective 284*5b5e7992SMatthew G. Knepley 285b9907514SLisandro Dalcin Input Parameter: 286b9907514SLisandro Dalcin + label - The DMLabel 287b9907514SLisandro Dalcin . numStrata - The number of stratum values 288b9907514SLisandro Dalcin - stratumValues - The stratum values 289b9907514SLisandro Dalcin 290b9907514SLisandro Dalcin Level: beginner 291b9907514SLisandro Dalcin 292b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 293b9907514SLisandro Dalcin @*/ 294b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[]) 295b9907514SLisandro Dalcin { 296b9907514SLisandro Dalcin PetscInt *values, v; 297b9907514SLisandro Dalcin PetscErrorCode ierr; 298b9907514SLisandro Dalcin 299b9907514SLisandro Dalcin PetscFunctionBegin; 300b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 301b9907514SLisandro Dalcin if (numStrata) PetscValidIntPointer(stratumValues, 3); 302b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &values);CHKERRQ(ierr); 303b9907514SLisandro Dalcin ierr = PetscMemcpy(values, stratumValues, numStrata*sizeof(PetscInt));CHKERRQ(ierr); 304b9907514SLisandro Dalcin ierr = PetscSortRemoveDupsInt(&numStrata, values);CHKERRQ(ierr); 305b9907514SLisandro Dalcin if (!label->numStrata) { /* Fast preallocation */ 306b9907514SLisandro Dalcin PetscInt *tmpV; 307b9907514SLisandro Dalcin PetscInt *tmpS; 308b9907514SLisandro Dalcin PetscHSetI *tmpH, ht; 309b9907514SLisandro Dalcin IS *tmpP, is; 310b9907514SLisandro Dalcin PetscBool *tmpB; 311b9907514SLisandro Dalcin PetscHMapI hmap = label->hmap; 312b9907514SLisandro Dalcin 313b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpV);CHKERRQ(ierr); 314b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpS);CHKERRQ(ierr); 315b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpH);CHKERRQ(ierr); 316b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpP);CHKERRQ(ierr); 317b9907514SLisandro Dalcin ierr = PetscMalloc1(numStrata, &tmpB);CHKERRQ(ierr); 318b9907514SLisandro Dalcin label->numStrata = numStrata; 319b9907514SLisandro Dalcin label->stratumValues = tmpV; 320b9907514SLisandro Dalcin label->stratumSizes = tmpS; 321b9907514SLisandro Dalcin label->ht = tmpH; 322b9907514SLisandro Dalcin label->points = tmpP; 323b9907514SLisandro Dalcin label->validIS = tmpB; 324b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 325b9907514SLisandro Dalcin ierr = PetscHSetICreate(&ht);CHKERRQ(ierr); 326b9907514SLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr); 327b9907514SLisandro Dalcin ierr = PetscHMapISet(hmap, values[v], v);CHKERRQ(ierr); 328b9907514SLisandro Dalcin tmpV[v] = values[v]; 329b9907514SLisandro Dalcin tmpS[v] = 0; 330b9907514SLisandro Dalcin tmpH[v] = ht; 331b9907514SLisandro Dalcin tmpP[v] = is; 332b9907514SLisandro Dalcin tmpB[v] = PETSC_TRUE; 333b9907514SLisandro Dalcin } 334277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 335b9907514SLisandro Dalcin } else { 336b9907514SLisandro Dalcin for (v = 0; v < numStrata; ++v) { 337b9907514SLisandro Dalcin ierr = DMLabelAddStratum(label, values[v]);CHKERRQ(ierr); 338b9907514SLisandro Dalcin } 339b9907514SLisandro Dalcin } 340b9907514SLisandro Dalcin ierr = PetscFree(values);CHKERRQ(ierr); 341b9907514SLisandro Dalcin PetscFunctionReturn(0); 342b9907514SLisandro Dalcin } 343b9907514SLisandro Dalcin 344b9907514SLisandro Dalcin /*@ 345b9907514SLisandro Dalcin DMLabelAddStrataIS - Adds new stratum values in a DMLabel 346b9907514SLisandro Dalcin 347*5b5e7992SMatthew G. Knepley Not collective 348*5b5e7992SMatthew G. Knepley 349b9907514SLisandro Dalcin Input Parameter: 350b9907514SLisandro Dalcin + label - The DMLabel 351b9907514SLisandro Dalcin - valueIS - Index set with stratum values 352b9907514SLisandro Dalcin 353b9907514SLisandro Dalcin Level: beginner 354b9907514SLisandro Dalcin 355b9907514SLisandro Dalcin .seealso: DMLabelCreate(), DMLabelDestroy() 356b9907514SLisandro Dalcin @*/ 357b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS) 358b9907514SLisandro Dalcin { 359b9907514SLisandro Dalcin PetscInt numStrata; 360b9907514SLisandro Dalcin const PetscInt *stratumValues; 361b9907514SLisandro Dalcin PetscErrorCode ierr; 362b9907514SLisandro Dalcin 363b9907514SLisandro Dalcin PetscFunctionBegin; 364b9907514SLisandro Dalcin PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 365b9907514SLisandro Dalcin PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2); 366b9907514SLisandro Dalcin ierr = ISGetLocalSize(valueIS, &numStrata);CHKERRQ(ierr); 367b9907514SLisandro Dalcin ierr = ISGetIndices(valueIS, &stratumValues);CHKERRQ(ierr); 368b9907514SLisandro Dalcin ierr = DMLabelAddStrata(label, numStrata, stratumValues);CHKERRQ(ierr); 369c58f1c22SToby Isaac PetscFunctionReturn(0); 370c58f1c22SToby Isaac } 371c58f1c22SToby Isaac 372c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer) 373c58f1c22SToby Isaac { 374c58f1c22SToby Isaac PetscInt v; 375c58f1c22SToby Isaac PetscMPIInt rank; 376c58f1c22SToby Isaac PetscErrorCode ierr; 377c58f1c22SToby Isaac 378c58f1c22SToby Isaac PetscFunctionBegin; 379c58f1c22SToby Isaac ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRQ(ierr); 380c58f1c22SToby Isaac ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 381c58f1c22SToby Isaac if (label) { 382d67d17b1SMatthew G. Knepley const char *name; 383d67d17b1SMatthew G. Knepley 384d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 385d67d17b1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name);CHKERRQ(ierr); 386c58f1c22SToby Isaac if (label->bt) {ierr = PetscViewerASCIIPrintf(viewer, " Index has been calculated in [%D, %D)\n", label->pStart, label->pEnd);CHKERRQ(ierr);} 387c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 388c58f1c22SToby Isaac const PetscInt value = label->stratumValues[v]; 389ad8374ffSToby Isaac const PetscInt *points; 390c58f1c22SToby Isaac PetscInt p; 391c58f1c22SToby Isaac 392ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 393c58f1c22SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 394ad8374ffSToby Isaac ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\n", rank, points[p], value);CHKERRQ(ierr); 395c58f1c22SToby Isaac } 396ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 397c58f1c22SToby Isaac } 398c58f1c22SToby Isaac } 399c58f1c22SToby Isaac ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 400c58f1c22SToby Isaac ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 401c58f1c22SToby Isaac PetscFunctionReturn(0); 402c58f1c22SToby Isaac } 403c58f1c22SToby Isaac 404c58f1c22SToby Isaac /*@C 405c58f1c22SToby Isaac DMLabelView - View the label 406c58f1c22SToby Isaac 407*5b5e7992SMatthew G. Knepley Collective on viewer 408*5b5e7992SMatthew G. Knepley 409c58f1c22SToby Isaac Input Parameters: 410c58f1c22SToby Isaac + label - The DMLabel 411c58f1c22SToby Isaac - viewer - The PetscViewer 412c58f1c22SToby Isaac 413c58f1c22SToby Isaac Level: intermediate 414c58f1c22SToby Isaac 415c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelDestroy() 416c58f1c22SToby Isaac @*/ 417c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer) 418c58f1c22SToby Isaac { 419c58f1c22SToby Isaac PetscBool iascii; 420c58f1c22SToby Isaac PetscErrorCode ierr; 421c58f1c22SToby Isaac 422c58f1c22SToby Isaac PetscFunctionBegin; 423d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 424b9907514SLisandro Dalcin if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer);CHKERRQ(ierr);} 425c58f1c22SToby Isaac PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 426c58f1c22SToby Isaac if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 427c58f1c22SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 428c58f1c22SToby Isaac if (iascii) { 429c58f1c22SToby Isaac ierr = DMLabelView_Ascii(label, viewer);CHKERRQ(ierr); 430c58f1c22SToby Isaac } 431c58f1c22SToby Isaac PetscFunctionReturn(0); 432c58f1c22SToby Isaac } 433c58f1c22SToby Isaac 43484f0b6dfSMatthew G. Knepley /*@ 435d67d17b1SMatthew G. Knepley DMLabelReset - Destroys internal data structures in a DMLabel 436d67d17b1SMatthew G. Knepley 437*5b5e7992SMatthew G. Knepley Not collective 438*5b5e7992SMatthew G. Knepley 439d67d17b1SMatthew G. Knepley Input Parameter: 440d67d17b1SMatthew G. Knepley . label - The DMLabel 441d67d17b1SMatthew G. Knepley 442d67d17b1SMatthew G. Knepley Level: beginner 443d67d17b1SMatthew G. Knepley 444d67d17b1SMatthew G. Knepley .seealso: DMLabelDestroy(), DMLabelCreate() 445d67d17b1SMatthew G. Knepley @*/ 446d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelReset(DMLabel label) 447d67d17b1SMatthew G. Knepley { 448d67d17b1SMatthew G. Knepley PetscInt v; 449d67d17b1SMatthew G. Knepley PetscErrorCode ierr; 450d67d17b1SMatthew G. Knepley 451d67d17b1SMatthew G. Knepley PetscFunctionBegin; 452d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 453d67d17b1SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 454d67d17b1SMatthew G. Knepley ierr = PetscHSetIDestroy(&label->ht[v]);CHKERRQ(ierr); 455d67d17b1SMatthew G. Knepley ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 456d67d17b1SMatthew G. Knepley } 457b9907514SLisandro Dalcin label->numStrata = 0; 458b9907514SLisandro Dalcin ierr = PetscFree(label->stratumValues);CHKERRQ(ierr); 459b9907514SLisandro Dalcin ierr = PetscFree(label->stratumSizes);CHKERRQ(ierr); 460d67d17b1SMatthew G. Knepley ierr = PetscFree(label->ht);CHKERRQ(ierr); 461d67d17b1SMatthew G. Knepley ierr = PetscFree(label->points);CHKERRQ(ierr); 462d67d17b1SMatthew G. Knepley ierr = PetscFree(label->validIS);CHKERRQ(ierr); 463b9907514SLisandro Dalcin ierr = PetscHMapIReset(label->hmap);CHKERRQ(ierr); 464b9907514SLisandro Dalcin label->pStart = -1; 465b9907514SLisandro Dalcin label->pEnd = -1; 466d67d17b1SMatthew G. Knepley ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 467d67d17b1SMatthew G. Knepley PetscFunctionReturn(0); 468d67d17b1SMatthew G. Knepley } 469d67d17b1SMatthew G. Knepley 470d67d17b1SMatthew G. Knepley /*@ 47184f0b6dfSMatthew G. Knepley DMLabelDestroy - Destroys a DMLabel 47284f0b6dfSMatthew G. Knepley 473*5b5e7992SMatthew G. Knepley Collective on label 474*5b5e7992SMatthew G. Knepley 47584f0b6dfSMatthew G. Knepley Input Parameter: 47684f0b6dfSMatthew G. Knepley . label - The DMLabel 47784f0b6dfSMatthew G. Knepley 47884f0b6dfSMatthew G. Knepley Level: beginner 47984f0b6dfSMatthew G. Knepley 480d67d17b1SMatthew G. Knepley .seealso: DMLabelReset(), DMLabelCreate() 48184f0b6dfSMatthew G. Knepley @*/ 482c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label) 483c58f1c22SToby Isaac { 484c58f1c22SToby Isaac PetscErrorCode ierr; 485c58f1c22SToby Isaac 486c58f1c22SToby Isaac PetscFunctionBegin; 487d67d17b1SMatthew G. Knepley if (!*label) PetscFunctionReturn(0); 488d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific((*label),DMLABEL_CLASSID,1); 489b9907514SLisandro Dalcin if (--((PetscObject)(*label))->refct > 0) {*label = NULL; PetscFunctionReturn(0);} 490d67d17b1SMatthew G. Knepley ierr = DMLabelReset(*label);CHKERRQ(ierr); 491b9907514SLisandro Dalcin ierr = PetscHMapIDestroy(&(*label)->hmap);CHKERRQ(ierr); 492d67d17b1SMatthew G. Knepley ierr = PetscHeaderDestroy(label);CHKERRQ(ierr); 493c58f1c22SToby Isaac PetscFunctionReturn(0); 494c58f1c22SToby Isaac } 495c58f1c22SToby Isaac 49684f0b6dfSMatthew G. Knepley /*@ 49784f0b6dfSMatthew G. Knepley DMLabelDuplicate - Duplicates a DMLabel 49884f0b6dfSMatthew G. Knepley 499*5b5e7992SMatthew G. Knepley Collective on label 500*5b5e7992SMatthew G. Knepley 50184f0b6dfSMatthew G. Knepley Input Parameter: 50284f0b6dfSMatthew G. Knepley . label - The DMLabel 50384f0b6dfSMatthew G. Knepley 50484f0b6dfSMatthew G. Knepley Output Parameter: 50584f0b6dfSMatthew G. Knepley . labelnew - location to put new vector 50684f0b6dfSMatthew G. Knepley 50784f0b6dfSMatthew G. Knepley Level: intermediate 50884f0b6dfSMatthew G. Knepley 50984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelDestroy() 51084f0b6dfSMatthew G. Knepley @*/ 511c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew) 512c58f1c22SToby Isaac { 513d67d17b1SMatthew G. Knepley const char *name; 514ad8374ffSToby Isaac PetscInt v; 515c58f1c22SToby Isaac PetscErrorCode ierr; 516c58f1c22SToby Isaac 517c58f1c22SToby Isaac PetscFunctionBegin; 518d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 519c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 520d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr); 521d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PetscObjectComm((PetscObject) label), name, labelnew);CHKERRQ(ierr); 522c58f1c22SToby Isaac 523c58f1c22SToby Isaac (*labelnew)->numStrata = label->numStrata; 5245aa44df4SToby Isaac (*labelnew)->defaultValue = label->defaultValue; 525c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues);CHKERRQ(ierr); 526c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes);CHKERRQ(ierr); 527c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->ht);CHKERRQ(ierr); 528c58f1c22SToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->points);CHKERRQ(ierr); 529ad8374ffSToby Isaac ierr = PetscMalloc1(label->numStrata, &(*labelnew)->validIS);CHKERRQ(ierr); 530c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 531e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelnew)->ht[v]);CHKERRQ(ierr); 532c58f1c22SToby Isaac (*labelnew)->stratumValues[v] = label->stratumValues[v]; 533c58f1c22SToby Isaac (*labelnew)->stratumSizes[v] = label->stratumSizes[v]; 534ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) (label->points[v]));CHKERRQ(ierr); 535ad8374ffSToby Isaac (*labelnew)->points[v] = label->points[v]; 536b9907514SLisandro Dalcin (*labelnew)->validIS[v] = PETSC_TRUE; 537c58f1c22SToby Isaac } 538f14fe40dSLisandro Dalcin ierr = PetscHMapIDestroy(&(*labelnew)->hmap);CHKERRQ(ierr); 539b9907514SLisandro Dalcin ierr = PetscHMapIDuplicate(label->hmap,&(*labelnew)->hmap);CHKERRQ(ierr); 540c58f1c22SToby Isaac (*labelnew)->pStart = -1; 541c58f1c22SToby Isaac (*labelnew)->pEnd = -1; 542c58f1c22SToby Isaac (*labelnew)->bt = NULL; 543c58f1c22SToby Isaac PetscFunctionReturn(0); 544c58f1c22SToby Isaac } 545c58f1c22SToby Isaac 546c6a43d28SMatthew G. Knepley /*@ 547c6a43d28SMatthew G. Knepley DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds 548c6a43d28SMatthew G. Knepley 549*5b5e7992SMatthew G. Knepley Not collective 550*5b5e7992SMatthew G. Knepley 551c6a43d28SMatthew G. Knepley Input Parameter: 552c6a43d28SMatthew G. Knepley . label - The DMLabel 553c6a43d28SMatthew G. Knepley 554c6a43d28SMatthew G. Knepley Level: intermediate 555c6a43d28SMatthew G. Knepley 556c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 557c6a43d28SMatthew G. Knepley @*/ 558c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelComputeIndex(DMLabel label) 559c6a43d28SMatthew G. Knepley { 560c6a43d28SMatthew G. Knepley PetscInt pStart = PETSC_MAX_INT, pEnd = -1, v; 561c6a43d28SMatthew G. Knepley PetscErrorCode ierr; 562c6a43d28SMatthew G. Knepley 563c6a43d28SMatthew G. Knepley PetscFunctionBegin; 564c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 565c6a43d28SMatthew G. Knepley ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 566c6a43d28SMatthew G. Knepley for (v = 0; v < label->numStrata; ++v) { 567c6a43d28SMatthew G. Knepley const PetscInt *points; 568c6a43d28SMatthew G. Knepley PetscInt i; 569c6a43d28SMatthew G. Knepley 570c6a43d28SMatthew G. Knepley ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 571c6a43d28SMatthew G. Knepley for (i = 0; i < label->stratumSizes[v]; ++i) { 572c6a43d28SMatthew G. Knepley const PetscInt point = points[i]; 573c6a43d28SMatthew G. Knepley 574c6a43d28SMatthew G. Knepley pStart = PetscMin(point, pStart); 575c6a43d28SMatthew G. Knepley pEnd = PetscMax(point+1, pEnd); 576c6a43d28SMatthew G. Knepley } 577c6a43d28SMatthew G. Knepley ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 578c6a43d28SMatthew G. Knepley } 579c6a43d28SMatthew G. Knepley label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart; 580c6a43d28SMatthew G. Knepley label->pEnd = pEnd; 581c6a43d28SMatthew G. Knepley ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 582c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 583c6a43d28SMatthew G. Knepley } 584c6a43d28SMatthew G. Knepley 585c6a43d28SMatthew G. Knepley /*@ 586c6a43d28SMatthew G. Knepley DMLabelCreateIndex - Create an index structure for membership determination 587c6a43d28SMatthew G. Knepley 588*5b5e7992SMatthew G. Knepley Not collective 589*5b5e7992SMatthew G. Knepley 590c6a43d28SMatthew G. Knepley Input Parameters: 591c6a43d28SMatthew G. Knepley + label - The DMLabel 592c6a43d28SMatthew G. Knepley . pStart - The smallest point 593c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 594c6a43d28SMatthew G. Knepley 595c6a43d28SMatthew G. Knepley Level: intermediate 596c6a43d28SMatthew G. Knepley 597c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelComputeIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue() 598c6a43d28SMatthew G. Knepley @*/ 599c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd) 600c58f1c22SToby Isaac { 601c58f1c22SToby Isaac PetscInt v; 602c58f1c22SToby Isaac PetscErrorCode ierr; 603c58f1c22SToby Isaac 604c58f1c22SToby Isaac PetscFunctionBegin; 605d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 6060c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 607c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 608c58f1c22SToby Isaac label->pStart = pStart; 609c58f1c22SToby Isaac label->pEnd = pEnd; 610c6a43d28SMatthew G. Knepley /* This can be hooked into SetValue(), ClearValue(), etc. for updating */ 611c58f1c22SToby Isaac ierr = PetscBTCreate(pEnd - pStart, &label->bt);CHKERRQ(ierr); 612c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 613ad8374ffSToby Isaac const PetscInt *points; 614c58f1c22SToby Isaac PetscInt i; 615c58f1c22SToby Isaac 616ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 617c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 618ad8374ffSToby Isaac const PetscInt point = points[i]; 619c58f1c22SToby Isaac 620c58f1c22SToby 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); 621c58f1c22SToby Isaac ierr = PetscBTSet(label->bt, point - pStart);CHKERRQ(ierr); 622c58f1c22SToby Isaac } 623ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 624c58f1c22SToby Isaac } 625c58f1c22SToby Isaac PetscFunctionReturn(0); 626c58f1c22SToby Isaac } 627c58f1c22SToby Isaac 628c6a43d28SMatthew G. Knepley /*@ 629c6a43d28SMatthew G. Knepley DMLabelDestroyIndex - Destroy the index structure 630c6a43d28SMatthew G. Knepley 631*5b5e7992SMatthew G. Knepley Not collective 632*5b5e7992SMatthew G. Knepley 633c6a43d28SMatthew G. Knepley Input Parameter: 634c6a43d28SMatthew G. Knepley . label - the DMLabel 635c6a43d28SMatthew G. Knepley 636c6a43d28SMatthew G. Knepley Level: intermediate 637c6a43d28SMatthew G. Knepley 638c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 639c6a43d28SMatthew G. Knepley @*/ 640c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label) 641c58f1c22SToby Isaac { 642c58f1c22SToby Isaac PetscErrorCode ierr; 643c58f1c22SToby Isaac 644c58f1c22SToby Isaac PetscFunctionBegin; 645d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 646c58f1c22SToby Isaac label->pStart = -1; 647c58f1c22SToby Isaac label->pEnd = -1; 6480c3c4a36SLisandro Dalcin ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 649c58f1c22SToby Isaac PetscFunctionReturn(0); 650c58f1c22SToby Isaac } 651c58f1c22SToby Isaac 652c58f1c22SToby Isaac /*@ 653c6a43d28SMatthew G. Knepley DMLabelGetBounds - Return the smallest and largest point in the label 654c6a43d28SMatthew G. Knepley 655*5b5e7992SMatthew G. Knepley Not collective 656*5b5e7992SMatthew G. Knepley 657c6a43d28SMatthew G. Knepley Input Parameter: 658c6a43d28SMatthew G. Knepley . label - the DMLabel 659c6a43d28SMatthew G. Knepley 660c6a43d28SMatthew G. Knepley Output Parameters: 661c6a43d28SMatthew G. Knepley + pStart - The smallest point 662c6a43d28SMatthew G. Knepley - pEnd - The largest point + 1 663c6a43d28SMatthew G. Knepley 664c6a43d28SMatthew G. Knepley Note: This will compute an index for the label if one does not exist. 665c6a43d28SMatthew G. Knepley 666c6a43d28SMatthew G. Knepley Level: intermediate 667c6a43d28SMatthew G. Knepley 668c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 669c6a43d28SMatthew G. Knepley @*/ 670c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd) 671c6a43d28SMatthew G. Knepley { 672c6a43d28SMatthew G. Knepley PetscErrorCode ierr; 673c6a43d28SMatthew G. Knepley 674c6a43d28SMatthew G. Knepley PetscFunctionBegin; 675c6a43d28SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 676c6a43d28SMatthew G. Knepley if ((label->pStart == -1) && (label->pEnd == -1)) {ierr = DMLabelComputeIndex(label);CHKERRQ(ierr);} 677c6a43d28SMatthew G. Knepley if (pStart) { 678c6a43d28SMatthew G. Knepley PetscValidPointer(pStart, 2); 679c6a43d28SMatthew G. Knepley *pStart = label->pStart; 680c6a43d28SMatthew G. Knepley } 681c6a43d28SMatthew G. Knepley if (pEnd) { 682c6a43d28SMatthew G. Knepley PetscValidPointer(pEnd, 3); 683c6a43d28SMatthew G. Knepley *pEnd = label->pEnd; 684c6a43d28SMatthew G. Knepley } 685c6a43d28SMatthew G. Knepley PetscFunctionReturn(0); 686c6a43d28SMatthew G. Knepley } 687c6a43d28SMatthew G. Knepley 688c6a43d28SMatthew G. Knepley /*@ 689c58f1c22SToby Isaac DMLabelHasValue - Determine whether a label assigns the value to any point 690c58f1c22SToby Isaac 691*5b5e7992SMatthew G. Knepley Not collective 692*5b5e7992SMatthew G. Knepley 693c58f1c22SToby Isaac Input Parameters: 694c58f1c22SToby Isaac + label - the DMLabel 695c58f1c22SToby Isaac - value - the value 696c58f1c22SToby Isaac 697c58f1c22SToby Isaac Output Parameter: 698c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point 699c58f1c22SToby Isaac 700c58f1c22SToby Isaac Level: developer 701c58f1c22SToby Isaac 702c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue() 703c58f1c22SToby Isaac @*/ 704c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains) 705c58f1c22SToby Isaac { 706c58f1c22SToby Isaac PetscInt v; 7070c3c4a36SLisandro Dalcin PetscErrorCode ierr; 708c58f1c22SToby Isaac 709c58f1c22SToby Isaac PetscFunctionBegin; 710d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 711c58f1c22SToby Isaac PetscValidPointer(contains, 3); 7120c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 7130c3c4a36SLisandro Dalcin *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE; 714c58f1c22SToby Isaac PetscFunctionReturn(0); 715c58f1c22SToby Isaac } 716c58f1c22SToby Isaac 717c58f1c22SToby Isaac /*@ 718c58f1c22SToby Isaac DMLabelHasPoint - Determine whether a label assigns a value to a point 719c58f1c22SToby Isaac 720*5b5e7992SMatthew G. Knepley Not collective 721*5b5e7992SMatthew G. Knepley 722c58f1c22SToby Isaac Input Parameters: 723c58f1c22SToby Isaac + label - the DMLabel 724c58f1c22SToby Isaac - point - the point 725c58f1c22SToby Isaac 726c58f1c22SToby Isaac Output Parameter: 727c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value 728c58f1c22SToby Isaac 729c58f1c22SToby Isaac Note: The user must call DMLabelCreateIndex() before this function. 730c58f1c22SToby Isaac 731c58f1c22SToby Isaac Level: developer 732c58f1c22SToby Isaac 733c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue() 734c58f1c22SToby Isaac @*/ 735c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains) 736c58f1c22SToby Isaac { 737c58f1c22SToby Isaac PetscErrorCode ierr; 738c58f1c22SToby Isaac 739c58f1c22SToby Isaac PetscFunctionBeginHot; 740d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 741c58f1c22SToby Isaac PetscValidPointer(contains, 3); 742c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 743c58f1c22SToby Isaac #if defined(PETSC_USE_DEBUG) 744c58f1c22SToby Isaac if (!label->bt) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()"); 745c58f1c22SToby 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); 746c58f1c22SToby Isaac #endif 747c58f1c22SToby Isaac *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE; 748c58f1c22SToby Isaac PetscFunctionReturn(0); 749c58f1c22SToby Isaac } 750c58f1c22SToby Isaac 751c58f1c22SToby Isaac /*@ 752c58f1c22SToby Isaac DMLabelStratumHasPoint - Return true if the stratum contains a point 753c58f1c22SToby Isaac 754*5b5e7992SMatthew G. Knepley Not collective 755*5b5e7992SMatthew G. Knepley 756c58f1c22SToby Isaac Input Parameters: 757c58f1c22SToby Isaac + label - the DMLabel 758c58f1c22SToby Isaac . value - the stratum value 759c58f1c22SToby Isaac - point - the point 760c58f1c22SToby Isaac 761c58f1c22SToby Isaac Output Parameter: 762c58f1c22SToby Isaac . contains - true if the stratum contains the point 763c58f1c22SToby Isaac 764c58f1c22SToby Isaac Level: intermediate 765c58f1c22SToby Isaac 766c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue() 767c58f1c22SToby Isaac @*/ 768c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains) 769c58f1c22SToby Isaac { 770c58f1c22SToby Isaac PetscInt v; 771c58f1c22SToby Isaac PetscErrorCode ierr; 772c58f1c22SToby Isaac 7730c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 774d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 775c58f1c22SToby Isaac PetscValidPointer(contains, 4); 776c58f1c22SToby Isaac *contains = PETSC_FALSE; 7770c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 7780c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 7790c3c4a36SLisandro Dalcin 780ad8374ffSToby Isaac if (label->validIS[v]) { 781c58f1c22SToby Isaac PetscInt i; 782c58f1c22SToby Isaac 783a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 7840c3c4a36SLisandro Dalcin if (i >= 0) *contains = PETSC_TRUE; 785c58f1c22SToby Isaac } else { 786c58f1c22SToby Isaac PetscBool has; 787c58f1c22SToby Isaac 788b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr); 7890c3c4a36SLisandro Dalcin if (has) *contains = PETSC_TRUE; 790c58f1c22SToby Isaac } 791c58f1c22SToby Isaac PetscFunctionReturn(0); 792c58f1c22SToby Isaac } 793c58f1c22SToby Isaac 79484f0b6dfSMatthew G. Knepley /*@ 7955aa44df4SToby Isaac DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 7965aa44df4SToby Isaac When a label is created, it is initialized to -1. 7975aa44df4SToby Isaac 798*5b5e7992SMatthew G. Knepley Not collective 799*5b5e7992SMatthew G. Knepley 8005aa44df4SToby Isaac Input parameter: 8015aa44df4SToby Isaac . label - a DMLabel object 8025aa44df4SToby Isaac 8035aa44df4SToby Isaac Output parameter: 8045aa44df4SToby Isaac . defaultValue - the default value 8055aa44df4SToby Isaac 8065aa44df4SToby Isaac Level: beginner 8075aa44df4SToby Isaac 8085aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 80984f0b6dfSMatthew G. Knepley @*/ 8105aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue) 8115aa44df4SToby Isaac { 8125aa44df4SToby Isaac PetscFunctionBegin; 813d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8145aa44df4SToby Isaac *defaultValue = label->defaultValue; 8155aa44df4SToby Isaac PetscFunctionReturn(0); 8165aa44df4SToby Isaac } 8175aa44df4SToby Isaac 81884f0b6dfSMatthew G. Knepley /*@ 8195aa44df4SToby Isaac DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value. 8205aa44df4SToby Isaac When a label is created, it is initialized to -1. 8215aa44df4SToby Isaac 822*5b5e7992SMatthew G. Knepley Not collective 823*5b5e7992SMatthew G. Knepley 8245aa44df4SToby Isaac Input parameter: 8255aa44df4SToby Isaac . label - a DMLabel object 8265aa44df4SToby Isaac 8275aa44df4SToby Isaac Output parameter: 8285aa44df4SToby Isaac . defaultValue - the default value 8295aa44df4SToby Isaac 8305aa44df4SToby Isaac Level: beginner 8315aa44df4SToby Isaac 8325aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue() 83384f0b6dfSMatthew G. Knepley @*/ 8345aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue) 8355aa44df4SToby Isaac { 8365aa44df4SToby Isaac PetscFunctionBegin; 837d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 8385aa44df4SToby Isaac label->defaultValue = defaultValue; 8395aa44df4SToby Isaac PetscFunctionReturn(0); 8405aa44df4SToby Isaac } 8415aa44df4SToby Isaac 842c58f1c22SToby Isaac /*@ 8435aa44df4SToby 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()) 844c58f1c22SToby Isaac 845*5b5e7992SMatthew G. Knepley Not collective 846*5b5e7992SMatthew G. Knepley 847c58f1c22SToby Isaac Input Parameters: 848c58f1c22SToby Isaac + label - the DMLabel 849c58f1c22SToby Isaac - point - the point 850c58f1c22SToby Isaac 851c58f1c22SToby Isaac Output Parameter: 8528e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default) 853c58f1c22SToby Isaac 854c58f1c22SToby Isaac Level: intermediate 855c58f1c22SToby Isaac 8565aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 857c58f1c22SToby Isaac @*/ 858c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value) 859c58f1c22SToby Isaac { 860c58f1c22SToby Isaac PetscInt v; 861c58f1c22SToby Isaac PetscErrorCode ierr; 862c58f1c22SToby Isaac 8630c3c4a36SLisandro Dalcin PetscFunctionBeginHot; 864d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 865c58f1c22SToby Isaac PetscValidPointer(value, 3); 8665aa44df4SToby Isaac *value = label->defaultValue; 867c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 868ad8374ffSToby Isaac if (label->validIS[v]) { 869c58f1c22SToby Isaac PetscInt i; 870c58f1c22SToby Isaac 871a2d74346SToby Isaac ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr); 872c58f1c22SToby Isaac if (i >= 0) { 873c58f1c22SToby Isaac *value = label->stratumValues[v]; 874c58f1c22SToby Isaac break; 875c58f1c22SToby Isaac } 876c58f1c22SToby Isaac } else { 877c58f1c22SToby Isaac PetscBool has; 878c58f1c22SToby Isaac 879b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr); 880c58f1c22SToby Isaac if (has) { 881c58f1c22SToby Isaac *value = label->stratumValues[v]; 882c58f1c22SToby Isaac break; 883c58f1c22SToby Isaac } 884c58f1c22SToby Isaac } 885c58f1c22SToby Isaac } 886c58f1c22SToby Isaac PetscFunctionReturn(0); 887c58f1c22SToby Isaac } 888c58f1c22SToby Isaac 889c58f1c22SToby Isaac /*@ 890367003a6SStefano 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. 891c58f1c22SToby Isaac 892*5b5e7992SMatthew G. Knepley Not collective 893*5b5e7992SMatthew G. Knepley 894c58f1c22SToby Isaac Input Parameters: 895c58f1c22SToby Isaac + label - the DMLabel 896c58f1c22SToby Isaac . point - the point 897c58f1c22SToby Isaac - value - The point value 898c58f1c22SToby Isaac 899c58f1c22SToby Isaac Level: intermediate 900c58f1c22SToby Isaac 9015aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue() 902c58f1c22SToby Isaac @*/ 903c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value) 904c58f1c22SToby Isaac { 905c58f1c22SToby Isaac PetscInt v; 906c58f1c22SToby Isaac PetscErrorCode ierr; 907c58f1c22SToby Isaac 908c58f1c22SToby Isaac PetscFunctionBegin; 909d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 9100c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 9115aa44df4SToby Isaac if (value == label->defaultValue) PetscFunctionReturn(0); 912b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 913c58f1c22SToby Isaac /* Set key */ 9140c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 915e8f14785SLisandro Dalcin ierr = PetscHSetIAdd(label->ht[v], point);CHKERRQ(ierr); 916c58f1c22SToby Isaac PetscFunctionReturn(0); 917c58f1c22SToby Isaac } 918c58f1c22SToby Isaac 919c58f1c22SToby Isaac /*@ 920c58f1c22SToby Isaac DMLabelClearValue - Clear the value a label assigns to a point 921c58f1c22SToby Isaac 922*5b5e7992SMatthew G. Knepley Not collective 923*5b5e7992SMatthew G. Knepley 924c58f1c22SToby Isaac Input Parameters: 925c58f1c22SToby Isaac + label - the DMLabel 926c58f1c22SToby Isaac . point - the point 927c58f1c22SToby Isaac - value - The point value 928c58f1c22SToby Isaac 929c58f1c22SToby Isaac Level: intermediate 930c58f1c22SToby Isaac 931c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue() 932c58f1c22SToby Isaac @*/ 933c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value) 934c58f1c22SToby Isaac { 935ad8374ffSToby Isaac PetscInt v; 936c58f1c22SToby Isaac PetscErrorCode ierr; 937c58f1c22SToby Isaac 938c58f1c22SToby Isaac PetscFunctionBegin; 939d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 940c58f1c22SToby Isaac /* Find label value */ 9410c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 9420c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 9430c3c4a36SLisandro Dalcin 944eeed21e7SToby Isaac if (label->bt) { 945eeed21e7SToby 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); 946eeed21e7SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 947eeed21e7SToby Isaac } 9480c3c4a36SLisandro Dalcin 9490c3c4a36SLisandro Dalcin /* Delete key */ 9500c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 951e8f14785SLisandro Dalcin ierr = PetscHSetIDel(label->ht[v], point);CHKERRQ(ierr); 952c58f1c22SToby Isaac PetscFunctionReturn(0); 953c58f1c22SToby Isaac } 954c58f1c22SToby Isaac 955c58f1c22SToby Isaac /*@ 956c58f1c22SToby Isaac DMLabelInsertIS - Set all points in the IS to a value 957c58f1c22SToby Isaac 958*5b5e7992SMatthew G. Knepley Not collective 959*5b5e7992SMatthew G. Knepley 960c58f1c22SToby Isaac Input Parameters: 961c58f1c22SToby Isaac + label - the DMLabel 962c58f1c22SToby Isaac . is - the point IS 963c58f1c22SToby Isaac - value - The point value 964c58f1c22SToby Isaac 965c58f1c22SToby Isaac Level: intermediate 966c58f1c22SToby Isaac 967c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 968c58f1c22SToby Isaac @*/ 969c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value) 970c58f1c22SToby Isaac { 9710c3c4a36SLisandro Dalcin PetscInt v, n, p; 972c58f1c22SToby Isaac const PetscInt *points; 973c58f1c22SToby Isaac PetscErrorCode ierr; 974c58f1c22SToby Isaac 975c58f1c22SToby Isaac PetscFunctionBegin; 976d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 977c58f1c22SToby Isaac PetscValidHeaderSpecific(is, IS_CLASSID, 2); 9780c3c4a36SLisandro Dalcin /* Find label value, add new entry if needed */ 9790c3c4a36SLisandro Dalcin if (value == label->defaultValue) PetscFunctionReturn(0); 980b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 9810c3c4a36SLisandro Dalcin /* Set keys */ 9820c3c4a36SLisandro Dalcin ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr); 983c58f1c22SToby Isaac ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 984c58f1c22SToby Isaac ierr = ISGetIndices(is, &points);CHKERRQ(ierr); 985e8f14785SLisandro Dalcin for (p = 0; p < n; ++p) {ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);} 986c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &points);CHKERRQ(ierr); 987c58f1c22SToby Isaac PetscFunctionReturn(0); 988c58f1c22SToby Isaac } 989c58f1c22SToby Isaac 99084f0b6dfSMatthew G. Knepley /*@ 99184f0b6dfSMatthew G. Knepley DMLabelGetNumValues - Get the number of values that the DMLabel takes 99284f0b6dfSMatthew G. Knepley 993*5b5e7992SMatthew G. Knepley Not collective 994*5b5e7992SMatthew G. Knepley 99584f0b6dfSMatthew G. Knepley Input Parameter: 99684f0b6dfSMatthew G. Knepley . label - the DMLabel 99784f0b6dfSMatthew G. Knepley 99884f0b6dfSMatthew G. Knepley Output Paramater: 99984f0b6dfSMatthew G. Knepley . numValues - the number of values 100084f0b6dfSMatthew G. Knepley 100184f0b6dfSMatthew G. Knepley Level: intermediate 100284f0b6dfSMatthew G. Knepley 100384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 100484f0b6dfSMatthew G. Knepley @*/ 1005c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues) 1006c58f1c22SToby Isaac { 1007c58f1c22SToby Isaac PetscFunctionBegin; 1008d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1009c58f1c22SToby Isaac PetscValidPointer(numValues, 2); 1010c58f1c22SToby Isaac *numValues = label->numStrata; 1011c58f1c22SToby Isaac PetscFunctionReturn(0); 1012c58f1c22SToby Isaac } 1013c58f1c22SToby Isaac 101484f0b6dfSMatthew G. Knepley /*@ 101584f0b6dfSMatthew G. Knepley DMLabelGetValueIS - Get an IS of all values that the DMlabel takes 101684f0b6dfSMatthew G. Knepley 1017*5b5e7992SMatthew G. Knepley Not collective 1018*5b5e7992SMatthew G. Knepley 101984f0b6dfSMatthew G. Knepley Input Parameter: 102084f0b6dfSMatthew G. Knepley . label - the DMLabel 102184f0b6dfSMatthew G. Knepley 102284f0b6dfSMatthew G. Knepley Output Paramater: 102384f0b6dfSMatthew G. Knepley . is - the value IS 102484f0b6dfSMatthew G. Knepley 102584f0b6dfSMatthew G. Knepley Level: intermediate 102684f0b6dfSMatthew G. Knepley 102784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 102884f0b6dfSMatthew G. Knepley @*/ 1029c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values) 1030c58f1c22SToby Isaac { 1031c58f1c22SToby Isaac PetscErrorCode ierr; 1032c58f1c22SToby Isaac 1033c58f1c22SToby Isaac PetscFunctionBegin; 1034d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1035c58f1c22SToby Isaac PetscValidPointer(values, 2); 1036c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr); 1037c58f1c22SToby Isaac PetscFunctionReturn(0); 1038c58f1c22SToby Isaac } 1039c58f1c22SToby Isaac 104084f0b6dfSMatthew G. Knepley /*@ 104184f0b6dfSMatthew G. Knepley DMLabelHasStratum - Determine whether points exist with the given value 104284f0b6dfSMatthew G. Knepley 1043*5b5e7992SMatthew G. Knepley Not collective 1044*5b5e7992SMatthew G. Knepley 104584f0b6dfSMatthew G. Knepley Input Parameters: 104684f0b6dfSMatthew G. Knepley + label - the DMLabel 104784f0b6dfSMatthew G. Knepley - value - the stratum value 104884f0b6dfSMatthew G. Knepley 104984f0b6dfSMatthew G. Knepley Output Paramater: 105084f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist 105184f0b6dfSMatthew G. Knepley 105284f0b6dfSMatthew G. Knepley Level: intermediate 105384f0b6dfSMatthew G. Knepley 105484f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 105584f0b6dfSMatthew G. Knepley @*/ 1056fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists) 1057fada774cSMatthew G. Knepley { 1058fada774cSMatthew G. Knepley PetscInt v; 10590c3c4a36SLisandro Dalcin PetscErrorCode ierr; 1060fada774cSMatthew G. Knepley 1061fada774cSMatthew G. Knepley PetscFunctionBegin; 1062d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1063fada774cSMatthew G. Knepley PetscValidPointer(exists, 3); 10640c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 10650c3c4a36SLisandro Dalcin *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE; 1066fada774cSMatthew G. Knepley PetscFunctionReturn(0); 1067fada774cSMatthew G. Knepley } 1068fada774cSMatthew G. Knepley 106984f0b6dfSMatthew G. Knepley /*@ 107084f0b6dfSMatthew G. Knepley DMLabelGetStratumSize - Get the size of a stratum 107184f0b6dfSMatthew G. Knepley 1072*5b5e7992SMatthew G. Knepley Not collective 1073*5b5e7992SMatthew G. Knepley 107484f0b6dfSMatthew G. Knepley Input Parameters: 107584f0b6dfSMatthew G. Knepley + label - the DMLabel 107684f0b6dfSMatthew G. Knepley - value - the stratum value 107784f0b6dfSMatthew G. Knepley 107884f0b6dfSMatthew G. Knepley Output Paramater: 107984f0b6dfSMatthew G. Knepley . size - The number of points in the stratum 108084f0b6dfSMatthew G. Knepley 108184f0b6dfSMatthew G. Knepley Level: intermediate 108284f0b6dfSMatthew G. Knepley 108384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 108484f0b6dfSMatthew G. Knepley @*/ 1085c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size) 1086c58f1c22SToby Isaac { 1087c58f1c22SToby Isaac PetscInt v; 1088c58f1c22SToby Isaac PetscErrorCode ierr; 1089c58f1c22SToby Isaac 1090c58f1c22SToby Isaac PetscFunctionBegin; 1091d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1092c58f1c22SToby Isaac PetscValidPointer(size, 3); 1093c58f1c22SToby Isaac *size = 0; 10940c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 10950c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1096c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 1097c58f1c22SToby Isaac *size = label->stratumSizes[v]; 1098c58f1c22SToby Isaac PetscFunctionReturn(0); 1099c58f1c22SToby Isaac } 1100c58f1c22SToby Isaac 110184f0b6dfSMatthew G. Knepley /*@ 110284f0b6dfSMatthew G. Knepley DMLabelGetStratumBounds - Get the largest and smallest point of a stratum 110384f0b6dfSMatthew G. Knepley 1104*5b5e7992SMatthew G. Knepley Not collective 1105*5b5e7992SMatthew G. Knepley 110684f0b6dfSMatthew G. Knepley Input Parameters: 110784f0b6dfSMatthew G. Knepley + label - the DMLabel 110884f0b6dfSMatthew G. Knepley - value - the stratum value 110984f0b6dfSMatthew G. Knepley 111084f0b6dfSMatthew G. Knepley Output Paramaters: 111184f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum 111284f0b6dfSMatthew G. Knepley - end - the largest point in the stratum 111384f0b6dfSMatthew G. Knepley 111484f0b6dfSMatthew G. Knepley Level: intermediate 111584f0b6dfSMatthew G. Knepley 111684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 111784f0b6dfSMatthew G. Knepley @*/ 1118c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end) 1119c58f1c22SToby Isaac { 11200c3c4a36SLisandro Dalcin PetscInt v, min, max; 1121c58f1c22SToby Isaac PetscErrorCode ierr; 1122c58f1c22SToby Isaac 1123c58f1c22SToby Isaac PetscFunctionBegin; 1124d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1125c58f1c22SToby Isaac if (start) {PetscValidPointer(start, 3); *start = 0;} 1126c58f1c22SToby Isaac if (end) {PetscValidPointer(end, 4); *end = 0;} 11270c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 11280c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1129c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 11300c3c4a36SLisandro Dalcin if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0); 1131d6cb179aSToby Isaac ierr = ISGetMinMax(label->points[v], &min, &max);CHKERRQ(ierr); 1132d6cb179aSToby Isaac if (start) *start = min; 1133d6cb179aSToby Isaac if (end) *end = max+1; 1134c58f1c22SToby Isaac PetscFunctionReturn(0); 1135c58f1c22SToby Isaac } 1136c58f1c22SToby Isaac 113784f0b6dfSMatthew G. Knepley /*@ 113884f0b6dfSMatthew G. Knepley DMLabelGetStratumIS - Get an IS with the stratum points 113984f0b6dfSMatthew G. Knepley 1140*5b5e7992SMatthew G. Knepley Not collective 1141*5b5e7992SMatthew G. Knepley 114284f0b6dfSMatthew G. Knepley Input Parameters: 114384f0b6dfSMatthew G. Knepley + label - the DMLabel 114484f0b6dfSMatthew G. Knepley - value - the stratum value 114584f0b6dfSMatthew G. Knepley 114684f0b6dfSMatthew G. Knepley Output Paramater: 114784f0b6dfSMatthew G. Knepley . points - The stratum points 114884f0b6dfSMatthew G. Knepley 114984f0b6dfSMatthew G. Knepley Level: intermediate 115084f0b6dfSMatthew G. Knepley 115184f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 115284f0b6dfSMatthew G. Knepley @*/ 1153c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points) 1154c58f1c22SToby Isaac { 1155c58f1c22SToby Isaac PetscInt v; 1156c58f1c22SToby Isaac PetscErrorCode ierr; 1157c58f1c22SToby Isaac 1158c58f1c22SToby Isaac PetscFunctionBegin; 1159d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1160c58f1c22SToby Isaac PetscValidPointer(points, 3); 1161c58f1c22SToby Isaac *points = NULL; 11620c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 11630c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 1164c58f1c22SToby Isaac ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr); 1165ad8374ffSToby Isaac ierr = PetscObjectReference((PetscObject) label->points[v]);CHKERRQ(ierr); 1166ad8374ffSToby Isaac *points = label->points[v]; 1167c58f1c22SToby Isaac PetscFunctionReturn(0); 1168c58f1c22SToby Isaac } 1169c58f1c22SToby Isaac 117084f0b6dfSMatthew G. Knepley /*@ 117184f0b6dfSMatthew G. Knepley DMLabelSetStratumIS - Set the stratum points using an IS 117284f0b6dfSMatthew G. Knepley 1173*5b5e7992SMatthew G. Knepley Not collective 1174*5b5e7992SMatthew G. Knepley 117584f0b6dfSMatthew G. Knepley Input Parameters: 117684f0b6dfSMatthew G. Knepley + label - the DMLabel 117784f0b6dfSMatthew G. Knepley . value - the stratum value 117884f0b6dfSMatthew G. Knepley - points - The stratum points 117984f0b6dfSMatthew G. Knepley 118084f0b6dfSMatthew G. Knepley Level: intermediate 118184f0b6dfSMatthew G. Knepley 118284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 118384f0b6dfSMatthew G. Knepley @*/ 11844de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is) 11854de306b1SToby Isaac { 11860c3c4a36SLisandro Dalcin PetscInt v; 11874de306b1SToby Isaac PetscErrorCode ierr; 11884de306b1SToby Isaac 11894de306b1SToby Isaac PetscFunctionBegin; 1190d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1191d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(is, IS_CLASSID, 3); 1192b9907514SLisandro Dalcin ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr); 11934de306b1SToby Isaac if (is == label->points[v]) PetscFunctionReturn(0); 11944de306b1SToby Isaac ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr); 11954de306b1SToby Isaac ierr = ISGetLocalSize(is, &(label->stratumSizes[v]));CHKERRQ(ierr); 11964de306b1SToby Isaac ierr = PetscObjectReference((PetscObject)is);CHKERRQ(ierr); 11974de306b1SToby Isaac ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr); 11980c3c4a36SLisandro Dalcin label->points[v] = is; 11990c3c4a36SLisandro Dalcin label->validIS[v] = PETSC_TRUE; 1200277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 12014de306b1SToby Isaac if (label->bt) { 12024de306b1SToby Isaac const PetscInt *points; 12034de306b1SToby Isaac PetscInt p; 12044de306b1SToby Isaac 12054de306b1SToby Isaac ierr = ISGetIndices(is,&points);CHKERRQ(ierr); 12064de306b1SToby Isaac for (p = 0; p < label->stratumSizes[v]; ++p) { 12074de306b1SToby Isaac const PetscInt point = points[p]; 12084de306b1SToby Isaac 12094de306b1SToby 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); 12104de306b1SToby Isaac ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr); 12114de306b1SToby Isaac } 12124de306b1SToby Isaac } 12134de306b1SToby Isaac PetscFunctionReturn(0); 12144de306b1SToby Isaac } 12154de306b1SToby Isaac 121684f0b6dfSMatthew G. Knepley /*@ 121784f0b6dfSMatthew G. Knepley DMLabelClearStratum - Remove a stratum 12184de306b1SToby Isaac 1219*5b5e7992SMatthew G. Knepley Not collective 1220*5b5e7992SMatthew G. Knepley 122184f0b6dfSMatthew G. Knepley Input Parameters: 122284f0b6dfSMatthew G. Knepley + label - the DMLabel 122384f0b6dfSMatthew G. Knepley - value - the stratum value 122484f0b6dfSMatthew G. Knepley 122584f0b6dfSMatthew G. Knepley Level: intermediate 122684f0b6dfSMatthew G. Knepley 122784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 122884f0b6dfSMatthew G. Knepley @*/ 1229c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value) 1230c58f1c22SToby Isaac { 1231c58f1c22SToby Isaac PetscInt v; 1232c58f1c22SToby Isaac PetscErrorCode ierr; 1233c58f1c22SToby Isaac 1234c58f1c22SToby Isaac PetscFunctionBegin; 1235d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12360c3c4a36SLisandro Dalcin ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr); 12370c3c4a36SLisandro Dalcin if (v < 0) PetscFunctionReturn(0); 12384de306b1SToby Isaac if (label->validIS[v]) { 12394de306b1SToby Isaac if (label->bt) { 1240c58f1c22SToby Isaac PetscInt i; 1241ad8374ffSToby Isaac const PetscInt *points; 1242c58f1c22SToby Isaac 1243ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 1244c58f1c22SToby Isaac for (i = 0; i < label->stratumSizes[v]; ++i) { 1245ad8374ffSToby Isaac const PetscInt point = points[i]; 1246c58f1c22SToby Isaac 1247c58f1c22SToby 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); 1248c58f1c22SToby Isaac ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr); 1249c58f1c22SToby Isaac } 1250ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr); 1251c58f1c22SToby Isaac } 1252c58f1c22SToby Isaac label->stratumSizes[v] = 0; 12530c3c4a36SLisandro Dalcin ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 1254277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v]);CHKERRQ(ierr); 12550c3c4a36SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr); 1256277ea44aSLisandro Dalcin ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr); 1257c58f1c22SToby Isaac } else { 1258b9907514SLisandro Dalcin ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr); 1259c58f1c22SToby Isaac } 1260c58f1c22SToby Isaac PetscFunctionReturn(0); 1261c58f1c22SToby Isaac } 1262c58f1c22SToby Isaac 126384f0b6dfSMatthew G. Knepley /*@ 126484f0b6dfSMatthew G. Knepley DMLabelFilter - Remove all points outside of [start, end) 126584f0b6dfSMatthew G. Knepley 1266*5b5e7992SMatthew G. Knepley Not collective 1267*5b5e7992SMatthew G. Knepley 126884f0b6dfSMatthew G. Knepley Input Parameters: 126984f0b6dfSMatthew G. Knepley + label - the DMLabel 127084f0b6dfSMatthew G. Knepley . start - the first point 127184f0b6dfSMatthew G. Knepley - end - the last point 127284f0b6dfSMatthew G. Knepley 127384f0b6dfSMatthew G. Knepley Level: intermediate 127484f0b6dfSMatthew G. Knepley 127584f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 127684f0b6dfSMatthew G. Knepley @*/ 1277c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end) 1278c58f1c22SToby Isaac { 1279c58f1c22SToby Isaac PetscInt v; 1280c58f1c22SToby Isaac PetscErrorCode ierr; 1281c58f1c22SToby Isaac 1282c58f1c22SToby Isaac PetscFunctionBegin; 1283d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 12840c3c4a36SLisandro Dalcin ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr); 1285c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1286c58f1c22SToby Isaac for (v = 0; v < label->numStrata; ++v) { 1287c58f1c22SToby Isaac PetscInt off, q; 1288ad8374ffSToby Isaac const PetscInt *points; 1289033405d5SLisandro Dalcin PetscInt numPointsNew = 0, *pointsNew = NULL; 1290c58f1c22SToby Isaac 1291ad8374ffSToby Isaac ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr); 1292033405d5SLisandro Dalcin for (q = 0; q < label->stratumSizes[v]; ++q) 1293033405d5SLisandro Dalcin if (points[q] >= start && points[q] < end) 1294033405d5SLisandro Dalcin numPointsNew++; 1295033405d5SLisandro Dalcin ierr = PetscMalloc1(numPointsNew, &pointsNew);CHKERRQ(ierr); 1296c58f1c22SToby Isaac for (off = 0, q = 0; q < label->stratumSizes[v]; ++q) { 1297033405d5SLisandro Dalcin if (points[q] >= start && points[q] < end) 1298033405d5SLisandro Dalcin pointsNew[off++] = points[q]; 1299ad8374ffSToby Isaac } 1300ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr); 1301033405d5SLisandro Dalcin 1302033405d5SLisandro Dalcin label->stratumSizes[v] = numPointsNew; 1303033405d5SLisandro Dalcin ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr); 1304033405d5SLisandro Dalcin ierr = ISCreateGeneral(PETSC_COMM_SELF,numPointsNew, pointsNew, PETSC_OWN_POINTER, &label->points[v]);CHKERRQ(ierr); 1305033405d5SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr); 1306c58f1c22SToby Isaac } 1307c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, start, end);CHKERRQ(ierr); 1308c58f1c22SToby Isaac PetscFunctionReturn(0); 1309c58f1c22SToby Isaac } 1310c58f1c22SToby Isaac 131184f0b6dfSMatthew G. Knepley /*@ 131284f0b6dfSMatthew G. Knepley DMLabelPermute - Create a new label with permuted points 131384f0b6dfSMatthew G. Knepley 1314*5b5e7992SMatthew G. Knepley Not collective 1315*5b5e7992SMatthew G. Knepley 131684f0b6dfSMatthew G. Knepley Input Parameters: 131784f0b6dfSMatthew G. Knepley + label - the DMLabel 131884f0b6dfSMatthew G. Knepley - permutation - the point permutation 131984f0b6dfSMatthew G. Knepley 132084f0b6dfSMatthew G. Knepley Output Parameter: 132184f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points 132284f0b6dfSMatthew G. Knepley 132384f0b6dfSMatthew G. Knepley Level: intermediate 132484f0b6dfSMatthew G. Knepley 132584f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 132684f0b6dfSMatthew G. Knepley @*/ 1327c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew) 1328c58f1c22SToby Isaac { 1329c58f1c22SToby Isaac const PetscInt *perm; 1330c58f1c22SToby Isaac PetscInt numValues, numPoints, v, q; 1331c58f1c22SToby Isaac PetscErrorCode ierr; 1332c58f1c22SToby Isaac 1333c58f1c22SToby Isaac PetscFunctionBegin; 1334d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1335d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(permutation, IS_CLASSID, 2); 1336c58f1c22SToby Isaac ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1337c58f1c22SToby Isaac ierr = DMLabelDuplicate(label, labelNew);CHKERRQ(ierr); 1338c58f1c22SToby Isaac ierr = DMLabelGetNumValues(*labelNew, &numValues);CHKERRQ(ierr); 1339c58f1c22SToby Isaac ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr); 1340c58f1c22SToby Isaac ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr); 1341c58f1c22SToby Isaac for (v = 0; v < numValues; ++v) { 1342c58f1c22SToby Isaac const PetscInt size = (*labelNew)->stratumSizes[v]; 1343ad8374ffSToby Isaac const PetscInt *points; 1344ad8374ffSToby Isaac PetscInt *pointsNew; 1345c58f1c22SToby Isaac 1346ad8374ffSToby Isaac ierr = ISGetIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1347ad8374ffSToby Isaac ierr = PetscMalloc1(size,&pointsNew);CHKERRQ(ierr); 1348c58f1c22SToby Isaac for (q = 0; q < size; ++q) { 1349ad8374ffSToby Isaac const PetscInt point = points[q]; 1350c58f1c22SToby Isaac 1351c58f1c22SToby 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); 1352ad8374ffSToby Isaac pointsNew[q] = perm[point]; 1353c58f1c22SToby Isaac } 1354ad8374ffSToby Isaac ierr = ISRestoreIndices((*labelNew)->points[v],&points);CHKERRQ(ierr); 1355ad8374ffSToby Isaac ierr = PetscSortInt(size, pointsNew);CHKERRQ(ierr); 1356ad8374ffSToby Isaac ierr = ISDestroy(&((*labelNew)->points[v]));CHKERRQ(ierr); 1357fa8e8ae5SToby Isaac if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) { 1358fa8e8ae5SToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]));CHKERRQ(ierr); 1359fa8e8ae5SToby Isaac ierr = PetscFree(pointsNew);CHKERRQ(ierr); 1360fa8e8ae5SToby Isaac } else { 1361ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]));CHKERRQ(ierr); 1362fa8e8ae5SToby Isaac } 1363ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices");CHKERRQ(ierr); 1364c58f1c22SToby Isaac } 1365c58f1c22SToby Isaac ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr); 1366c58f1c22SToby Isaac if (label->bt) { 1367c58f1c22SToby Isaac ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr); 1368c58f1c22SToby Isaac ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr); 1369c58f1c22SToby Isaac } 1370c58f1c22SToby Isaac PetscFunctionReturn(0); 1371c58f1c22SToby Isaac } 1372c58f1c22SToby Isaac 137326c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata) 137426c55118SMichael Lange { 137526c55118SMichael Lange MPI_Comm comm; 137626c55118SMichael Lange PetscInt s, l, nroots, nleaves, dof, offset, size; 137726c55118SMichael Lange PetscInt *remoteOffsets, *rootStrata, *rootIdx; 137826c55118SMichael Lange PetscSection rootSection; 137926c55118SMichael Lange PetscSF labelSF; 138026c55118SMichael Lange PetscErrorCode ierr; 138126c55118SMichael Lange 138226c55118SMichael Lange PetscFunctionBegin; 138326c55118SMichael Lange if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);} 138426c55118SMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 138526c55118SMichael Lange /* Build a section of stratum values per point, generate the according SF 138626c55118SMichael Lange and distribute point-wise stratum values to leaves. */ 138726c55118SMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL);CHKERRQ(ierr); 138826c55118SMichael Lange ierr = PetscSectionCreate(comm, &rootSection);CHKERRQ(ierr); 138926c55118SMichael Lange ierr = PetscSectionSetChart(rootSection, 0, nroots);CHKERRQ(ierr); 139026c55118SMichael Lange if (label) { 139126c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1392ad8374ffSToby Isaac const PetscInt *points; 1393ad8374ffSToby Isaac 1394ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 139526c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1396ad8374ffSToby Isaac ierr = PetscSectionGetDof(rootSection, points[l], &dof);CHKERRQ(ierr); 1397ad8374ffSToby Isaac ierr = PetscSectionSetDof(rootSection, points[l], dof+1);CHKERRQ(ierr); 139826c55118SMichael Lange } 1399ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 140026c55118SMichael Lange } 140126c55118SMichael Lange } 140226c55118SMichael Lange ierr = PetscSectionSetUp(rootSection);CHKERRQ(ierr); 140326c55118SMichael Lange /* Create a point-wise array of stratum values */ 140426c55118SMichael Lange ierr = PetscSectionGetStorageSize(rootSection, &size);CHKERRQ(ierr); 140526c55118SMichael Lange ierr = PetscMalloc1(size, &rootStrata);CHKERRQ(ierr); 140626c55118SMichael Lange ierr = PetscCalloc1(nroots, &rootIdx);CHKERRQ(ierr); 140726c55118SMichael Lange if (label) { 140826c55118SMichael Lange for (s = 0; s < label->numStrata; ++s) { 1409ad8374ffSToby Isaac const PetscInt *points; 1410ad8374ffSToby Isaac 1411ad8374ffSToby Isaac ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr); 141226c55118SMichael Lange for (l = 0; l < label->stratumSizes[s]; l++) { 1413ad8374ffSToby Isaac const PetscInt p = points[l]; 141426c55118SMichael Lange ierr = PetscSectionGetOffset(rootSection, p, &offset);CHKERRQ(ierr); 141526c55118SMichael Lange rootStrata[offset+rootIdx[p]++] = label->stratumValues[s]; 141626c55118SMichael Lange } 1417ad8374ffSToby Isaac ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr); 141826c55118SMichael Lange } 141926c55118SMichael Lange } 142026c55118SMichael Lange /* Build SF that maps label points to remote processes */ 142126c55118SMichael Lange ierr = PetscSectionCreate(comm, leafSection);CHKERRQ(ierr); 142226c55118SMichael Lange ierr = PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection);CHKERRQ(ierr); 142326c55118SMichael Lange ierr = PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF);CHKERRQ(ierr); 142426c55118SMichael Lange ierr = PetscFree(remoteOffsets);CHKERRQ(ierr); 142526c55118SMichael Lange /* Send the strata for each point over the derived SF */ 142626c55118SMichael Lange ierr = PetscSectionGetStorageSize(*leafSection, &size);CHKERRQ(ierr); 142726c55118SMichael Lange ierr = PetscMalloc1(size, leafStrata);CHKERRQ(ierr); 142826c55118SMichael Lange ierr = PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr); 142926c55118SMichael Lange ierr = PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr); 143026c55118SMichael Lange /* Clean up */ 143126c55118SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 143226c55118SMichael Lange ierr = PetscFree(rootIdx);CHKERRQ(ierr); 143326c55118SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 143426c55118SMichael Lange ierr = PetscSFDestroy(&labelSF);CHKERRQ(ierr); 143526c55118SMichael Lange PetscFunctionReturn(0); 143626c55118SMichael Lange } 143726c55118SMichael Lange 143884f0b6dfSMatthew G. Knepley /*@ 143984f0b6dfSMatthew G. Knepley DMLabelDistribute - Create a new label pushed forward over the PetscSF 144084f0b6dfSMatthew G. Knepley 1441*5b5e7992SMatthew G. Knepley Collective on sf 1442*5b5e7992SMatthew G. Knepley 144384f0b6dfSMatthew G. Knepley Input Parameters: 144484f0b6dfSMatthew G. Knepley + label - the DMLabel 144584f0b6dfSMatthew G. Knepley - sf - the map from old to new distribution 144684f0b6dfSMatthew G. Knepley 144784f0b6dfSMatthew G. Knepley Output Parameter: 144884f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label 144984f0b6dfSMatthew G. Knepley 145084f0b6dfSMatthew G. Knepley Level: intermediate 145184f0b6dfSMatthew G. Knepley 145284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue() 145384f0b6dfSMatthew G. Knepley @*/ 1454c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew) 1455c58f1c22SToby Isaac { 1456c58f1c22SToby Isaac MPI_Comm comm; 145726c55118SMichael Lange PetscSection leafSection; 145826c55118SMichael Lange PetscInt p, pStart, pEnd, s, size, dof, offset, stratum; 145926c55118SMichael Lange PetscInt *leafStrata, *strataIdx; 1460ad8374ffSToby Isaac PetscInt **points; 1461d67d17b1SMatthew G. Knepley const char *lname = NULL; 1462c58f1c22SToby Isaac char *name; 1463c58f1c22SToby Isaac PetscInt nameSize; 1464e8f14785SLisandro Dalcin PetscHSetI stratumHash; 1465c58f1c22SToby Isaac size_t len = 0; 146626c55118SMichael Lange PetscMPIInt rank; 1467c58f1c22SToby Isaac PetscErrorCode ierr; 1468c58f1c22SToby Isaac 1469c58f1c22SToby Isaac PetscFunctionBegin; 1470d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1471f018e600SMatthew G. Knepley if (label) { 1472f018e600SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1473f018e600SMatthew G. Knepley ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr); 1474f018e600SMatthew G. Knepley } 1475c58f1c22SToby Isaac ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 1476c58f1c22SToby Isaac ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1477c58f1c22SToby Isaac /* Bcast name */ 1478d67d17b1SMatthew G. Knepley if (!rank) { 1479d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 1480d67d17b1SMatthew G. Knepley ierr = PetscStrlen(lname, &len);CHKERRQ(ierr); 1481d67d17b1SMatthew G. Knepley } 1482c58f1c22SToby Isaac nameSize = len; 1483c58f1c22SToby Isaac ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1484c58f1c22SToby Isaac ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1485d67d17b1SMatthew G. Knepley if (!rank) {ierr = PetscMemcpy(name, lname, nameSize+1);CHKERRQ(ierr);} 1486c58f1c22SToby Isaac ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 1487d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr); 1488c58f1c22SToby Isaac ierr = PetscFree(name);CHKERRQ(ierr); 148977d236dfSMichael Lange /* Bcast defaultValue */ 149077d236dfSMichael Lange if (!rank) (*labelNew)->defaultValue = label->defaultValue; 149177d236dfSMichael Lange ierr = MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 149226c55118SMichael Lange /* Distribute stratum values over the SF and get the point mapping on the receiver */ 149326c55118SMichael Lange ierr = DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata);CHKERRQ(ierr); 14945cbdf6fcSMichael Lange /* Determine received stratum values and initialise new label*/ 1495e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&stratumHash);CHKERRQ(ierr); 149626c55118SMichael Lange ierr = PetscSectionGetStorageSize(leafSection, &size);CHKERRQ(ierr); 1497e8f14785SLisandro Dalcin for (p = 0; p < size; ++p) {ierr = PetscHSetIAdd(stratumHash, leafStrata[p]);CHKERRQ(ierr);} 1498e8f14785SLisandro Dalcin ierr = PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata);CHKERRQ(ierr); 1499ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS);CHKERRQ(ierr); 1500ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE; 15015cbdf6fcSMichael Lange ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues);CHKERRQ(ierr); 15025cbdf6fcSMichael Lange /* Turn leafStrata into indices rather than stratum values */ 15035cbdf6fcSMichael Lange offset = 0; 1504e8f14785SLisandro Dalcin ierr = PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues);CHKERRQ(ierr); 1505a205f1fdSToby Isaac ierr = PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues);CHKERRQ(ierr); 150690e9b2aeSLisandro Dalcin for (s = 0; s < (*labelNew)->numStrata; ++s) { 150790e9b2aeSLisandro Dalcin ierr = PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s);CHKERRQ(ierr); 150890e9b2aeSLisandro Dalcin } 15095cbdf6fcSMichael Lange for (p = 0; p < size; ++p) { 1510231b9e6fSMatthew G. Knepley for (s = 0; s < (*labelNew)->numStrata; ++s) { 1511231b9e6fSMatthew G. Knepley if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;} 15125cbdf6fcSMichael Lange } 15135cbdf6fcSMichael Lange } 1514c58f1c22SToby Isaac /* Rebuild the point strata on the receiver */ 1515c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes);CHKERRQ(ierr); 1516c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1517c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1518c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1519c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1520c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1521c58f1c22SToby Isaac (*labelNew)->stratumSizes[leafStrata[offset+s]]++; 1522c58f1c22SToby Isaac } 1523c58f1c22SToby Isaac } 1524c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht);CHKERRQ(ierr); 1525c58f1c22SToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points);CHKERRQ(ierr); 1526ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->numStrata,&points);CHKERRQ(ierr); 1527c58f1c22SToby Isaac for (s = 0; s < (*labelNew)->numStrata; ++s) { 1528e8f14785SLisandro Dalcin ierr = PetscHSetICreate(&(*labelNew)->ht[s]);CHKERRQ(ierr); 1529ad8374ffSToby Isaac ierr = PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]));CHKERRQ(ierr); 1530c58f1c22SToby Isaac } 1531c58f1c22SToby Isaac /* Insert points into new strata */ 1532c58f1c22SToby Isaac ierr = PetscCalloc1((*labelNew)->numStrata, &strataIdx);CHKERRQ(ierr); 1533c58f1c22SToby Isaac ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr); 1534c58f1c22SToby Isaac for (p=pStart; p<pEnd; p++) { 1535c58f1c22SToby Isaac ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr); 1536c58f1c22SToby Isaac ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr); 1537c58f1c22SToby Isaac for (s=0; s<dof; s++) { 1538c58f1c22SToby Isaac stratum = leafStrata[offset+s]; 1539ad8374ffSToby Isaac points[stratum][strataIdx[stratum]++] = p; 1540c58f1c22SToby Isaac } 1541c58f1c22SToby Isaac } 1542ad8374ffSToby Isaac for (s = 0; s < (*labelNew)->numStrata; s++) { 1543ad8374ffSToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]));CHKERRQ(ierr); 1544ad8374ffSToby Isaac ierr = PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices");CHKERRQ(ierr); 1545ad8374ffSToby Isaac } 1546ad8374ffSToby Isaac ierr = PetscFree(points);CHKERRQ(ierr); 1547e8f14785SLisandro Dalcin ierr = PetscHSetIDestroy(&stratumHash);CHKERRQ(ierr); 1548c58f1c22SToby Isaac ierr = PetscFree(leafStrata);CHKERRQ(ierr); 1549c58f1c22SToby Isaac ierr = PetscFree(strataIdx);CHKERRQ(ierr); 1550c58f1c22SToby Isaac ierr = PetscSectionDestroy(&leafSection);CHKERRQ(ierr); 1551c58f1c22SToby Isaac PetscFunctionReturn(0); 1552c58f1c22SToby Isaac } 1553c58f1c22SToby Isaac 15547937d9ceSMichael Lange /*@ 15557937d9ceSMichael Lange DMLabelGather - Gather all label values from leafs into roots 15567937d9ceSMichael Lange 1557*5b5e7992SMatthew G. Knepley Collective on sf 1558*5b5e7992SMatthew G. Knepley 15597937d9ceSMichael Lange Input Parameters: 15607937d9ceSMichael Lange + label - the DMLabel 156184f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map 15627937d9ceSMichael Lange 156384f0b6dfSMatthew G. Knepley Output Parameters: 156484f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values 15657937d9ceSMichael Lange 15667937d9ceSMichael Lange Level: developer 15677937d9ceSMichael Lange 15687937d9ceSMichael Lange Note: This is the inverse operation to DMLabelDistribute. 15697937d9ceSMichael Lange 15707937d9ceSMichael Lange .seealso: DMLabelDistribute() 15717937d9ceSMichael Lange @*/ 15727937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew) 15737937d9ceSMichael Lange { 15747937d9ceSMichael Lange MPI_Comm comm; 15757937d9ceSMichael Lange PetscSection rootSection; 15767937d9ceSMichael Lange PetscSF sfLabel; 15777937d9ceSMichael Lange PetscSFNode *rootPoints, *leafPoints; 15787937d9ceSMichael Lange PetscInt p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset; 15797937d9ceSMichael Lange const PetscInt *rootDegree, *ilocal; 15807937d9ceSMichael Lange PetscInt *rootStrata; 1581d67d17b1SMatthew G. Knepley const char *lname; 15827937d9ceSMichael Lange char *name; 15837937d9ceSMichael Lange PetscInt nameSize; 15847937d9ceSMichael Lange size_t len = 0; 15859852e123SBarry Smith PetscMPIInt rank, size; 15867937d9ceSMichael Lange PetscErrorCode ierr; 15877937d9ceSMichael Lange 15887937d9ceSMichael Lange PetscFunctionBegin; 1589d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1590d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 15917937d9ceSMichael Lange ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr); 15927937d9ceSMichael Lange ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 15939852e123SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 15947937d9ceSMichael Lange /* Bcast name */ 1595d67d17b1SMatthew G. Knepley if (!rank) { 1596d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr); 1597d67d17b1SMatthew G. Knepley ierr = PetscStrlen(lname, &len);CHKERRQ(ierr); 1598d67d17b1SMatthew G. Knepley } 15997937d9ceSMichael Lange nameSize = len; 16007937d9ceSMichael Lange ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 16017937d9ceSMichael Lange ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr); 1602d67d17b1SMatthew G. Knepley if (!rank) {ierr = PetscMemcpy(name, lname, nameSize+1);CHKERRQ(ierr);} 16037937d9ceSMichael Lange ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 1604d67d17b1SMatthew G. Knepley ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr); 16057937d9ceSMichael Lange ierr = PetscFree(name);CHKERRQ(ierr); 16067937d9ceSMichael Lange /* Gather rank/index pairs of leaves into local roots to build 16077937d9ceSMichael Lange an inverse, multi-rooted SF. Note that this ignores local leaf 16087937d9ceSMichael Lange indexing due to the use of the multiSF in PetscSFGather. */ 16097937d9ceSMichael Lange ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL);CHKERRQ(ierr); 1610dc53bc9bSMatthew G. Knepley ierr = PetscMalloc1(nroots, &leafPoints);CHKERRQ(ierr); 1611dc53bc9bSMatthew G. Knepley for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1; 16127937d9ceSMichael Lange for (p = 0; p < nleaves; p++) { 16138212dd46SStefano Zampini PetscInt ilp = ilocal ? ilocal[p] : p; 16148212dd46SStefano Zampini 16158212dd46SStefano Zampini leafPoints[ilp].index = ilp; 16168212dd46SStefano Zampini leafPoints[ilp].rank = rank; 16177937d9ceSMichael Lange } 16187937d9ceSMichael Lange ierr = PetscSFComputeDegreeBegin(sf, &rootDegree);CHKERRQ(ierr); 16197937d9ceSMichael Lange ierr = PetscSFComputeDegreeEnd(sf, &rootDegree);CHKERRQ(ierr); 16207937d9ceSMichael Lange for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p]; 16217937d9ceSMichael Lange ierr = PetscMalloc1(nmultiroots, &rootPoints);CHKERRQ(ierr); 16227937d9ceSMichael Lange ierr = PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 16237937d9ceSMichael Lange ierr = PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr); 16247937d9ceSMichael Lange ierr = PetscSFCreate(comm,& sfLabel);CHKERRQ(ierr); 16257937d9ceSMichael Lange ierr = PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER);CHKERRQ(ierr); 16267937d9ceSMichael Lange /* Migrate label over inverted SF to pull stratum values at leaves into roots. */ 16277937d9ceSMichael Lange ierr = DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata);CHKERRQ(ierr); 16287937d9ceSMichael Lange /* Rebuild the point strata on the receiver */ 16297937d9ceSMichael Lange for (p = 0, idx = 0; p < nroots; p++) { 16307937d9ceSMichael Lange for (d = 0; d < rootDegree[p]; d++) { 16317937d9ceSMichael Lange ierr = PetscSectionGetDof(rootSection, idx+d, &dof);CHKERRQ(ierr); 16327937d9ceSMichael Lange ierr = PetscSectionGetOffset(rootSection, idx+d, &offset);CHKERRQ(ierr); 16337937d9ceSMichael Lange for (s = 0; s < dof; s++) {ierr = DMLabelSetValue(*labelNew, p, rootStrata[offset+s]);CHKERRQ(ierr);} 16347937d9ceSMichael Lange } 16357937d9ceSMichael Lange idx += rootDegree[p]; 16367937d9ceSMichael Lange } 163777e0c0e7SMichael Lange ierr = PetscFree(leafPoints);CHKERRQ(ierr); 163877e0c0e7SMichael Lange ierr = PetscFree(rootStrata);CHKERRQ(ierr); 163977e0c0e7SMichael Lange ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr); 164077e0c0e7SMichael Lange ierr = PetscSFDestroy(&sfLabel);CHKERRQ(ierr); 16417937d9ceSMichael Lange PetscFunctionReturn(0); 16427937d9ceSMichael Lange } 16437937d9ceSMichael Lange 164484f0b6dfSMatthew G. Knepley /*@ 164584f0b6dfSMatthew G. Knepley DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label 164684f0b6dfSMatthew G. Knepley 1647*5b5e7992SMatthew G. Knepley Not collective 1648*5b5e7992SMatthew G. Knepley 164984f0b6dfSMatthew G. Knepley Input Parameter: 165084f0b6dfSMatthew G. Knepley . label - the DMLabel 165184f0b6dfSMatthew G. Knepley 165284f0b6dfSMatthew G. Knepley Output Parameters: 165384f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum 165484f0b6dfSMatthew G. Knepley - is - An IS containing all the label points 165584f0b6dfSMatthew G. Knepley 165684f0b6dfSMatthew G. Knepley Level: developer 165784f0b6dfSMatthew G. Knepley 165884f0b6dfSMatthew G. Knepley .seealso: DMLabelDistribute() 165984f0b6dfSMatthew G. Knepley @*/ 1660c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is) 1661c58f1c22SToby Isaac { 1662c58f1c22SToby Isaac IS vIS; 1663c58f1c22SToby Isaac const PetscInt *values; 1664c58f1c22SToby Isaac PetscInt *points; 1665c58f1c22SToby Isaac PetscInt nV, vS = 0, vE = 0, v, N; 1666c58f1c22SToby Isaac PetscErrorCode ierr; 1667c58f1c22SToby Isaac 1668c58f1c22SToby Isaac PetscFunctionBegin; 1669d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1); 1670c58f1c22SToby Isaac ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr); 1671c58f1c22SToby Isaac ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr); 1672c58f1c22SToby Isaac ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr); 1673c58f1c22SToby Isaac if (nV) {vS = values[0]; vE = values[0]+1;} 1674c58f1c22SToby Isaac for (v = 1; v < nV; ++v) { 1675c58f1c22SToby Isaac vS = PetscMin(vS, values[v]); 1676c58f1c22SToby Isaac vE = PetscMax(vE, values[v]+1); 1677c58f1c22SToby Isaac } 1678c58f1c22SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr); 1679c58f1c22SToby Isaac ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr); 1680c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1681c58f1c22SToby Isaac PetscInt n; 1682c58f1c22SToby Isaac 1683c58f1c22SToby Isaac ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr); 1684c58f1c22SToby Isaac ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr); 1685c58f1c22SToby Isaac } 1686c58f1c22SToby Isaac ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 1687c58f1c22SToby Isaac ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr); 1688c58f1c22SToby Isaac ierr = PetscMalloc1(N, &points);CHKERRQ(ierr); 1689c58f1c22SToby Isaac for (v = 0; v < nV; ++v) { 1690c58f1c22SToby Isaac IS is; 1691c58f1c22SToby Isaac const PetscInt *spoints; 1692c58f1c22SToby Isaac PetscInt dof, off, p; 1693c58f1c22SToby Isaac 1694c58f1c22SToby Isaac ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr); 1695c58f1c22SToby Isaac ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr); 1696c58f1c22SToby Isaac ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr); 1697c58f1c22SToby Isaac ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr); 1698c58f1c22SToby Isaac for (p = 0; p < dof; ++p) points[off+p] = spoints[p]; 1699c58f1c22SToby Isaac ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr); 1700c58f1c22SToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 1701c58f1c22SToby Isaac } 1702c58f1c22SToby Isaac ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr); 1703c58f1c22SToby Isaac ierr = ISDestroy(&vIS);CHKERRQ(ierr); 1704c58f1c22SToby Isaac ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 1705c58f1c22SToby Isaac PetscFunctionReturn(0); 1706c58f1c22SToby Isaac } 1707c58f1c22SToby Isaac 170884f0b6dfSMatthew G. Knepley /*@ 1709c58f1c22SToby Isaac PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 1710c58f1c22SToby Isaac the local section and an SF describing the section point overlap. 1711c58f1c22SToby Isaac 1712*5b5e7992SMatthew G. Knepley Collective on sf 1713*5b5e7992SMatthew G. Knepley 1714c58f1c22SToby Isaac Input Parameters: 1715c58f1c22SToby Isaac + s - The PetscSection for the local field layout 1716c58f1c22SToby Isaac . sf - The SF describing parallel layout of the section points 1717c58f1c22SToby Isaac . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 1718c58f1c22SToby Isaac . label - The label specifying the points 1719c58f1c22SToby Isaac - labelValue - The label stratum specifying the points 1720c58f1c22SToby Isaac 1721c58f1c22SToby Isaac Output Parameter: 1722c58f1c22SToby Isaac . gsection - The PetscSection for the global field layout 1723c58f1c22SToby Isaac 1724c58f1c22SToby Isaac Note: This gives negative sizes and offsets to points not owned by this process 1725c58f1c22SToby Isaac 1726c58f1c22SToby Isaac Level: developer 1727c58f1c22SToby Isaac 1728c58f1c22SToby Isaac .seealso: PetscSectionCreate() 1729c58f1c22SToby Isaac @*/ 1730c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 1731c58f1c22SToby Isaac { 1732c58f1c22SToby Isaac PetscInt *neg = NULL, *tmpOff = NULL; 1733c58f1c22SToby Isaac PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 1734c58f1c22SToby Isaac PetscErrorCode ierr; 1735c58f1c22SToby Isaac 1736c58f1c22SToby Isaac PetscFunctionBegin; 1737d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1); 1738d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2); 1739d67d17b1SMatthew G. Knepley PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4); 1740c58f1c22SToby Isaac ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr); 1741c58f1c22SToby Isaac ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 1742c58f1c22SToby Isaac ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr); 1743c58f1c22SToby Isaac ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 1744c58f1c22SToby Isaac if (nroots >= 0) { 1745c58f1c22SToby Isaac if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart); 1746c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr); 1747c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1748c58f1c22SToby Isaac ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr); 1749c58f1c22SToby Isaac } else { 1750c58f1c22SToby Isaac tmpOff = &(*gsection)->atlasDof[-pStart]; 1751c58f1c22SToby Isaac } 1752c58f1c22SToby Isaac } 1753c58f1c22SToby Isaac /* Mark ghost points with negative dof */ 1754c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) { 1755c58f1c22SToby Isaac PetscInt value; 1756c58f1c22SToby Isaac 1757c58f1c22SToby Isaac ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr); 1758c58f1c22SToby Isaac if (value != labelValue) continue; 1759c58f1c22SToby Isaac ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 1760c58f1c22SToby Isaac ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr); 1761c58f1c22SToby Isaac ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 1762c58f1c22SToby Isaac if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);} 1763c58f1c22SToby Isaac if (neg) neg[p] = -(dof+1); 1764c58f1c22SToby Isaac } 1765c58f1c22SToby Isaac ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr); 1766c58f1c22SToby Isaac if (nroots >= 0) { 1767c58f1c22SToby Isaac ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1768c58f1c22SToby Isaac ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1769c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1770c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 1771c58f1c22SToby Isaac } 1772c58f1c22SToby Isaac } 1773c58f1c22SToby Isaac /* Calculate new sizes, get proccess offset, and calculate point offsets */ 1774c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1775c58f1c22SToby Isaac cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 1776c58f1c22SToby Isaac (*gsection)->atlasOff[p] = off; 1777c58f1c22SToby Isaac off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 1778c58f1c22SToby Isaac } 1779c58f1c22SToby Isaac ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRQ(ierr); 1780c58f1c22SToby Isaac globalOff -= off; 1781c58f1c22SToby Isaac for (p = 0, off = 0; p < pEnd-pStart; ++p) { 1782c58f1c22SToby Isaac (*gsection)->atlasOff[p] += globalOff; 1783c58f1c22SToby Isaac if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 1784c58f1c22SToby Isaac } 1785c58f1c22SToby Isaac /* Put in negative offsets for ghost points */ 1786c58f1c22SToby Isaac if (nroots >= 0) { 1787c58f1c22SToby Isaac ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1788c58f1c22SToby Isaac ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 1789c58f1c22SToby Isaac if (nroots > pEnd-pStart) { 1790c58f1c22SToby Isaac for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 1791c58f1c22SToby Isaac } 1792c58f1c22SToby Isaac } 1793c58f1c22SToby Isaac if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);} 1794c58f1c22SToby Isaac ierr = PetscFree(neg);CHKERRQ(ierr); 1795c58f1c22SToby Isaac PetscFunctionReturn(0); 1796c58f1c22SToby Isaac } 1797c58f1c22SToby Isaac 17985fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label 17995fdea053SToby Isaac { 18005fdea053SToby Isaac DMLabel label; 18015fdea053SToby Isaac PetscCopyMode *modes; 18025fdea053SToby Isaac PetscInt *sizes; 18035fdea053SToby Isaac const PetscInt ***perms; 18045fdea053SToby Isaac const PetscScalar ***rots; 18055fdea053SToby Isaac PetscInt (*minMaxOrients)[2]; 18065fdea053SToby Isaac PetscInt numStrata; /* numStrata is only increasing, functions as a state */ 18075fdea053SToby Isaac } PetscSectionSym_Label; 18085fdea053SToby Isaac 18095fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym) 18105fdea053SToby Isaac { 18115fdea053SToby Isaac PetscInt i, j; 18125fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 18135fdea053SToby Isaac PetscErrorCode ierr; 18145fdea053SToby Isaac 18155fdea053SToby Isaac PetscFunctionBegin; 18165fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 18175fdea053SToby Isaac if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) { 18185fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 18195fdea053SToby Isaac if (sl->perms[i]) {ierr = PetscFree(sl->perms[i][j]);CHKERRQ(ierr);} 18205fdea053SToby Isaac if (sl->rots[i]) {ierr = PetscFree(sl->rots[i][j]);CHKERRQ(ierr);} 18215fdea053SToby Isaac } 18225fdea053SToby Isaac if (sl->perms[i]) { 18235fdea053SToby Isaac const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]]; 18245fdea053SToby Isaac 18255fdea053SToby Isaac ierr = PetscFree(perms);CHKERRQ(ierr); 18265fdea053SToby Isaac } 18275fdea053SToby Isaac if (sl->rots[i]) { 18285fdea053SToby Isaac const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]]; 18295fdea053SToby Isaac 18305fdea053SToby Isaac ierr = PetscFree(rots);CHKERRQ(ierr); 18315fdea053SToby Isaac } 18325fdea053SToby Isaac } 18335fdea053SToby Isaac } 18345fdea053SToby Isaac ierr = PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients);CHKERRQ(ierr); 18355fdea053SToby Isaac ierr = DMLabelDestroy(&sl->label);CHKERRQ(ierr); 18365fdea053SToby Isaac sl->numStrata = 0; 18375fdea053SToby Isaac PetscFunctionReturn(0); 18385fdea053SToby Isaac } 18395fdea053SToby Isaac 18405fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym) 18415fdea053SToby Isaac { 18425fdea053SToby Isaac PetscErrorCode ierr; 18435fdea053SToby Isaac 18445fdea053SToby Isaac PetscFunctionBegin; 18455fdea053SToby Isaac ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr); 18465fdea053SToby Isaac ierr = PetscFree(sym->data);CHKERRQ(ierr); 18475fdea053SToby Isaac PetscFunctionReturn(0); 18485fdea053SToby Isaac } 18495fdea053SToby Isaac 18505fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer) 18515fdea053SToby Isaac { 18525fdea053SToby Isaac PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data; 18535fdea053SToby Isaac PetscBool isAscii; 18545fdea053SToby Isaac DMLabel label = sl->label; 1855d67d17b1SMatthew G. Knepley const char *name; 18565fdea053SToby Isaac PetscErrorCode ierr; 18575fdea053SToby Isaac 18585fdea053SToby Isaac PetscFunctionBegin; 18595fdea053SToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii);CHKERRQ(ierr); 18605fdea053SToby Isaac if (isAscii) { 18615fdea053SToby Isaac PetscInt i, j, k; 18625fdea053SToby Isaac PetscViewerFormat format; 18635fdea053SToby Isaac 18645fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 18655fdea053SToby Isaac if (label) { 18665fdea053SToby Isaac ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 18675fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 18685fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 18695fdea053SToby Isaac ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 18705fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 18715fdea053SToby Isaac } else { 1872d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr); 1873d67d17b1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer," Label '%s'\n",name);CHKERRQ(ierr); 18745fdea053SToby Isaac } 18755fdea053SToby Isaac } else { 18765fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "No label given\n");CHKERRQ(ierr); 18775fdea053SToby Isaac } 18785fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 18795fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 18805fdea053SToby Isaac PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue; 18815fdea053SToby Isaac 18825fdea053SToby Isaac if (!(sl->perms[i] || sl->rots[i])) { 18835fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point): no symmetries\n", value, sl->sizes[i]);CHKERRQ(ierr); 18845fdea053SToby Isaac } else { 18855fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point):\n", value, sl->sizes[i]);CHKERRQ(ierr); 18865fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 18875fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation range: [%D, %D)\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1]);CHKERRQ(ierr); 18885fdea053SToby Isaac if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 18895fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 18905fdea053SToby Isaac for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) { 18915fdea053SToby Isaac if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) { 18925fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D: identity\n",j);CHKERRQ(ierr); 18935fdea053SToby Isaac } else { 18945fdea053SToby Isaac PetscInt tab; 18955fdea053SToby Isaac 18965fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D:\n",j);CHKERRQ(ierr); 18975fdea053SToby Isaac ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 18985fdea053SToby Isaac ierr = PetscViewerASCIIGetTab(viewer,&tab);CHKERRQ(ierr); 18995fdea053SToby Isaac if (sl->perms[i] && sl->perms[i][j]) { 19005fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Permutation:");CHKERRQ(ierr); 19015fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 19025fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %D",sl->perms[i][j][k]);CHKERRQ(ierr);} 19035fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 19045fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 19055fdea053SToby Isaac } 19065fdea053SToby Isaac if (sl->rots[i] && sl->rots[i][j]) { 19075fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"Rotations: ");CHKERRQ(ierr); 19085fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr); 19095fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX) 19105fdea053SToby 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);} 19115fdea053SToby Isaac #else 19125fdea053SToby Isaac for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f",sl->rots[i][j][k]);CHKERRQ(ierr);} 19135fdea053SToby Isaac #endif 19145fdea053SToby Isaac ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 19155fdea053SToby Isaac ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr); 19165fdea053SToby Isaac } 19175fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19185fdea053SToby Isaac } 19195fdea053SToby Isaac } 19205fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19215fdea053SToby Isaac } 19225fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19235fdea053SToby Isaac } 19245fdea053SToby Isaac } 19255fdea053SToby Isaac ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 19265fdea053SToby Isaac } 19275fdea053SToby Isaac PetscFunctionReturn(0); 19285fdea053SToby Isaac } 19295fdea053SToby Isaac 19305fdea053SToby Isaac /*@ 19315fdea053SToby Isaac PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries 19325fdea053SToby Isaac 19335fdea053SToby Isaac Logically collective on sym 19345fdea053SToby Isaac 19355fdea053SToby Isaac Input parameters: 19365fdea053SToby Isaac + sym - the section symmetries 19375fdea053SToby Isaac - label - the DMLabel describing the types of points 19385fdea053SToby Isaac 19395fdea053SToby Isaac Level: developer: 19405fdea053SToby Isaac 19415fdea053SToby Isaac .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreateLabel(), PetscSectionGetPointSyms() 19425fdea053SToby Isaac @*/ 19435fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label) 19445fdea053SToby Isaac { 19455fdea053SToby Isaac PetscSectionSym_Label *sl; 19465fdea053SToby Isaac PetscErrorCode ierr; 19475fdea053SToby Isaac 19485fdea053SToby Isaac PetscFunctionBegin; 19495fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 19505fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 19515fdea053SToby Isaac if (sl->label && sl->label != label) {ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);} 19525fdea053SToby Isaac if (label) { 19535fdea053SToby Isaac sl->label = label; 1954d67d17b1SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr); 19555fdea053SToby Isaac ierr = DMLabelGetNumValues(label,&sl->numStrata);CHKERRQ(ierr); 19561a834cf9SToby 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); 19571a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode));CHKERRQ(ierr); 19581a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt));CHKERRQ(ierr); 19591a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **));CHKERRQ(ierr); 19601a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **));CHKERRQ(ierr); 19611a834cf9SToby Isaac ierr = PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]));CHKERRQ(ierr); 19625fdea053SToby Isaac } 19635fdea053SToby Isaac PetscFunctionReturn(0); 19645fdea053SToby Isaac } 19655fdea053SToby Isaac 19665fdea053SToby Isaac /*@C 19675fdea053SToby Isaac PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum 19685fdea053SToby Isaac 1969*5b5e7992SMatthew G. Knepley Logically collective on sym 19705fdea053SToby Isaac 19715fdea053SToby Isaac InputParameters: 1972*5b5e7992SMatthew G. Knepley + sym - the section symmetries 19735fdea053SToby Isaac . stratum - the stratum value in the label that we are assigning symmetries for 19745fdea053SToby Isaac . size - the number of dofs for points in the stratum of the label 19755fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum 19765fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient)) 19775fdea053SToby Isaac . mode - how sym should copy the perms and rots arrays 19785fdea053SToby Isaac . perms - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation. A NULL permutation is the identity 19795fdea053SToby 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 19805fdea053SToby Isaac 19815fdea053SToby Isaac Level: developer 19825fdea053SToby Isaac 19835fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel() 19845fdea053SToby Isaac @*/ 19855fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots) 19865fdea053SToby Isaac { 19875fdea053SToby Isaac PetscSectionSym_Label *sl; 1988d67d17b1SMatthew G. Knepley const char *name; 1989d67d17b1SMatthew G. Knepley PetscInt i, j, k; 19905fdea053SToby Isaac PetscErrorCode ierr; 19915fdea053SToby Isaac 19925fdea053SToby Isaac PetscFunctionBegin; 19935fdea053SToby Isaac PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1); 19945fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 19955fdea053SToby Isaac if (!sl->label) SETERRQ(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_WRONGSTATE,"No label set yet"); 19965fdea053SToby Isaac for (i = 0; i <= sl->numStrata; i++) { 19975fdea053SToby Isaac PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue; 19985fdea053SToby Isaac 19995fdea053SToby Isaac if (stratum == value) break; 20005fdea053SToby Isaac } 2001d67d17b1SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr); 2002d67d17b1SMatthew G. Knepley if (i > sl->numStrata) SETERRQ2(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_OUTOFRANGE,"Stratum %D not found in label %s\n",stratum,name); 20035fdea053SToby Isaac sl->sizes[i] = size; 20045fdea053SToby Isaac sl->modes[i] = mode; 20055fdea053SToby Isaac sl->minMaxOrients[i][0] = minOrient; 20065fdea053SToby Isaac sl->minMaxOrients[i][1] = maxOrient; 20075fdea053SToby Isaac if (mode == PETSC_COPY_VALUES) { 20085fdea053SToby Isaac if (perms) { 20095fdea053SToby Isaac PetscInt **ownPerms; 20105fdea053SToby Isaac 20115fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownPerms);CHKERRQ(ierr); 20125fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 20135fdea053SToby Isaac if (perms[j]) { 20145fdea053SToby Isaac ierr = PetscMalloc1(size,&ownPerms[j]);CHKERRQ(ierr); 20155fdea053SToby Isaac for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];} 20165fdea053SToby Isaac } 20175fdea053SToby Isaac } 20185fdea053SToby Isaac sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient]; 20195fdea053SToby Isaac } 20205fdea053SToby Isaac if (rots) { 20215fdea053SToby Isaac PetscScalar **ownRots; 20225fdea053SToby Isaac 20235fdea053SToby Isaac ierr = PetscCalloc1(maxOrient - minOrient,&ownRots);CHKERRQ(ierr); 20245fdea053SToby Isaac for (j = 0; j < maxOrient-minOrient; j++) { 20255fdea053SToby Isaac if (rots[j]) { 20265fdea053SToby Isaac ierr = PetscMalloc1(size,&ownRots[j]);CHKERRQ(ierr); 20275fdea053SToby Isaac for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];} 20285fdea053SToby Isaac } 20295fdea053SToby Isaac } 20305fdea053SToby Isaac sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient]; 20315fdea053SToby Isaac } 20325fdea053SToby Isaac } else { 20335fdea053SToby Isaac sl->perms[i] = perms ? &perms[-minOrient] : NULL; 20345fdea053SToby Isaac sl->rots[i] = rots ? &rots[-minOrient] : NULL; 20355fdea053SToby Isaac } 20365fdea053SToby Isaac PetscFunctionReturn(0); 20375fdea053SToby Isaac } 20385fdea053SToby Isaac 20395fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots) 20405fdea053SToby Isaac { 20415fdea053SToby Isaac PetscInt i, j, numStrata; 20425fdea053SToby Isaac PetscSectionSym_Label *sl; 20435fdea053SToby Isaac DMLabel label; 20445fdea053SToby Isaac PetscErrorCode ierr; 20455fdea053SToby Isaac 20465fdea053SToby Isaac PetscFunctionBegin; 20475fdea053SToby Isaac sl = (PetscSectionSym_Label *) sym->data; 20485fdea053SToby Isaac numStrata = sl->numStrata; 20495fdea053SToby Isaac label = sl->label; 20505fdea053SToby Isaac for (i = 0; i < numPoints; i++) { 20515fdea053SToby Isaac PetscInt point = points[2*i]; 20525fdea053SToby Isaac PetscInt ornt = points[2*i+1]; 20535fdea053SToby Isaac 20545fdea053SToby Isaac for (j = 0; j < numStrata; j++) { 20555fdea053SToby Isaac if (label->validIS[j]) { 20565fdea053SToby Isaac PetscInt k; 20575fdea053SToby Isaac 20585fdea053SToby Isaac ierr = ISLocate(label->points[j],point,&k);CHKERRQ(ierr); 20595fdea053SToby Isaac if (k >= 0) break; 20605fdea053SToby Isaac } else { 20615fdea053SToby Isaac PetscBool has; 20625fdea053SToby Isaac 2063b9907514SLisandro Dalcin ierr = PetscHSetIHas(label->ht[j], point, &has);CHKERRQ(ierr); 20645fdea053SToby Isaac if (has) break; 20655fdea053SToby Isaac } 20665fdea053SToby Isaac } 20675fdea053SToby 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); 20685fdea053SToby Isaac if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;} 20695fdea053SToby Isaac if (rots) {rots[i] = sl->rots[j] ? sl->rots[j][ornt] : NULL;} 20705fdea053SToby Isaac } 20715fdea053SToby Isaac PetscFunctionReturn(0); 20725fdea053SToby Isaac } 20735fdea053SToby Isaac 20745fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym) 20755fdea053SToby Isaac { 20765fdea053SToby Isaac PetscSectionSym_Label *sl; 20775fdea053SToby Isaac PetscErrorCode ierr; 20785fdea053SToby Isaac 20795fdea053SToby Isaac PetscFunctionBegin; 20805fdea053SToby Isaac ierr = PetscNewLog(sym,&sl);CHKERRQ(ierr); 20815fdea053SToby Isaac sym->ops->getpoints = PetscSectionSymGetPoints_Label; 20825fdea053SToby Isaac sym->ops->view = PetscSectionSymView_Label; 20835fdea053SToby Isaac sym->ops->destroy = PetscSectionSymDestroy_Label; 20845fdea053SToby Isaac sym->data = (void *) sl; 20855fdea053SToby Isaac PetscFunctionReturn(0); 20865fdea053SToby Isaac } 20875fdea053SToby Isaac 20885fdea053SToby Isaac /*@ 20895fdea053SToby Isaac PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label 20905fdea053SToby Isaac 20915fdea053SToby Isaac Collective 20925fdea053SToby Isaac 20935fdea053SToby Isaac Input Parameters: 20945fdea053SToby Isaac + comm - the MPI communicator for the new symmetry 20955fdea053SToby Isaac - label - the label defining the strata 20965fdea053SToby Isaac 20975fdea053SToby Isaac Output Parameters: 20985fdea053SToby Isaac . sym - the section symmetries 20995fdea053SToby Isaac 21005fdea053SToby Isaac Level: developer 21015fdea053SToby Isaac 21025fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym(), PetscSectionSymLabelSetStratum(), PetscSectionGetPointSyms() 21035fdea053SToby Isaac @*/ 21045fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym) 21055fdea053SToby Isaac { 21065fdea053SToby Isaac PetscErrorCode ierr; 21075fdea053SToby Isaac 21085fdea053SToby Isaac PetscFunctionBegin; 21095fdea053SToby Isaac ierr = DMInitializePackage();CHKERRQ(ierr); 21105fdea053SToby Isaac ierr = PetscSectionSymCreate(comm,sym);CHKERRQ(ierr); 21115fdea053SToby Isaac ierr = PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL);CHKERRQ(ierr); 21125fdea053SToby Isaac ierr = PetscSectionSymLabelSetLabel(*sym,label);CHKERRQ(ierr); 21135fdea053SToby Isaac PetscFunctionReturn(0); 21145fdea053SToby Isaac } 2115