1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2af0996ceSBarry Smith #include <petsc/private/isimpl.h> 3e5c6e791SKarl Rupp #include <petsc/private/vecimpl.h> 40c312b8eSJed Brown #include <petscsf.h> 5e228b242SToby Isaac #include <petscds.h> 6*e412dcbdSMatthew G. Knepley #include <petscdraw.h> 7552f7358SJed Brown 8552f7358SJed Brown /* Logging support */ 9fa534816SMatthew G. Knepley PetscLogEvent DMPLEX_Interpolate, PETSCPARTITIONER_Partition, DMPLEX_Distribute, DMPLEX_DistributeCones, DMPLEX_DistributeLabels, DMPLEX_DistributeSF, DMPLEX_DistributeOverlap, DMPLEX_DistributeField, DMPLEX_DistributeData, DMPLEX_Migrate, DMPLEX_GlobalToNaturalBegin, DMPLEX_GlobalToNaturalEnd, DMPLEX_NaturalToGlobalBegin, DMPLEX_NaturalToGlobalEnd, DMPLEX_Stratify, DMPLEX_Preallocate, DMPLEX_ResidualFEM, DMPLEX_JacobianFEM, DMPLEX_InterpolatorFEM, DMPLEX_InjectorFEM, DMPLEX_IntegralFEM, DMPLEX_CreateGmsh; 10552f7358SJed Brown 115a576424SJed Brown PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 122c40f234SMatthew G. Knepley PETSC_EXTERN PetscErrorCode VecLoad_Default(Vec, PetscViewer); 13552f7358SJed Brown 147e42fee7SMatthew G. Knepley #undef __FUNCT__ 157afe7537SMatthew G. Knepley #define __FUNCT__ "DMPlexGetFieldType_Internal" 167afe7537SMatthew G. Knepley PetscErrorCode DMPlexGetFieldType_Internal(DM dm, PetscSection section, PetscInt field, PetscInt *sStart, PetscInt *sEnd, PetscViewerVTKFieldType *ft) 177e42fee7SMatthew G. Knepley { 1880d5bdc6SMatthew G. Knepley PetscInt dim, pStart, pEnd, vStart, vEnd, cStart, cEnd, cEndInterior, vdof = 0, cdof = 0; 197e42fee7SMatthew G. Knepley PetscErrorCode ierr; 207e42fee7SMatthew G. Knepley 217e42fee7SMatthew G. Knepley PetscFunctionBegin; 227e42fee7SMatthew G. Knepley *ft = PETSC_VTK_POINT_FIELD; 23c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 247e42fee7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 257e42fee7SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 2680d5bdc6SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cEndInterior, NULL, NULL, NULL);CHKERRQ(ierr); 2780d5bdc6SMatthew G. Knepley cEnd = cEndInterior < 0 ? cEnd : cEndInterior; 287e42fee7SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 297e42fee7SMatthew G. Knepley if (field >= 0) { 307e42fee7SMatthew G. Knepley if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, vStart, field, &vdof);CHKERRQ(ierr);} 317e42fee7SMatthew G. Knepley if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, cStart, field, &cdof);CHKERRQ(ierr);} 327e42fee7SMatthew G. Knepley } else { 337e42fee7SMatthew G. Knepley if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetDof(section, vStart, &vdof);CHKERRQ(ierr);} 347e42fee7SMatthew G. Knepley if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetDof(section, cStart, &cdof);CHKERRQ(ierr);} 357e42fee7SMatthew G. Knepley } 367e42fee7SMatthew G. Knepley if (vdof) { 377e42fee7SMatthew G. Knepley *sStart = vStart; 387e42fee7SMatthew G. Knepley *sEnd = vEnd; 397e42fee7SMatthew G. Knepley if (vdof == dim) *ft = PETSC_VTK_POINT_VECTOR_FIELD; 407e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_POINT_FIELD; 417e42fee7SMatthew G. Knepley } else if (cdof) { 427e42fee7SMatthew G. Knepley *sStart = cStart; 437e42fee7SMatthew G. Knepley *sEnd = cEnd; 447e42fee7SMatthew G. Knepley if (cdof == dim) *ft = PETSC_VTK_CELL_VECTOR_FIELD; 457e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_CELL_FIELD; 467e42fee7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Could not classify input Vec for VTK"); 477e42fee7SMatthew G. Knepley PetscFunctionReturn(0); 487e42fee7SMatthew G. Knepley } 497e42fee7SMatthew G. Knepley 50552f7358SJed Brown #undef __FUNCT__ 51552f7358SJed Brown #define __FUNCT__ "VecView_Plex_Local" 52552f7358SJed Brown PetscErrorCode VecView_Plex_Local(Vec v, PetscViewer viewer) 53552f7358SJed Brown { 54552f7358SJed Brown DM dm; 55b136c2c9SMatthew G. Knepley PetscBool isvtk, ishdf5, isseq; 56552f7358SJed Brown PetscErrorCode ierr; 57552f7358SJed Brown 58552f7358SJed Brown PetscFunctionBegin; 59552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 6082f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 61552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 62b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 63b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 64ef31f671SMatthew G. Knepley if (isvtk || ishdf5) { 65ef31f671SMatthew G. Knepley PetscInt numFields; 66ef31f671SMatthew G. Knepley PetscBool fem = PETSC_FALSE; 67ef31f671SMatthew G. Knepley 68ef31f671SMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 69ef31f671SMatthew G. Knepley if (numFields) { 70ef31f671SMatthew G. Knepley PetscObject fe; 71ef31f671SMatthew G. Knepley 72ef31f671SMatthew G. Knepley ierr = DMGetField(dm, 0, &fe);CHKERRQ(ierr); 73ef31f671SMatthew G. Knepley if (fe->classid == PETSCFE_CLASSID) fem = PETSC_TRUE; 74ef31f671SMatthew G. Knepley } 75bdd6f66aSToby Isaac if (fem) {ierr = DMPlexInsertBoundaryValues(dm, PETSC_TRUE, v, 0.0, NULL, NULL, NULL);CHKERRQ(ierr);} 76ef31f671SMatthew G. Knepley } 77552f7358SJed Brown if (isvtk) { 78552f7358SJed Brown PetscSection section; 79b136c2c9SMatthew G. Knepley PetscViewerVTKFieldType ft; 80b136c2c9SMatthew G. Knepley PetscInt pStart, pEnd; 81552f7358SJed Brown 82552f7358SJed Brown ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 837afe7537SMatthew G. Knepley ierr = DMPlexGetFieldType_Internal(dm, section, PETSC_DETERMINE, &pStart, &pEnd, &ft);CHKERRQ(ierr); 84552f7358SJed Brown ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); /* viewer drops reference */ 85552f7358SJed Brown ierr = PetscObjectReference((PetscObject) v);CHKERRQ(ierr); /* viewer drops reference */ 86552f7358SJed Brown ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, ft, (PetscObject) v);CHKERRQ(ierr); 87b136c2c9SMatthew G. Knepley } else if (ishdf5) { 88b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 89b136c2c9SMatthew G. Knepley ierr = VecView_Plex_Local_HDF5(v, viewer);CHKERRQ(ierr); 90b136c2c9SMatthew G. Knepley #else 91b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 92b136c2c9SMatthew G. Knepley #endif 93552f7358SJed Brown } else { 9455f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 9555f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 96552f7358SJed Brown } 97552f7358SJed Brown PetscFunctionReturn(0); 98552f7358SJed Brown } 99552f7358SJed Brown 100552f7358SJed Brown #undef __FUNCT__ 101*e412dcbdSMatthew G. Knepley #define __FUNCT__ "VecView_Plex_Draw" 102*e412dcbdSMatthew G. Knepley PetscErrorCode VecView_Plex_Draw(Vec v, PetscViewer viewer) 103*e412dcbdSMatthew G. Knepley { 104*e412dcbdSMatthew G. Knepley DM dm; 105*e412dcbdSMatthew G. Knepley PetscDraw draw, popup; 106*e412dcbdSMatthew G. Knepley DM cdm; 107*e412dcbdSMatthew G. Knepley DMLabel markers; 108*e412dcbdSMatthew G. Knepley PetscSection coordSection; 109*e412dcbdSMatthew G. Knepley Vec coordinates; 110*e412dcbdSMatthew G. Knepley const PetscScalar *coords, *array; 111*e412dcbdSMatthew G. Knepley PetscReal bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 112*e412dcbdSMatthew G. Knepley PetscReal min, max; 113*e412dcbdSMatthew G. Knepley PetscBool isnull; 114*e412dcbdSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N, level; 115*e412dcbdSMatthew G. Knepley const char *name; 116*e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 117*e412dcbdSMatthew G. Knepley 118*e412dcbdSMatthew G. Knepley PetscFunctionBegin; 119*e412dcbdSMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 120*e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 121*e412dcbdSMatthew G. Knepley if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 122*e412dcbdSMatthew G. Knepley ierr = DMGetCoarsenLevel(dm, &level);CHKERRQ(ierr); 123*e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 124*e412dcbdSMatthew G. Knepley ierr = DMGetDefaultSection(cdm, &coordSection);CHKERRQ(ierr); 125*e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 126*e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 127*e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 128*e412dcbdSMatthew G. Knepley 129*e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 130*e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 131*e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 132*e412dcbdSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 133*e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, name);CHKERRQ(ierr); 134*e412dcbdSMatthew G. Knepley 135*e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 136*e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 137*e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 138*e412dcbdSMatthew G. Knepley bound[0] = PetscMin(bound[0], coords[c]); bound[2] = PetscMax(bound[2], coords[c]); 139*e412dcbdSMatthew G. Knepley bound[1] = PetscMin(bound[1], coords[c+1]); bound[3] = PetscMax(bound[3], coords[c+1]); 140*e412dcbdSMatthew G. Knepley } 141*e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 142*e412dcbdSMatthew G. Knepley ierr = PetscDrawSetCoordinates(draw, bound[0], bound[1], bound[2], bound[3]);CHKERRQ(ierr); 143*e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 144*e412dcbdSMatthew G. Knepley 145*e412dcbdSMatthew G. Knepley ierr = VecMin(v, NULL, &min);CHKERRQ(ierr); 146*e412dcbdSMatthew G. Knepley ierr = VecMax(v, NULL, &max);CHKERRQ(ierr); 147*e412dcbdSMatthew G. Knepley ierr = PetscDrawGetPopup(draw, &popup);CHKERRQ(ierr); 148*e412dcbdSMatthew G. Knepley ierr = PetscDrawScalePopup(popup, min, max);CHKERRQ(ierr); 149*e412dcbdSMatthew G. Knepley 150*e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(v, &array);CHKERRQ(ierr); 151*e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 152*e412dcbdSMatthew G. Knepley PetscScalar *coords = NULL, *a; 153*e412dcbdSMatthew G. Knepley PetscInt numCoords, color; 154*e412dcbdSMatthew G. Knepley 155*e412dcbdSMatthew G. Knepley ierr = DMPlexPointGlobalRead(dm, c, array, &a);CHKERRQ(ierr); 156*e412dcbdSMatthew G. Knepley color = PetscDrawRealToColor(PetscRealPart(a[0]), min, max); 157*e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 158*e412dcbdSMatthew G. Knepley switch (numCoords) { 159*e412dcbdSMatthew G. Knepley case 6: 160*e412dcbdSMatthew G. Knepley ierr = PetscDrawTriangle(draw, coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], color, color, color);CHKERRQ(ierr); 161*e412dcbdSMatthew G. Knepley break; 162*e412dcbdSMatthew G. Knepley case 8: 163*e412dcbdSMatthew G. Knepley ierr = PetscDrawTriangle(draw, coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], color, color, color);CHKERRQ(ierr); 164*e412dcbdSMatthew G. Knepley ierr = PetscDrawTriangle(draw, coords[4], coords[5], coords[6], coords[7], coords[0], coords[1], color, color, color);CHKERRQ(ierr); 165*e412dcbdSMatthew G. Knepley break; 166*e412dcbdSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D coordinates", numCoords); 167*e412dcbdSMatthew G. Knepley } 168*e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 169*e412dcbdSMatthew G. Knepley } 170*e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &array);CHKERRQ(ierr); 171*e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 172*e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 173*e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 174*e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 175*e412dcbdSMatthew G. Knepley } 176*e412dcbdSMatthew G. Knepley 177*e412dcbdSMatthew G. Knepley #undef __FUNCT__ 178552f7358SJed Brown #define __FUNCT__ "VecView_Plex" 179552f7358SJed Brown PetscErrorCode VecView_Plex(Vec v, PetscViewer viewer) 180552f7358SJed Brown { 181552f7358SJed Brown DM dm; 182*e412dcbdSMatthew G. Knepley PetscBool isvtk, ishdf5, isdraw, isseq; 183552f7358SJed Brown PetscErrorCode ierr; 184552f7358SJed Brown 185552f7358SJed Brown PetscFunctionBegin; 186552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 18782f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 188552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 18933c3e6b4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 190*e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 19155f2e967SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 192552f7358SJed Brown if (isvtk) { 193552f7358SJed Brown Vec locv; 194552f7358SJed Brown const char *name; 195552f7358SJed Brown 196552f7358SJed Brown ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 197552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 198552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 199552f7358SJed Brown ierr = DMGlobalToLocalBegin(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 200552f7358SJed Brown ierr = DMGlobalToLocalEnd(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 201552f7358SJed Brown ierr = VecView_Plex_Local(locv, viewer);CHKERRQ(ierr); 202552f7358SJed Brown ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 203b136c2c9SMatthew G. Knepley } else if (ishdf5) { 204b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 205b136c2c9SMatthew G. Knepley ierr = VecView_Plex_HDF5(v, viewer);CHKERRQ(ierr); 206b136c2c9SMatthew G. Knepley #else 207b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 208b136c2c9SMatthew G. Knepley #endif 209*e412dcbdSMatthew G. Knepley } else if (isdraw) { 210*e412dcbdSMatthew G. Knepley ierr = VecView_Plex_Draw(v, viewer);CHKERRQ(ierr); 211552f7358SJed Brown } else { 21255f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 21355f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 214552f7358SJed Brown } 215552f7358SJed Brown PetscFunctionReturn(0); 216552f7358SJed Brown } 217552f7358SJed Brown 218552f7358SJed Brown #undef __FUNCT__ 219d930f514SMatthew G. Knepley #define __FUNCT__ "VecView_Plex_Native" 220d930f514SMatthew G. Knepley PetscErrorCode VecView_Plex_Native(Vec originalv, PetscViewer viewer) 221d930f514SMatthew G. Knepley { 222d930f514SMatthew G. Knepley DM dm; 223d930f514SMatthew G. Knepley MPI_Comm comm; 224d930f514SMatthew G. Knepley PetscViewerFormat format; 225d930f514SMatthew G. Knepley Vec v; 226d930f514SMatthew G. Knepley PetscBool isvtk, ishdf5; 227d930f514SMatthew G. Knepley PetscErrorCode ierr; 228d930f514SMatthew G. Knepley 229d930f514SMatthew G. Knepley PetscFunctionBegin; 230d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 231d930f514SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) originalv, &comm);CHKERRQ(ierr); 2322c4c0c81SMatthew G. Knepley if (!dm) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 233d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 234d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 235d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 236d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 237d930f514SMatthew G. Knepley const char *vecname; 238d930f514SMatthew G. Knepley PetscInt n, nroots; 239d930f514SMatthew G. Knepley 240d930f514SMatthew G. Knepley if (dm->sfNatural) { 241ca43db0aSBarry Smith ierr = VecGetLocalSize(originalv, &n);CHKERRQ(ierr); 242d930f514SMatthew G. Knepley ierr = PetscSFGetGraph(dm->sfNatural, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 243d930f514SMatthew G. Knepley if (n == nroots) { 244d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 245d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, originalv, v);CHKERRQ(ierr); 246d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, originalv, v);CHKERRQ(ierr); 247d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 248d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 249d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONG, "DM global to natural SF only handles global vectors"); 250d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created"); 251d930f514SMatthew G. Knepley } else { 252d930f514SMatthew G. Knepley /* we are viewing a natural DMPlex vec. */ 253d930f514SMatthew G. Knepley v = originalv; 254d930f514SMatthew G. Knepley } 255d930f514SMatthew G. Knepley if (ishdf5) { 256d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 257d930f514SMatthew G. Knepley ierr = VecView_Plex_HDF5_Native(v, viewer);CHKERRQ(ierr); 258d930f514SMatthew G. Knepley #else 259d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 260d930f514SMatthew G. Knepley #endif 261d930f514SMatthew G. Knepley } else if (isvtk) { 262d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "VTK format does not support viewing in natural order. Please switch to HDF5."); 263d930f514SMatthew G. Knepley } else { 264d930f514SMatthew G. Knepley PetscBool isseq; 265d930f514SMatthew G. Knepley 266d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 267d930f514SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 268d930f514SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 269d930f514SMatthew G. Knepley } 270d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) {ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);} 271d930f514SMatthew G. Knepley PetscFunctionReturn(0); 272d930f514SMatthew G. Knepley } 273d930f514SMatthew G. Knepley 274d930f514SMatthew G. Knepley #undef __FUNCT__ 2752c40f234SMatthew G. Knepley #define __FUNCT__ "VecLoad_Plex_Local" 2762c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Local(Vec v, PetscViewer viewer) 2772c40f234SMatthew G. Knepley { 2782c40f234SMatthew G. Knepley DM dm; 2792c40f234SMatthew G. Knepley PetscBool ishdf5; 2802c40f234SMatthew G. Knepley PetscErrorCode ierr; 2812c40f234SMatthew G. Knepley 2822c40f234SMatthew G. Knepley PetscFunctionBegin; 2832c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 2842c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 2852c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 2862c40f234SMatthew G. Knepley if (ishdf5) { 2872c40f234SMatthew G. Knepley DM dmBC; 2882c40f234SMatthew G. Knepley Vec gv; 2892c40f234SMatthew G. Knepley const char *name; 2902c40f234SMatthew G. Knepley 2912c40f234SMatthew G. Knepley ierr = DMGetOutputDM(dm, &dmBC);CHKERRQ(ierr); 2922c40f234SMatthew G. Knepley ierr = DMGetGlobalVector(dmBC, &gv);CHKERRQ(ierr); 2932c40f234SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 2942c40f234SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) gv, name);CHKERRQ(ierr); 2952c40f234SMatthew G. Knepley ierr = VecLoad_Default(gv, viewer);CHKERRQ(ierr); 2962c40f234SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 2972c40f234SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 2982c40f234SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmBC, &gv);CHKERRQ(ierr); 2992c40f234SMatthew G. Knepley } else { 3002c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 3012c40f234SMatthew G. Knepley } 3022c40f234SMatthew G. Knepley PetscFunctionReturn(0); 3032c40f234SMatthew G. Knepley } 3042c40f234SMatthew G. Knepley 3052c40f234SMatthew G. Knepley #undef __FUNCT__ 3062c40f234SMatthew G. Knepley #define __FUNCT__ "VecLoad_Plex" 3072c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex(Vec v, PetscViewer viewer) 3082c40f234SMatthew G. Knepley { 3092c40f234SMatthew G. Knepley DM dm; 3102c40f234SMatthew G. Knepley PetscBool ishdf5; 3112c40f234SMatthew G. Knepley PetscErrorCode ierr; 3122c40f234SMatthew G. Knepley 3132c40f234SMatthew G. Knepley PetscFunctionBegin; 3142c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 3152c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 3162c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 3172c40f234SMatthew G. Knepley if (ishdf5) { 318878b459fSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 319b136c2c9SMatthew G. Knepley ierr = VecLoad_Plex_HDF5(v, viewer);CHKERRQ(ierr); 320b136c2c9SMatthew G. Knepley #else 321b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 322878b459fSMatthew G. Knepley #endif 3232c40f234SMatthew G. Knepley } else { 3242c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 325552f7358SJed Brown } 326552f7358SJed Brown PetscFunctionReturn(0); 327552f7358SJed Brown } 328552f7358SJed Brown 329552f7358SJed Brown #undef __FUNCT__ 330d930f514SMatthew G. Knepley #define __FUNCT__ "VecLoad_Plex_Native" 331d930f514SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Native(Vec originalv, PetscViewer viewer) 332d930f514SMatthew G. Knepley { 333d930f514SMatthew G. Knepley DM dm; 334d930f514SMatthew G. Knepley PetscViewerFormat format; 335d930f514SMatthew G. Knepley PetscBool ishdf5; 336d930f514SMatthew G. Knepley PetscErrorCode ierr; 337d930f514SMatthew G. Knepley 338d930f514SMatthew G. Knepley PetscFunctionBegin; 339d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 340d930f514SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject) originalv), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 341d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 342d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 343d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 344d930f514SMatthew G. Knepley if (dm->sfNatural) { 345d930f514SMatthew G. Knepley if (ishdf5) { 346d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 347d930f514SMatthew G. Knepley Vec v; 348d930f514SMatthew G. Knepley const char *vecname; 349d930f514SMatthew G. Knepley 350d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 351d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 352d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 353d930f514SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Native(v, viewer);CHKERRQ(ierr); 354d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, v, originalv);CHKERRQ(ierr); 355d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, v, originalv);CHKERRQ(ierr); 356d930f514SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); 357d930f514SMatthew G. Knepley #else 358d930f514SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 359d930f514SMatthew G. Knepley #endif 360d930f514SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Reading in natural order is not supported for anything but HDF5."); 361d930f514SMatthew G. Knepley } 362d930f514SMatthew G. Knepley } 363d930f514SMatthew G. Knepley PetscFunctionReturn(0); 364d930f514SMatthew G. Knepley } 365d930f514SMatthew G. Knepley 366d930f514SMatthew G. Knepley #undef __FUNCT__ 367731e8ddeSMatthew G. Knepley #define __FUNCT__ "DMPlexView_Ascii_Geometry" 368731e8ddeSMatthew G. Knepley PetscErrorCode DMPlexView_Ascii_Geometry(DM dm, PetscViewer viewer) 369731e8ddeSMatthew G. Knepley { 370731e8ddeSMatthew G. Knepley PetscSection coordSection; 371731e8ddeSMatthew G. Knepley Vec coordinates; 372731e8ddeSMatthew G. Knepley DMLabel depthLabel; 373731e8ddeSMatthew G. Knepley const char *name[4]; 374731e8ddeSMatthew G. Knepley const PetscScalar *a; 375731e8ddeSMatthew G. Knepley PetscInt dim, pStart, pEnd, cStart, cEnd, c; 376731e8ddeSMatthew G. Knepley PetscErrorCode ierr; 377731e8ddeSMatthew G. Knepley 378731e8ddeSMatthew G. Knepley PetscFunctionBegin; 379731e8ddeSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 380731e8ddeSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 381731e8ddeSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 382731e8ddeSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 383731e8ddeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 384731e8ddeSMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &pStart, &pEnd);CHKERRQ(ierr); 385731e8ddeSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &a);CHKERRQ(ierr); 386731e8ddeSMatthew G. Knepley name[0] = "vertex"; 387731e8ddeSMatthew G. Knepley name[1] = "edge"; 388731e8ddeSMatthew G. Knepley name[dim-1] = "face"; 389731e8ddeSMatthew G. Knepley name[dim] = "cell"; 390731e8ddeSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 391731e8ddeSMatthew G. Knepley PetscInt *closure = NULL; 392731e8ddeSMatthew G. Knepley PetscInt closureSize, cl; 393731e8ddeSMatthew G. Knepley 394f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "Geometry for cell %D:\n", c);CHKERRQ(ierr); 395731e8ddeSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 396731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 397731e8ddeSMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 398731e8ddeSMatthew G. Knepley PetscInt point = closure[cl], depth, dof, off, d, p; 399731e8ddeSMatthew G. Knepley 400731e8ddeSMatthew G. Knepley if ((point < pStart) || (point >= pEnd)) continue; 401731e8ddeSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 402731e8ddeSMatthew G. Knepley if (!dof) continue; 403731e8ddeSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, point, &depth);CHKERRQ(ierr); 404731e8ddeSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 405f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "%s %D coords:", name[depth], point);CHKERRQ(ierr); 406731e8ddeSMatthew G. Knepley for (p = 0; p < dof/dim; ++p) { 407731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (");CHKERRQ(ierr); 408731e8ddeSMatthew G. Knepley for (d = 0; d < dim; ++d) { 409731e8ddeSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 41041477eefSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%g", PetscRealPart(a[off+p*dim+d]));CHKERRQ(ierr); 411731e8ddeSMatthew G. Knepley } 412731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ")");CHKERRQ(ierr); 413731e8ddeSMatthew G. Knepley } 414731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 415731e8ddeSMatthew G. Knepley } 416731e8ddeSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 417731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 418731e8ddeSMatthew G. Knepley } 419731e8ddeSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &a);CHKERRQ(ierr); 420731e8ddeSMatthew G. Knepley PetscFunctionReturn(0); 421731e8ddeSMatthew G. Knepley } 422731e8ddeSMatthew G. Knepley 423731e8ddeSMatthew G. Knepley #undef __FUNCT__ 424552f7358SJed Brown #define __FUNCT__ "DMPlexView_Ascii" 425552f7358SJed Brown PetscErrorCode DMPlexView_Ascii(DM dm, PetscViewer viewer) 426552f7358SJed Brown { 427552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 428552f7358SJed Brown DM cdm; 429552f7358SJed Brown DMLabel markers; 430552f7358SJed Brown PetscSection coordSection; 431552f7358SJed Brown Vec coordinates; 432552f7358SJed Brown PetscViewerFormat format; 433552f7358SJed Brown PetscErrorCode ierr; 434552f7358SJed Brown 435552f7358SJed Brown PetscFunctionBegin; 436552f7358SJed Brown ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 437552f7358SJed Brown ierr = DMGetDefaultSection(cdm, &coordSection);CHKERRQ(ierr); 438552f7358SJed Brown ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 439552f7358SJed Brown ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 440552f7358SJed Brown if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 441552f7358SJed Brown const char *name; 442552f7358SJed Brown PetscInt maxConeSize, maxSupportSize; 443552f7358SJed Brown PetscInt pStart, pEnd, p; 444552f7358SJed Brown PetscMPIInt rank, size; 445552f7358SJed Brown 44682f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 44782f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 448552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 449552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 450552f7358SJed Brown ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 451552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "Mesh '%s':\n", name);CHKERRQ(ierr); 452552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "orientation is missing\n", name);CHKERRQ(ierr); 453552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "cap --> base:\n", name);CHKERRQ(ierr); 4544d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 4554d4c343aSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max sizes cone: %D support: %D\n", rank,maxConeSize, maxSupportSize);CHKERRQ(ierr); 456552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 457552f7358SJed Brown PetscInt dof, off, s; 458552f7358SJed Brown 459552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 460552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 461552f7358SJed Brown for (s = off; s < off+dof; ++s) { 462e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D ----> %D\n", rank, p, mesh->supports[s]);CHKERRQ(ierr); 463552f7358SJed Brown } 464552f7358SJed Brown } 465552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 466552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "base <-- cap:\n", name);CHKERRQ(ierr); 467552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 468552f7358SJed Brown PetscInt dof, off, c; 469552f7358SJed Brown 470552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 471552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 472552f7358SJed Brown for (c = off; c < off+dof; ++c) { 473e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D <---- %D (%D)\n", rank, p, mesh->cones[c], mesh->coneOrientations[c]);CHKERRQ(ierr); 474552f7358SJed Brown } 475552f7358SJed Brown } 476552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4774d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 4780298fd71SBarry Smith ierr = PetscSectionGetChart(coordSection, &pStart, NULL);CHKERRQ(ierr); 479552f7358SJed Brown if (pStart >= 0) {ierr = PetscSectionVecView(coordSection, coordinates, viewer);CHKERRQ(ierr);} 480c58f1c22SToby Isaac ierr = DMGetLabel(dm, "marker", &markers);CHKERRQ(ierr); 481552f7358SJed Brown ierr = DMLabelView(markers,viewer);CHKERRQ(ierr); 482552f7358SJed Brown if (size > 1) { 483552f7358SJed Brown PetscSF sf; 484552f7358SJed Brown 485552f7358SJed Brown ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 486552f7358SJed Brown ierr = PetscSFView(sf, viewer);CHKERRQ(ierr); 487552f7358SJed Brown } 488552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 489552f7358SJed Brown } else if (format == PETSC_VIEWER_ASCII_LATEX) { 4900588280cSMatthew G. Knepley const char *name, *color; 4910588280cSMatthew G. Knepley const char *defcolors[3] = {"gray", "orange", "green"}; 4920588280cSMatthew G. Knepley const char *deflcolors[4] = {"blue", "cyan", "red", "magenta"}; 493552f7358SJed Brown PetscReal scale = 2.0; 4940588280cSMatthew G. Knepley PetscBool useNumbers = PETSC_TRUE, useLabels, useColors; 4950588280cSMatthew G. Knepley double tcoords[3]; 496552f7358SJed Brown PetscScalar *coords; 4970588280cSMatthew G. Knepley PetscInt numLabels, l, numColors, numLColors, dim, depth, cStart, cEnd, c, vStart, vEnd, v, eStart = 0, eEnd = 0, e, p; 498552f7358SJed Brown PetscMPIInt rank, size; 4990588280cSMatthew G. Knepley char **names, **colors, **lcolors; 500552f7358SJed Brown 5010588280cSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 502552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 503c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 5040588280cSMatthew G. Knepley numLabels = PetscMax(numLabels, 10); 5050588280cSMatthew G. Knepley numColors = 10; 5060588280cSMatthew G. Knepley numLColors = 10; 5070588280cSMatthew G. Knepley ierr = PetscCalloc3(numLabels, &names, numColors, &colors, numLColors, &lcolors);CHKERRQ(ierr); 508c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_scale", &scale, NULL);CHKERRQ(ierr); 509c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_numbers", &useNumbers, NULL);CHKERRQ(ierr); 510c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_labels", names, &numLabels, &useLabels);CHKERRQ(ierr); 5110588280cSMatthew G. Knepley if (!useLabels) numLabels = 0; 512c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_colors", colors, &numColors, &useColors);CHKERRQ(ierr); 5130588280cSMatthew G. Knepley if (!useColors) { 5140588280cSMatthew G. Knepley numColors = 3; 5150588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscStrallocpy(defcolors[c], &colors[c]);CHKERRQ(ierr);} 5160588280cSMatthew G. Knepley } 517c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_lcolors", lcolors, &numLColors, &useColors);CHKERRQ(ierr); 5180588280cSMatthew G. Knepley if (!useColors) { 5190588280cSMatthew G. Knepley numLColors = 4; 5200588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscStrallocpy(deflcolors[c], &lcolors[c]);CHKERRQ(ierr);} 5210588280cSMatthew G. Knepley } 52282f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 52382f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 524552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 525770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\ 5260588280cSMatthew G. Knepley \\documentclass[tikz]{standalone}\n\n\ 527552f7358SJed Brown \\usepackage{pgflibraryshapes}\n\ 528552f7358SJed Brown \\usetikzlibrary{backgrounds}\n\ 529552f7358SJed Brown \\usetikzlibrary{arrows}\n\ 5300588280cSMatthew G. Knepley \\begin{document}\n");CHKERRQ(ierr); 5310588280cSMatthew G. Knepley if (size > 1) { 532f738dd31SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s for process ", name);CHKERRQ(ierr); 533770b213bSMatthew G Knepley for (p = 0; p < size; ++p) { 534770b213bSMatthew G Knepley if (p > 0 && p == size-1) { 535770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", and ", colors[p%numColors], p);CHKERRQ(ierr); 536770b213bSMatthew G Knepley } else if (p > 0) { 537770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", ", colors[p%numColors], p);CHKERRQ(ierr); 538770b213bSMatthew G Knepley } 539770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\\textcolor{%s}%D}", colors[p%numColors], p);CHKERRQ(ierr); 540770b213bSMatthew G Knepley } 5410588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ".\n\n\n");CHKERRQ(ierr); 5420588280cSMatthew G. Knepley } 5430588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\begin{tikzpicture}[scale = %g,font=\\fontsize{8}{8}\\selectfont]\n", 1.0);CHKERRQ(ierr); 544552f7358SJed Brown /* Plot vertices */ 545552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 546552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5474d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 548552f7358SJed Brown for (v = vStart; v < vEnd; ++v) { 549552f7358SJed Brown PetscInt off, dof, d; 5500588280cSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 551552f7358SJed Brown 552552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 553552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5540588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 555f6dae198SJed Brown if (PetscUnlikely(dof > 3)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"coordSection vertex %D has dof %D > 3",v,dof); 5560588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 5570588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 5580588280cSMatthew G. Knepley tcoords[d] = PetscAbsReal(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 5590588280cSMatthew G. Knepley } 5600588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 5610588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 562552f7358SJed Brown for (d = 0; d < dof; ++d) { 563552f7358SJed Brown if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 5640588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", tcoords[d]);CHKERRQ(ierr); 565552f7358SJed Brown } 5660588280cSMatthew G. Knepley color = colors[rank%numColors]; 5670588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 5680588280cSMatthew G. Knepley PetscInt val; 569c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 5700588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 5710588280cSMatthew G. Knepley } 5720588280cSMatthew G. Knepley if (useNumbers) { 573e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", v, rank, color, v);CHKERRQ(ierr); 5740588280cSMatthew G. Knepley } else { 575e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", v, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 5760588280cSMatthew G. Knepley } 577552f7358SJed Brown } 578552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 579552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 580552f7358SJed Brown /* Plot edges */ 5810588280cSMatthew G. Knepley if (depth > 1) {ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);} 5820588280cSMatthew G. Knepley if (dim < 3 && useNumbers) { 583552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 584552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\\path\n");CHKERRQ(ierr); 585552f7358SJed Brown for (e = eStart; e < eEnd; ++e) { 586552f7358SJed Brown const PetscInt *cone; 587552f7358SJed Brown PetscInt coneSize, offA, offB, dof, d; 588552f7358SJed Brown 589552f7358SJed Brown ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 590f347f43bSBarry Smith if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 591552f7358SJed Brown ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 592552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, cone[0], &dof);CHKERRQ(ierr); 593552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 594552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 595552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(");CHKERRQ(ierr); 596552f7358SJed Brown for (d = 0; d < dof; ++d) { 5970588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[offA+d]+coords[offB+d])); 5980588280cSMatthew G. Knepley tcoords[d] = PetscAbsReal(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 599552f7358SJed Brown } 6000588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 6010588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 6020588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 6030588280cSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 604f347f43bSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double)tcoords[d]);CHKERRQ(ierr); 6050588280cSMatthew G. Knepley } 6060588280cSMatthew G. Knepley color = colors[rank%numColors]; 6070588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 6080588280cSMatthew G. Knepley PetscInt val; 609c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 6100750fff4SMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 6110588280cSMatthew G. Knepley } 612e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D} --\n", e, rank, color, e);CHKERRQ(ierr); 613552f7358SJed Brown } 614552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 615552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 616552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "(0,0);\n");CHKERRQ(ierr); 6170588280cSMatthew G. Knepley } 618552f7358SJed Brown /* Plot cells */ 6190588280cSMatthew G. Knepley if (dim == 3 || !useNumbers) { 6200588280cSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 6210588280cSMatthew G. Knepley const PetscInt *cone; 6220588280cSMatthew G. Knepley 6230588280cSMatthew G. Knepley color = colors[rank%numColors]; 6240588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 6250588280cSMatthew G. Knepley PetscInt val; 626c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], e, &val);CHKERRQ(ierr); 6270588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 6280588280cSMatthew G. Knepley } 6290588280cSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 630e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%d) -- (%D_%d);\n", color, cone[0], rank, cone[1], rank);CHKERRQ(ierr); 6310588280cSMatthew G. Knepley } 6320588280cSMatthew G. Knepley } else { 633552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 634552f7358SJed Brown for (c = cStart; c < cEnd; ++c) { 6350298fd71SBarry Smith PetscInt *closure = NULL; 636552f7358SJed Brown PetscInt closureSize, firstPoint = -1; 637552f7358SJed Brown 638552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 639552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] ", colors[rank%numColors]);CHKERRQ(ierr); 640552f7358SJed Brown for (p = 0; p < closureSize*2; p += 2) { 641552f7358SJed Brown const PetscInt point = closure[p]; 642552f7358SJed Brown 643552f7358SJed Brown if ((point < vStart) || (point >= vEnd)) continue; 644552f7358SJed Brown if (firstPoint >= 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- ");CHKERRQ(ierr);} 645e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(%D_%d)", point, rank);CHKERRQ(ierr); 646552f7358SJed Brown if (firstPoint < 0) firstPoint = point; 647552f7358SJed Brown } 648552f7358SJed Brown /* Why doesn't this work? ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- cycle;\n");CHKERRQ(ierr); */ 649e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- (%D_%d);\n", firstPoint, rank);CHKERRQ(ierr); 650552f7358SJed Brown ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 651552f7358SJed Brown } 6520588280cSMatthew G. Knepley } 653552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 6544d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 6550588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{tikzpicture}\n");CHKERRQ(ierr); 656770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{document}\n", name);CHKERRQ(ierr); 6570588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) {ierr = PetscFree(names[l]);CHKERRQ(ierr);} 6580588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscFree(colors[c]);CHKERRQ(ierr);} 6590588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscFree(lcolors[c]);CHKERRQ(ierr);} 6600588280cSMatthew G. Knepley ierr = PetscFree3(names, colors, lcolors);CHKERRQ(ierr); 661552f7358SJed Brown } else { 66282f516ccSBarry Smith MPI_Comm comm; 663834065abSMatthew G. Knepley PetscInt *sizes, *hybsizes; 664834065abSMatthew G. Knepley PetscInt locDepth, depth, dim, d, pMax[4]; 665552f7358SJed Brown PetscInt pStart, pEnd, p; 666a57dd577SMatthew G Knepley PetscInt numLabels, l; 6671143a3c0SMatthew G. Knepley const char *name; 668552f7358SJed Brown PetscMPIInt size; 669552f7358SJed Brown 67082f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 671552f7358SJed Brown ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 672c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6735f64d76eSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 6741143a3c0SMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimensions:\n", name, dim);CHKERRQ(ierr);} 6751143a3c0SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimensions:\n", dim);CHKERRQ(ierr);} 676552f7358SJed Brown ierr = DMPlexGetDepth(dm, &locDepth);CHKERRQ(ierr); 677b2566f29SBarry Smith ierr = MPIU_Allreduce(&locDepth, &depth, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 678bb81ee50SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &pMax[depth], depth > 0 ? &pMax[depth-1] : NULL, &pMax[1], &pMax[0]);CHKERRQ(ierr); 679dcca6d9dSJed Brown ierr = PetscMalloc2(size,&sizes,size,&hybsizes);CHKERRQ(ierr); 680552f7358SJed Brown if (depth == 1) { 681552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 682552f7358SJed Brown pEnd = pEnd - pStart; 683552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 684f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, " %d-cells:", 0);CHKERRQ(ierr); 685552f7358SJed Brown for (p = 0; p < size; ++p) {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 686552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 687552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 688552f7358SJed Brown pEnd = pEnd - pStart; 689552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 690552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", dim);CHKERRQ(ierr); 691552f7358SJed Brown for (p = 0; p < size; ++p) {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 692552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 693552f7358SJed Brown } else { 694552f7358SJed Brown for (d = 0; d <= dim; d++) { 695552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 696834065abSMatthew G. Knepley pEnd -= pStart; 697834065abSMatthew G. Knepley pMax[d] -= pStart; 698552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 699834065abSMatthew G. Knepley ierr = MPI_Gather(&pMax[d], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 700552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", d);CHKERRQ(ierr); 701834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 702834065abSMatthew G. Knepley if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 703834065abSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 704834065abSMatthew G. Knepley } 705552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 706552f7358SJed Brown } 707552f7358SJed Brown } 708834065abSMatthew G. Knepley ierr = PetscFree2(sizes,hybsizes);CHKERRQ(ierr); 709c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 710a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 711a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 712a57dd577SMatthew G Knepley DMLabel label; 713a57dd577SMatthew G Knepley const char *name; 714a57dd577SMatthew G Knepley IS valueIS; 715a57dd577SMatthew G Knepley const PetscInt *values; 716a57dd577SMatthew G Knepley PetscInt numValues, v; 717a57dd577SMatthew G Knepley 718c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 719c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 720a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 721f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, " %s: %D strata of sizes (", name, numValues);CHKERRQ(ierr); 722a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 723a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 724120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 725a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 726a57dd577SMatthew G Knepley PetscInt size; 727a57dd577SMatthew G Knepley 728a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 729a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 730f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "%D", size);CHKERRQ(ierr); 731a57dd577SMatthew G Knepley } 732a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 733120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 734a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 7354d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 736a57dd577SMatthew G Knepley } 737a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dm, &cdm);CHKERRQ(ierr); 7388e7ff633SMatthew G. Knepley if (cdm) { 7398e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 7408e7ff633SMatthew G. Knepley ierr = DMPlexView_Ascii(cdm, viewer);CHKERRQ(ierr); 7418e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 7428e7ff633SMatthew G. Knepley } 743552f7358SJed Brown } 744552f7358SJed Brown PetscFunctionReturn(0); 745552f7358SJed Brown } 746552f7358SJed Brown 747552f7358SJed Brown #undef __FUNCT__ 748*e412dcbdSMatthew G. Knepley #define __FUNCT__ "DMPlexView_Draw" 749*e412dcbdSMatthew G. Knepley PetscErrorCode DMPlexView_Draw(DM dm, PetscViewer viewer) 750*e412dcbdSMatthew G. Knepley { 751*e412dcbdSMatthew G. Knepley PetscDraw draw; 752*e412dcbdSMatthew G. Knepley DM cdm; 753*e412dcbdSMatthew G. Knepley DMLabel markers; 754*e412dcbdSMatthew G. Knepley PetscSection coordSection; 755*e412dcbdSMatthew G. Knepley Vec coordinates; 756*e412dcbdSMatthew G. Knepley const PetscScalar *coords; 757*e412dcbdSMatthew G. Knepley PetscReal bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 758*e412dcbdSMatthew G. Knepley PetscBool isnull; 759*e412dcbdSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N; 760*e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 761*e412dcbdSMatthew G. Knepley 762*e412dcbdSMatthew G. Knepley PetscFunctionBegin; 763*e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 764*e412dcbdSMatthew G. Knepley if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 765*e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 766*e412dcbdSMatthew G. Knepley ierr = DMGetDefaultSection(cdm, &coordSection);CHKERRQ(ierr); 767*e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 768*e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 769*e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 770*e412dcbdSMatthew G. Knepley 771*e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 772*e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 773*e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 774*e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, "Mesh");CHKERRQ(ierr); 775*e412dcbdSMatthew G. Knepley 776*e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 777*e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 778*e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 779*e412dcbdSMatthew G. Knepley bound[0] = PetscMin(bound[0], coords[c]); bound[2] = PetscMax(bound[2], coords[c]); 780*e412dcbdSMatthew G. Knepley bound[1] = PetscMin(bound[1], coords[c+1]); bound[3] = PetscMax(bound[3], coords[c+1]); 781*e412dcbdSMatthew G. Knepley } 782*e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 783*e412dcbdSMatthew G. Knepley ierr = PetscDrawSetCoordinates(draw, bound[0], bound[1], bound[2], bound[3]);CHKERRQ(ierr); 784*e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 785*e412dcbdSMatthew G. Knepley 786*e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 787*e412dcbdSMatthew G. Knepley PetscScalar *coords = NULL; 788*e412dcbdSMatthew G. Knepley PetscInt numCoords; 789*e412dcbdSMatthew G. Knepley 790*e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 791*e412dcbdSMatthew G. Knepley switch (numCoords) { 792*e412dcbdSMatthew G. Knepley case 6: 793*e412dcbdSMatthew G. Knepley ierr = PetscDrawLine(draw, coords[0], coords[1], coords[2], coords[3], PETSC_DRAW_BLACK);CHKERRQ(ierr); 794*e412dcbdSMatthew G. Knepley ierr = PetscDrawLine(draw, coords[2], coords[3], coords[4], coords[5], PETSC_DRAW_BLACK);CHKERRQ(ierr); 795*e412dcbdSMatthew G. Knepley ierr = PetscDrawLine(draw, coords[4], coords[5], coords[0], coords[1], PETSC_DRAW_BLACK);CHKERRQ(ierr); 796*e412dcbdSMatthew G. Knepley break; 797*e412dcbdSMatthew G. Knepley case 8: 798*e412dcbdSMatthew G. Knepley ierr = PetscDrawLine(draw, coords[0], coords[1], coords[2], coords[3], PETSC_DRAW_BLACK);CHKERRQ(ierr); 799*e412dcbdSMatthew G. Knepley ierr = PetscDrawLine(draw, coords[2], coords[3], coords[4], coords[5], PETSC_DRAW_BLACK);CHKERRQ(ierr); 800*e412dcbdSMatthew G. Knepley ierr = PetscDrawLine(draw, coords[4], coords[5], coords[6], coords[7], PETSC_DRAW_BLACK);CHKERRQ(ierr); 801*e412dcbdSMatthew G. Knepley ierr = PetscDrawLine(draw, coords[6], coords[7], coords[0], coords[1], PETSC_DRAW_BLACK);CHKERRQ(ierr); 802*e412dcbdSMatthew G. Knepley break; 803*e412dcbdSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D coordinates", numCoords); 804*e412dcbdSMatthew G. Knepley } 805*e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 806*e412dcbdSMatthew G. Knepley } 807*e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 808*e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 809*e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 810*e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 811*e412dcbdSMatthew G. Knepley } 812*e412dcbdSMatthew G. Knepley 813*e412dcbdSMatthew G. Knepley #undef __FUNCT__ 814552f7358SJed Brown #define __FUNCT__ "DMView_Plex" 815552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 816552f7358SJed Brown { 817*e412dcbdSMatthew G. Knepley PetscBool iascii, ishdf5, isvtk, isdraw; 818552f7358SJed Brown PetscErrorCode ierr; 819552f7358SJed Brown 820552f7358SJed Brown PetscFunctionBegin; 821552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 822552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 823552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 824fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 825c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 826*e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 827552f7358SJed Brown if (iascii) { 828552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 829c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 830c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 8317afe7537SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ);CHKERRQ(ierr); 832c6ccd67eSMatthew G. Knepley ierr = DMPlexView_HDF5(dm, viewer);CHKERRQ(ierr); 8337afe7537SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 834c6ccd67eSMatthew G. Knepley #else 835c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 836552f7358SJed Brown #endif 837*e412dcbdSMatthew G. Knepley } else if (isvtk) { 838fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 839*e412dcbdSMatthew G. Knepley } else if (isdraw) { 840*e412dcbdSMatthew G. Knepley ierr = DMPlexView_Draw(dm, viewer);CHKERRQ(ierr); 841fcf6c8fdSToby Isaac } 842552f7358SJed Brown PetscFunctionReturn(0); 843552f7358SJed Brown } 844552f7358SJed Brown 8452c40f234SMatthew G. Knepley #undef __FUNCT__ 8462c40f234SMatthew G. Knepley #define __FUNCT__ "DMLoad_Plex" 8472c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 8482c40f234SMatthew G. Knepley { 8492c40f234SMatthew G. Knepley PetscBool isbinary, ishdf5; 8502c40f234SMatthew G. Knepley PetscErrorCode ierr; 8512c40f234SMatthew G. Knepley 8522c40f234SMatthew G. Knepley PetscFunctionBegin; 8532c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8542c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 8552c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERBINARY, &isbinary);CHKERRQ(ierr); 8562c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 8572c40f234SMatthew G. Knepley if (isbinary) {SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Do not yet support binary viewers");} 8582c40f234SMatthew G. Knepley else if (ishdf5) { 8592c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 86010b7db4eSMatthew G. Knepley ierr = DMPlexLoad_HDF5(dm, viewer);CHKERRQ(ierr); 8612c40f234SMatthew G. Knepley #else 8622c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 863552f7358SJed Brown #endif 864552f7358SJed Brown } 865552f7358SJed Brown PetscFunctionReturn(0); 866552f7358SJed Brown } 867552f7358SJed Brown 8686c73c22cSMatthew G. Knepley 8696c73c22cSMatthew G. Knepley #undef __FUNCT__ 870552f7358SJed Brown #define __FUNCT__ "DMDestroy_Plex" 871552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 872552f7358SJed Brown { 873552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 874552f7358SJed Brown PetscErrorCode ierr; 875552f7358SJed Brown 876552f7358SJed Brown PetscFunctionBegin; 8770d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 878552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 879552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 880552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 881552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 882552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 883552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 884d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 885d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 88677623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 887a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 888552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 889552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 890a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 891a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 892d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 893d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 894d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 895d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 896d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 897d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 898fec49543SMatthew G. Knepley ierr = PetscGridHashDestroy(&mesh->lbox);CHKERRQ(ierr); 899552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 900552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 901552f7358SJed Brown PetscFunctionReturn(0); 902552f7358SJed Brown } 903552f7358SJed Brown 904552f7358SJed Brown #undef __FUNCT__ 905552f7358SJed Brown #define __FUNCT__ "DMCreateMatrix_Plex" 906b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 907552f7358SJed Brown { 9088d1174e4SMatthew G. Knepley PetscSection sectionGlobal; 909acd755d7SMatthew G. Knepley PetscInt bs = -1, mbs; 910552f7358SJed Brown PetscInt localSize; 91189545effSMatthew G. Knepley PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock; 912552f7358SJed Brown PetscErrorCode ierr; 913b412c318SBarry Smith MatType mtype; 9141428887cSShri Abhyankar ISLocalToGlobalMapping ltog; 915552f7358SJed Brown 916552f7358SJed Brown PetscFunctionBegin; 917607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 918b412c318SBarry Smith mtype = dm->mattype; 919552f7358SJed Brown ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 920552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 921552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 92282f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 923552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 924552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 925552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 926acd755d7SMatthew G. Knepley ierr = MatGetBlockSize(*J, &mbs);CHKERRQ(ierr); 927acd755d7SMatthew G. Knepley if (mbs > 1) bs = mbs; 928552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 929552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 930552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 931552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 932552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 933552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 934552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 935552f7358SJed Brown if (!isShell) { 936552f7358SJed Brown PetscBool fillMatrix = (PetscBool) !dm->prealloc_only; 9372a28c762SMatthew G Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal, bsMax, bsMin; 938fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 939552f7358SJed Brown 940552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 941552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 942a9d99c84SMatthew G. Knepley PetscInt bdof; 943a9d99c84SMatthew G. Knepley 944552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 945fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 9461d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 9471d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 9481d17a0a3SMatthew G. Knepley if (dof) { 9491d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 9501d17a0a3SMatthew G. Knepley else if (bs != bdof) {bs = 1; break;} 951552f7358SJed Brown } 9522a28c762SMatthew G Knepley } 9532a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 9542a28c762SMatthew G Knepley bsLocal = bs; 955b2566f29SBarry Smith ierr = MPIU_Allreduce(&bsLocal, &bsMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 9562a28c762SMatthew G Knepley bsLocal = bs < 0 ? bsMax : bs; 957b2566f29SBarry Smith ierr = MPIU_Allreduce(&bsLocal, &bsMin, 1, MPIU_INT, MPI_MIN, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 958bff27382SMatthew G. Knepley if (bsMin != bsMax) {bs = 1;} 959bff27382SMatthew G. Knepley else {bs = bsMax;} 9601795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 9618d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 962552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 9631428887cSShri Abhyankar 9641428887cSShri Abhyankar /* Set localtoglobalmapping on the matrix for MatSetValuesLocal() to work */ 9651428887cSShri Abhyankar ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 9661428887cSShri Abhyankar ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 967552f7358SJed Brown } 968552f7358SJed Brown PetscFunctionReturn(0); 969552f7358SJed Brown } 970552f7358SJed Brown 971552f7358SJed Brown #undef __FUNCT__ 972552f7358SJed Brown #define __FUNCT__ "DMPlexGetChart" 973552f7358SJed Brown /*@ 974552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 975552f7358SJed Brown 976552f7358SJed Brown Not collective 977552f7358SJed Brown 978552f7358SJed Brown Input Parameter: 979552f7358SJed Brown . mesh - The DMPlex 980552f7358SJed Brown 981552f7358SJed Brown Output Parameters: 982552f7358SJed Brown + pStart - The first mesh point 983552f7358SJed Brown - pEnd - The upper bound for mesh points 984552f7358SJed Brown 985552f7358SJed Brown Level: beginner 986552f7358SJed Brown 987552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 988552f7358SJed Brown @*/ 989552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 990552f7358SJed Brown { 991552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 992552f7358SJed Brown PetscErrorCode ierr; 993552f7358SJed Brown 994552f7358SJed Brown PetscFunctionBegin; 995552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 996552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 997552f7358SJed Brown PetscFunctionReturn(0); 998552f7358SJed Brown } 999552f7358SJed Brown 1000552f7358SJed Brown #undef __FUNCT__ 1001552f7358SJed Brown #define __FUNCT__ "DMPlexSetChart" 1002552f7358SJed Brown /*@ 1003552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 1004552f7358SJed Brown 1005552f7358SJed Brown Not collective 1006552f7358SJed Brown 1007552f7358SJed Brown Input Parameters: 1008552f7358SJed Brown + mesh - The DMPlex 1009552f7358SJed Brown . pStart - The first mesh point 1010552f7358SJed Brown - pEnd - The upper bound for mesh points 1011552f7358SJed Brown 1012552f7358SJed Brown Output Parameters: 1013552f7358SJed Brown 1014552f7358SJed Brown Level: beginner 1015552f7358SJed Brown 1016552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 1017552f7358SJed Brown @*/ 1018552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 1019552f7358SJed Brown { 1020552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1021552f7358SJed Brown PetscErrorCode ierr; 1022552f7358SJed Brown 1023552f7358SJed Brown PetscFunctionBegin; 1024552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1025552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 1026552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 1027552f7358SJed Brown PetscFunctionReturn(0); 1028552f7358SJed Brown } 1029552f7358SJed Brown 1030552f7358SJed Brown #undef __FUNCT__ 1031552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeSize" 1032552f7358SJed Brown /*@ 1033552f7358SJed Brown DMPlexGetConeSize - Return the number of in-edges for this point in the Sieve DAG 1034552f7358SJed Brown 1035552f7358SJed Brown Not collective 1036552f7358SJed Brown 1037552f7358SJed Brown Input Parameters: 1038552f7358SJed Brown + mesh - The DMPlex 1039552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1040552f7358SJed Brown 1041552f7358SJed Brown Output Parameter: 1042552f7358SJed Brown . size - The cone size for point p 1043552f7358SJed Brown 1044552f7358SJed Brown Level: beginner 1045552f7358SJed Brown 1046552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 1047552f7358SJed Brown @*/ 1048552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 1049552f7358SJed Brown { 1050552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1051552f7358SJed Brown PetscErrorCode ierr; 1052552f7358SJed Brown 1053552f7358SJed Brown PetscFunctionBegin; 1054552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1055552f7358SJed Brown PetscValidPointer(size, 3); 1056552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1057552f7358SJed Brown PetscFunctionReturn(0); 1058552f7358SJed Brown } 1059552f7358SJed Brown 1060552f7358SJed Brown #undef __FUNCT__ 1061552f7358SJed Brown #define __FUNCT__ "DMPlexSetConeSize" 1062552f7358SJed Brown /*@ 1063552f7358SJed Brown DMPlexSetConeSize - Set the number of in-edges for this point in the Sieve DAG 1064552f7358SJed Brown 1065552f7358SJed Brown Not collective 1066552f7358SJed Brown 1067552f7358SJed Brown Input Parameters: 1068552f7358SJed Brown + mesh - The DMPlex 1069552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1070552f7358SJed Brown - size - The cone size for point p 1071552f7358SJed Brown 1072552f7358SJed Brown Output Parameter: 1073552f7358SJed Brown 1074552f7358SJed Brown Note: 1075552f7358SJed Brown This should be called after DMPlexSetChart(). 1076552f7358SJed Brown 1077552f7358SJed Brown Level: beginner 1078552f7358SJed Brown 1079552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 1080552f7358SJed Brown @*/ 1081552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 1082552f7358SJed Brown { 1083552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1084552f7358SJed Brown PetscErrorCode ierr; 1085552f7358SJed Brown 1086552f7358SJed Brown PetscFunctionBegin; 1087552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1088552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 10890d644c17SKarl Rupp 1090552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 1091552f7358SJed Brown PetscFunctionReturn(0); 1092552f7358SJed Brown } 1093552f7358SJed Brown 1094552f7358SJed Brown #undef __FUNCT__ 1095f5a469b9SMatthew G. Knepley #define __FUNCT__ "DMPlexAddConeSize" 1096f5a469b9SMatthew G. Knepley /*@ 1097f5a469b9SMatthew G. Knepley DMPlexAddConeSize - Add the given number of in-edges to this point in the Sieve DAG 1098f5a469b9SMatthew G. Knepley 1099f5a469b9SMatthew G. Knepley Not collective 1100f5a469b9SMatthew G. Knepley 1101f5a469b9SMatthew G. Knepley Input Parameters: 1102f5a469b9SMatthew G. Knepley + mesh - The DMPlex 1103f5a469b9SMatthew G. Knepley . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1104f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 1105f5a469b9SMatthew G. Knepley 1106f5a469b9SMatthew G. Knepley Output Parameter: 1107f5a469b9SMatthew G. Knepley 1108f5a469b9SMatthew G. Knepley Note: 1109f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 1110f5a469b9SMatthew G. Knepley 1111f5a469b9SMatthew G. Knepley Level: beginner 1112f5a469b9SMatthew G. Knepley 1113f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 1114f5a469b9SMatthew G. Knepley @*/ 1115f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 1116f5a469b9SMatthew G. Knepley { 1117f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1118f5a469b9SMatthew G. Knepley PetscInt csize; 1119f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 1120f5a469b9SMatthew G. Knepley 1121f5a469b9SMatthew G. Knepley PetscFunctionBegin; 1122f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1123f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1124f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 1125f5a469b9SMatthew G. Knepley 1126f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 1127f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 1128f5a469b9SMatthew G. Knepley } 1129f5a469b9SMatthew G. Knepley 1130f5a469b9SMatthew G. Knepley #undef __FUNCT__ 1131552f7358SJed Brown #define __FUNCT__ "DMPlexGetCone" 1132552f7358SJed Brown /*@C 1133552f7358SJed Brown DMPlexGetCone - Return the points on the in-edges for this point in the Sieve DAG 1134552f7358SJed Brown 1135552f7358SJed Brown Not collective 1136552f7358SJed Brown 1137552f7358SJed Brown Input Parameters: 1138552f7358SJed Brown + mesh - The DMPlex 1139552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1140552f7358SJed Brown 1141552f7358SJed Brown Output Parameter: 1142552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 1143552f7358SJed Brown 1144552f7358SJed Brown Level: beginner 1145552f7358SJed Brown 11463813dfbdSMatthew G Knepley Fortran Notes: 11473813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 11483813dfbdSMatthew G Knepley include petsc.h90 in your code. 11493813dfbdSMatthew G Knepley 11503813dfbdSMatthew G Knepley You must also call DMPlexRestoreCone() after you finish using the returned array. 1151552f7358SJed Brown 1152552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart() 1153552f7358SJed Brown @*/ 1154552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 1155552f7358SJed Brown { 1156552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1157552f7358SJed Brown PetscInt off; 1158552f7358SJed Brown PetscErrorCode ierr; 1159552f7358SJed Brown 1160552f7358SJed Brown PetscFunctionBegin; 1161552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1162552f7358SJed Brown PetscValidPointer(cone, 3); 1163552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1164552f7358SJed Brown *cone = &mesh->cones[off]; 1165552f7358SJed Brown PetscFunctionReturn(0); 1166552f7358SJed Brown } 1167552f7358SJed Brown 1168552f7358SJed Brown #undef __FUNCT__ 1169552f7358SJed Brown #define __FUNCT__ "DMPlexSetCone" 1170552f7358SJed Brown /*@ 1171552f7358SJed Brown DMPlexSetCone - Set the points on the in-edges for this point in the Sieve DAG 1172552f7358SJed Brown 1173552f7358SJed Brown Not collective 1174552f7358SJed Brown 1175552f7358SJed Brown Input Parameters: 1176552f7358SJed Brown + mesh - The DMPlex 1177552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1178552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 1179552f7358SJed Brown 1180552f7358SJed Brown Output Parameter: 1181552f7358SJed Brown 1182552f7358SJed Brown Note: 1183552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1184552f7358SJed Brown 1185552f7358SJed Brown Level: beginner 1186552f7358SJed Brown 1187552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 1188552f7358SJed Brown @*/ 1189552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 1190552f7358SJed Brown { 1191552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1192552f7358SJed Brown PetscInt pStart, pEnd; 1193552f7358SJed Brown PetscInt dof, off, c; 1194552f7358SJed Brown PetscErrorCode ierr; 1195552f7358SJed Brown 1196552f7358SJed Brown PetscFunctionBegin; 1197552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1198552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1199552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1200552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 1201552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 120282f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 1203552f7358SJed Brown for (c = 0; c < dof; ++c) { 120482f516ccSBarry Smith if ((cone[c] < pStart) || (cone[c] >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", cone[c], pStart, pEnd); 1205552f7358SJed Brown mesh->cones[off+c] = cone[c]; 1206552f7358SJed Brown } 1207552f7358SJed Brown PetscFunctionReturn(0); 1208552f7358SJed Brown } 1209552f7358SJed Brown 1210552f7358SJed Brown #undef __FUNCT__ 1211552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeOrientation" 1212552f7358SJed Brown /*@C 1213552f7358SJed Brown DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the Sieve DAG 1214552f7358SJed Brown 1215552f7358SJed Brown Not collective 1216552f7358SJed Brown 1217552f7358SJed Brown Input Parameters: 1218552f7358SJed Brown + mesh - The DMPlex 1219552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1220552f7358SJed Brown 1221552f7358SJed Brown Output Parameter: 1222552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 1223552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 1224552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 1225552f7358SJed Brown the index of the cone point on which to start. 1226552f7358SJed Brown 1227552f7358SJed Brown Level: beginner 1228552f7358SJed Brown 12293813dfbdSMatthew G Knepley Fortran Notes: 12303813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 12313813dfbdSMatthew G Knepley include petsc.h90 in your code. 12323813dfbdSMatthew G Knepley 12333813dfbdSMatthew G Knepley You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 1234552f7358SJed Brown 1235552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 1236552f7358SJed Brown @*/ 1237552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 1238552f7358SJed Brown { 1239552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1240552f7358SJed Brown PetscInt off; 1241552f7358SJed Brown PetscErrorCode ierr; 1242552f7358SJed Brown 1243552f7358SJed Brown PetscFunctionBegin; 1244552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1245552f7358SJed Brown #if defined(PETSC_USE_DEBUG) 1246552f7358SJed Brown { 1247552f7358SJed Brown PetscInt dof; 1248552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1249552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 1250552f7358SJed Brown } 1251552f7358SJed Brown #endif 1252552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 12530d644c17SKarl Rupp 1254552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 1255552f7358SJed Brown PetscFunctionReturn(0); 1256552f7358SJed Brown } 1257552f7358SJed Brown 1258552f7358SJed Brown #undef __FUNCT__ 1259552f7358SJed Brown #define __FUNCT__ "DMPlexSetConeOrientation" 1260552f7358SJed Brown /*@ 1261552f7358SJed Brown DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the Sieve DAG 1262552f7358SJed Brown 1263552f7358SJed Brown Not collective 1264552f7358SJed Brown 1265552f7358SJed Brown Input Parameters: 1266552f7358SJed Brown + mesh - The DMPlex 1267552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1268552f7358SJed Brown - coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 1269552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 1270552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 1271552f7358SJed Brown the index of the cone point on which to start. 1272552f7358SJed Brown 1273552f7358SJed Brown Output Parameter: 1274552f7358SJed Brown 1275552f7358SJed Brown Note: 1276552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1277552f7358SJed Brown 1278552f7358SJed Brown Level: beginner 1279552f7358SJed Brown 1280552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 1281552f7358SJed Brown @*/ 1282552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 1283552f7358SJed Brown { 1284552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1285552f7358SJed Brown PetscInt pStart, pEnd; 1286552f7358SJed Brown PetscInt dof, off, c; 1287552f7358SJed Brown PetscErrorCode ierr; 1288552f7358SJed Brown 1289552f7358SJed Brown PetscFunctionBegin; 1290552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1291552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1292552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1293552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 1294552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 129582f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 1296552f7358SJed Brown for (c = 0; c < dof; ++c) { 1297552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 1298552f7358SJed Brown 1299552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 130082f516ccSBarry Smith if (o && ((o < -(cdof+1)) || (o >= cdof))) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone orientation %D is not in the valid range [%D. %D)", o, -(cdof+1), cdof); 1301552f7358SJed Brown mesh->coneOrientations[off+c] = o; 1302552f7358SJed Brown } 1303552f7358SJed Brown PetscFunctionReturn(0); 1304552f7358SJed Brown } 1305552f7358SJed Brown 1306552f7358SJed Brown #undef __FUNCT__ 1307552f7358SJed Brown #define __FUNCT__ "DMPlexInsertCone" 1308552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 1309552f7358SJed Brown { 1310552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1311552f7358SJed Brown PetscInt pStart, pEnd; 1312552f7358SJed Brown PetscInt dof, off; 1313552f7358SJed Brown PetscErrorCode ierr; 1314552f7358SJed Brown 1315552f7358SJed Brown PetscFunctionBegin; 1316552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1317552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 131882f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 131982f516ccSBarry Smith if ((conePoint < pStart) || (conePoint >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", conePoint, pStart, pEnd); 132077c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 132177c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 132277c88f5bSMatthew G Knepley if ((conePos < 0) || (conePos >= dof)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 1323552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 1324552f7358SJed Brown PetscFunctionReturn(0); 1325552f7358SJed Brown } 1326552f7358SJed Brown 1327552f7358SJed Brown #undef __FUNCT__ 132877c88f5bSMatthew G Knepley #define __FUNCT__ "DMPlexInsertConeOrientation" 132977c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 133077c88f5bSMatthew G Knepley { 133177c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 133277c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 133377c88f5bSMatthew G Knepley PetscInt dof, off; 133477c88f5bSMatthew G Knepley PetscErrorCode ierr; 133577c88f5bSMatthew G Knepley 133677c88f5bSMatthew G Knepley PetscFunctionBegin; 133777c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 133877c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 133977c88f5bSMatthew G Knepley if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 134077c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 134177c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 134277c88f5bSMatthew G Knepley if ((conePos < 0) || (conePos >= dof)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 134377c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 134477c88f5bSMatthew G Knepley PetscFunctionReturn(0); 134577c88f5bSMatthew G Knepley } 134677c88f5bSMatthew G Knepley 134777c88f5bSMatthew G Knepley #undef __FUNCT__ 1348552f7358SJed Brown #define __FUNCT__ "DMPlexGetSupportSize" 1349552f7358SJed Brown /*@ 1350552f7358SJed Brown DMPlexGetSupportSize - Return the number of out-edges for this point in the Sieve DAG 1351552f7358SJed Brown 1352552f7358SJed Brown Not collective 1353552f7358SJed Brown 1354552f7358SJed Brown Input Parameters: 1355552f7358SJed Brown + mesh - The DMPlex 1356552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1357552f7358SJed Brown 1358552f7358SJed Brown Output Parameter: 1359552f7358SJed Brown . size - The support size for point p 1360552f7358SJed Brown 1361552f7358SJed Brown Level: beginner 1362552f7358SJed Brown 1363552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 1364552f7358SJed Brown @*/ 1365552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 1366552f7358SJed Brown { 1367552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1368552f7358SJed Brown PetscErrorCode ierr; 1369552f7358SJed Brown 1370552f7358SJed Brown PetscFunctionBegin; 1371552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1372552f7358SJed Brown PetscValidPointer(size, 3); 1373552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 1374552f7358SJed Brown PetscFunctionReturn(0); 1375552f7358SJed Brown } 1376552f7358SJed Brown 1377552f7358SJed Brown #undef __FUNCT__ 1378552f7358SJed Brown #define __FUNCT__ "DMPlexSetSupportSize" 1379552f7358SJed Brown /*@ 1380552f7358SJed Brown DMPlexSetSupportSize - Set the number of out-edges for this point in the Sieve DAG 1381552f7358SJed Brown 1382552f7358SJed Brown Not collective 1383552f7358SJed Brown 1384552f7358SJed Brown Input Parameters: 1385552f7358SJed Brown + mesh - The DMPlex 1386552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1387552f7358SJed Brown - size - The support size for point p 1388552f7358SJed Brown 1389552f7358SJed Brown Output Parameter: 1390552f7358SJed Brown 1391552f7358SJed Brown Note: 1392552f7358SJed Brown This should be called after DMPlexSetChart(). 1393552f7358SJed Brown 1394552f7358SJed Brown Level: beginner 1395552f7358SJed Brown 1396552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 1397552f7358SJed Brown @*/ 1398552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 1399552f7358SJed Brown { 1400552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1401552f7358SJed Brown PetscErrorCode ierr; 1402552f7358SJed Brown 1403552f7358SJed Brown PetscFunctionBegin; 1404552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1405552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 14060d644c17SKarl Rupp 1407552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 1408552f7358SJed Brown PetscFunctionReturn(0); 1409552f7358SJed Brown } 1410552f7358SJed Brown 1411552f7358SJed Brown #undef __FUNCT__ 1412552f7358SJed Brown #define __FUNCT__ "DMPlexGetSupport" 1413552f7358SJed Brown /*@C 1414552f7358SJed Brown DMPlexGetSupport - Return the points on the out-edges for this point in the Sieve DAG 1415552f7358SJed Brown 1416552f7358SJed Brown Not collective 1417552f7358SJed Brown 1418552f7358SJed Brown Input Parameters: 1419552f7358SJed Brown + mesh - The DMPlex 1420552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1421552f7358SJed Brown 1422552f7358SJed Brown Output Parameter: 1423552f7358SJed Brown . support - An array of points which are on the out-edges for point p 1424552f7358SJed Brown 1425552f7358SJed Brown Level: beginner 1426552f7358SJed Brown 14273813dfbdSMatthew G Knepley Fortran Notes: 14283813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 14293813dfbdSMatthew G Knepley include petsc.h90 in your code. 14303813dfbdSMatthew G Knepley 14313813dfbdSMatthew G Knepley You must also call DMPlexRestoreSupport() after you finish using the returned array. 14323813dfbdSMatthew G Knepley 1433552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1434552f7358SJed Brown @*/ 1435552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 1436552f7358SJed Brown { 1437552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1438552f7358SJed Brown PetscInt off; 1439552f7358SJed Brown PetscErrorCode ierr; 1440552f7358SJed Brown 1441552f7358SJed Brown PetscFunctionBegin; 1442552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1443552f7358SJed Brown PetscValidPointer(support, 3); 1444552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 1445552f7358SJed Brown *support = &mesh->supports[off]; 1446552f7358SJed Brown PetscFunctionReturn(0); 1447552f7358SJed Brown } 1448552f7358SJed Brown 1449552f7358SJed Brown #undef __FUNCT__ 1450552f7358SJed Brown #define __FUNCT__ "DMPlexSetSupport" 1451552f7358SJed Brown /*@ 1452552f7358SJed Brown DMPlexSetSupport - Set the points on the out-edges for this point in the Sieve DAG 1453552f7358SJed Brown 1454552f7358SJed Brown Not collective 1455552f7358SJed Brown 1456552f7358SJed Brown Input Parameters: 1457552f7358SJed Brown + mesh - The DMPlex 1458552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1459552f7358SJed Brown - support - An array of points which are on the in-edges for point p 1460552f7358SJed Brown 1461552f7358SJed Brown Output Parameter: 1462552f7358SJed Brown 1463552f7358SJed Brown Note: 1464552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 1465552f7358SJed Brown 1466552f7358SJed Brown Level: beginner 1467552f7358SJed Brown 1468552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 1469552f7358SJed Brown @*/ 1470552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 1471552f7358SJed Brown { 1472552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1473552f7358SJed Brown PetscInt pStart, pEnd; 1474552f7358SJed Brown PetscInt dof, off, c; 1475552f7358SJed Brown PetscErrorCode ierr; 1476552f7358SJed Brown 1477552f7358SJed Brown PetscFunctionBegin; 1478552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1479552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 1480552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 1481552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 1482552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 148382f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 1484552f7358SJed Brown for (c = 0; c < dof; ++c) { 148582f516ccSBarry Smith if ((support[c] < pStart) || (support[c] >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", support[c], pStart, pEnd); 1486552f7358SJed Brown mesh->supports[off+c] = support[c]; 1487552f7358SJed Brown } 1488552f7358SJed Brown PetscFunctionReturn(0); 1489552f7358SJed Brown } 1490552f7358SJed Brown 1491552f7358SJed Brown #undef __FUNCT__ 1492552f7358SJed Brown #define __FUNCT__ "DMPlexInsertSupport" 1493552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 1494552f7358SJed Brown { 1495552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1496552f7358SJed Brown PetscInt pStart, pEnd; 1497552f7358SJed Brown PetscInt dof, off; 1498552f7358SJed Brown PetscErrorCode ierr; 1499552f7358SJed Brown 1500552f7358SJed Brown PetscFunctionBegin; 1501552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1502552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 1503552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 1504552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 150582f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 150682f516ccSBarry Smith if ((supportPoint < pStart) || (supportPoint >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", supportPoint, pStart, pEnd); 150782f516ccSBarry Smith if (supportPos >= dof) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support position %D of point %D is not in the valid range [0, %D)", supportPos, p, dof); 1508552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 1509552f7358SJed Brown PetscFunctionReturn(0); 1510552f7358SJed Brown } 1511552f7358SJed Brown 1512552f7358SJed Brown #undef __FUNCT__ 1513552f7358SJed Brown #define __FUNCT__ "DMPlexGetTransitiveClosure" 1514552f7358SJed Brown /*@C 1515552f7358SJed Brown DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the Sieve DAG 1516552f7358SJed Brown 1517552f7358SJed Brown Not collective 1518552f7358SJed Brown 1519552f7358SJed Brown Input Parameters: 1520552f7358SJed Brown + mesh - The DMPlex 1521552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1522552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 15230298fd71SBarry Smith - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 1524552f7358SJed Brown 1525552f7358SJed Brown Output Parameters: 1526552f7358SJed Brown + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 1527552f7358SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 1528552f7358SJed Brown 1529552f7358SJed Brown Note: 15300298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 1531552f7358SJed Brown 15323813dfbdSMatthew G Knepley Fortran Notes: 15333813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 15343813dfbdSMatthew G Knepley include petsc.h90 in your code. 15353813dfbdSMatthew G Knepley 15363813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 15373813dfbdSMatthew G Knepley 1538552f7358SJed Brown Level: beginner 1539552f7358SJed Brown 1540552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1541552f7358SJed Brown @*/ 1542552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 1543552f7358SJed Brown { 1544552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1545552f7358SJed Brown PetscInt *closure, *fifo; 15460298fd71SBarry Smith const PetscInt *tmp = NULL, *tmpO = NULL; 1547552f7358SJed Brown PetscInt tmpSize, t; 1548552f7358SJed Brown PetscInt depth = 0, maxSize; 1549552f7358SJed Brown PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 1550552f7358SJed Brown PetscErrorCode ierr; 1551552f7358SJed Brown 1552552f7358SJed Brown PetscFunctionBegin; 1553552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1554552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1555552f7358SJed Brown /* This is only 1-level */ 1556552f7358SJed Brown if (useCone) { 1557552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 1558552f7358SJed Brown ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 1559552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 1560552f7358SJed Brown } else { 1561552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 1562552f7358SJed Brown ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 1563552f7358SJed Brown } 1564bfbcdd7aSMatthew G. Knepley if (depth == 1) { 1565bfbcdd7aSMatthew G. Knepley if (*points) { 1566bfbcdd7aSMatthew G. Knepley closure = *points; 1567bfbcdd7aSMatthew G. Knepley } else { 1568bfbcdd7aSMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 1569bfbcdd7aSMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 1570bfbcdd7aSMatthew G. Knepley } 1571bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 1572bfbcdd7aSMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 1573bfbcdd7aSMatthew G. Knepley closure[closureSize] = tmp[t]; 1574bfbcdd7aSMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[t] : 0; 1575bfbcdd7aSMatthew G. Knepley } 1576bfbcdd7aSMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 1577bfbcdd7aSMatthew G. Knepley if (points) *points = closure; 1578bfbcdd7aSMatthew G. Knepley PetscFunctionReturn(0); 1579bfbcdd7aSMatthew G. Knepley } 158024c766afSToby Isaac { 158124c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 158224c766afSToby Isaac 158324c766afSToby Isaac c = mesh->maxConeSize; 158424c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 158524c766afSToby Isaac s = mesh->maxSupportSize; 158624c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 158724c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 158824c766afSToby Isaac } 1589bfbcdd7aSMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 1590bfbcdd7aSMatthew G. Knepley if (*points) { 1591bfbcdd7aSMatthew G. Knepley closure = *points; 1592bfbcdd7aSMatthew G. Knepley } else { 1593bfbcdd7aSMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 1594bfbcdd7aSMatthew G. Knepley } 1595bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 1596552f7358SJed Brown for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 1597552f7358SJed Brown const PetscInt cp = tmp[t]; 1598552f7358SJed Brown const PetscInt co = tmpO ? tmpO[t] : 0; 1599552f7358SJed Brown 1600552f7358SJed Brown closure[closureSize] = cp; 1601552f7358SJed Brown closure[closureSize+1] = co; 1602552f7358SJed Brown fifo[fifoSize] = cp; 1603552f7358SJed Brown fifo[fifoSize+1] = co; 1604552f7358SJed Brown } 1605bfbcdd7aSMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 1606552f7358SJed Brown while (fifoSize - fifoStart) { 1607552f7358SJed Brown const PetscInt q = fifo[fifoStart]; 1608552f7358SJed Brown const PetscInt o = fifo[fifoStart+1]; 1609552f7358SJed Brown const PetscInt rev = o >= 0 ? 0 : 1; 1610552f7358SJed Brown const PetscInt off = rev ? -(o+1) : o; 1611552f7358SJed Brown 1612552f7358SJed Brown if (useCone) { 1613552f7358SJed Brown ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 1614552f7358SJed Brown ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 1615552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 1616552f7358SJed Brown } else { 1617552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 1618552f7358SJed Brown ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 16190298fd71SBarry Smith tmpO = NULL; 1620552f7358SJed Brown } 1621552f7358SJed Brown for (t = 0; t < tmpSize; ++t) { 1622552f7358SJed Brown const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 1623552f7358SJed Brown const PetscInt cp = tmp[i]; 16242e1b13c2SMatthew G. Knepley /* Must propogate orientation: When we reverse orientation, we both reverse the direction of iteration and start at the other end of the chain. */ 16252e1b13c2SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 16262e1b13c2SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 16272e1b13c2SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 1628552f7358SJed Brown PetscInt c; 1629552f7358SJed Brown 16302e1b13c2SMatthew G. Knepley if (rev) { 16312e1b13c2SMatthew G. Knepley PetscInt childSize, coff; 16322e1b13c2SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 16332e1b13c2SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 16342e1b13c2SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 16352e1b13c2SMatthew G. Knepley } 1636552f7358SJed Brown /* Check for duplicate */ 1637552f7358SJed Brown for (c = 0; c < closureSize; c += 2) { 1638552f7358SJed Brown if (closure[c] == cp) break; 1639552f7358SJed Brown } 1640552f7358SJed Brown if (c == closureSize) { 1641552f7358SJed Brown closure[closureSize] = cp; 1642552f7358SJed Brown closure[closureSize+1] = co; 1643552f7358SJed Brown fifo[fifoSize] = cp; 1644552f7358SJed Brown fifo[fifoSize+1] = co; 1645552f7358SJed Brown closureSize += 2; 1646552f7358SJed Brown fifoSize += 2; 1647552f7358SJed Brown } 1648552f7358SJed Brown } 1649552f7358SJed Brown fifoStart += 2; 1650552f7358SJed Brown } 1651552f7358SJed Brown if (numPoints) *numPoints = closureSize/2; 1652552f7358SJed Brown if (points) *points = closure; 1653552f7358SJed Brown ierr = DMRestoreWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 1654552f7358SJed Brown PetscFunctionReturn(0); 1655552f7358SJed Brown } 1656552f7358SJed Brown 1657552f7358SJed Brown #undef __FUNCT__ 16589bf0dad6SMatthew G. Knepley #define __FUNCT__ "DMPlexGetTransitiveClosure_Internal" 16599bf0dad6SMatthew G. Knepley /*@C 16609bf0dad6SMatthew G. Knepley DMPlexGetTransitiveClosure_Internal - Return the points on the transitive closure of the in-edges or out-edges for this point in the Sieve DAG with a specified initial orientation 16619bf0dad6SMatthew G. Knepley 16629bf0dad6SMatthew G. Knepley Not collective 16639bf0dad6SMatthew G. Knepley 16649bf0dad6SMatthew G. Knepley Input Parameters: 16659bf0dad6SMatthew G. Knepley + mesh - The DMPlex 16669bf0dad6SMatthew G. Knepley . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 16679bf0dad6SMatthew G. Knepley . orientation - The orientation of the point 16689bf0dad6SMatthew G. Knepley . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 16699bf0dad6SMatthew G. Knepley - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 16709bf0dad6SMatthew G. Knepley 16719bf0dad6SMatthew G. Knepley Output Parameters: 16729bf0dad6SMatthew G. Knepley + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 16739bf0dad6SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 16749bf0dad6SMatthew G. Knepley 16759bf0dad6SMatthew G. Knepley Note: 16769bf0dad6SMatthew G. Knepley If using internal storage (points is NULL on input), each call overwrites the last output. 16779bf0dad6SMatthew G. Knepley 16789bf0dad6SMatthew G. Knepley Fortran Notes: 16799bf0dad6SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 16809bf0dad6SMatthew G. Knepley include petsc.h90 in your code. 16819bf0dad6SMatthew G. Knepley 16829bf0dad6SMatthew G. Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 16839bf0dad6SMatthew G. Knepley 16849bf0dad6SMatthew G. Knepley Level: beginner 16859bf0dad6SMatthew G. Knepley 16869bf0dad6SMatthew G. Knepley .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 16879bf0dad6SMatthew G. Knepley @*/ 16889bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 16899bf0dad6SMatthew G. Knepley { 16909bf0dad6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 16919bf0dad6SMatthew G. Knepley PetscInt *closure, *fifo; 16929bf0dad6SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 16939bf0dad6SMatthew G. Knepley PetscInt tmpSize, t; 16949bf0dad6SMatthew G. Knepley PetscInt depth = 0, maxSize; 16959bf0dad6SMatthew G. Knepley PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 16969bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 16979bf0dad6SMatthew G. Knepley 16989bf0dad6SMatthew G. Knepley PetscFunctionBegin; 16999bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17009bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 17019bf0dad6SMatthew G. Knepley /* This is only 1-level */ 17029bf0dad6SMatthew G. Knepley if (useCone) { 17039bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 17049bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 17059bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 17069bf0dad6SMatthew G. Knepley } else { 17079bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 17089bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 17099bf0dad6SMatthew G. Knepley } 17109bf0dad6SMatthew G. Knepley if (depth == 1) { 17119bf0dad6SMatthew G. Knepley if (*points) { 17129bf0dad6SMatthew G. Knepley closure = *points; 17139bf0dad6SMatthew G. Knepley } else { 17149bf0dad6SMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 17159bf0dad6SMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 17169bf0dad6SMatthew G. Knepley } 17179bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 17189bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 17199bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 17209bf0dad6SMatthew G. Knepley closure[closureSize] = tmp[i]; 17219bf0dad6SMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[i] : 0; 17229bf0dad6SMatthew G. Knepley } 17239bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 17249bf0dad6SMatthew G. Knepley if (points) *points = closure; 17259bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 17269bf0dad6SMatthew G. Knepley } 172724c766afSToby Isaac { 172824c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 172924c766afSToby Isaac 173024c766afSToby Isaac c = mesh->maxConeSize; 173124c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 173224c766afSToby Isaac s = mesh->maxSupportSize; 173324c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 173424c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 173524c766afSToby Isaac } 17369bf0dad6SMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 17379bf0dad6SMatthew G. Knepley if (*points) { 17389bf0dad6SMatthew G. Knepley closure = *points; 17399bf0dad6SMatthew G. Knepley } else { 17409bf0dad6SMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 17419bf0dad6SMatthew G. Knepley } 17429bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 17439bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 17449bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 17459bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 17469bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 17479bf0dad6SMatthew G. Knepley 17489bf0dad6SMatthew G. Knepley if (ornt < 0) { 17499bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 17509bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 175186b63641SMatthew G. Knepley coff = co < 0 ? -(tmpO[i]+1) : tmpO[i]; 17529bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 17539bf0dad6SMatthew G. Knepley } 17549bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 17559bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 17569bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 17579bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 17589bf0dad6SMatthew G. Knepley } 17599bf0dad6SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 17609bf0dad6SMatthew G. Knepley while (fifoSize - fifoStart) { 17619bf0dad6SMatthew G. Knepley const PetscInt q = fifo[fifoStart]; 17629bf0dad6SMatthew G. Knepley const PetscInt o = fifo[fifoStart+1]; 17639bf0dad6SMatthew G. Knepley const PetscInt rev = o >= 0 ? 0 : 1; 17649bf0dad6SMatthew G. Knepley const PetscInt off = rev ? -(o+1) : o; 17659bf0dad6SMatthew G. Knepley 17669bf0dad6SMatthew G. Knepley if (useCone) { 17679bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 17689bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 17699bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 17709bf0dad6SMatthew G. Knepley } else { 17719bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 17729bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 17739bf0dad6SMatthew G. Knepley tmpO = NULL; 17749bf0dad6SMatthew G. Knepley } 17759bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 17769bf0dad6SMatthew G. Knepley const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 17779bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 17789bf0dad6SMatthew G. Knepley /* Must propogate orientation: When we reverse orientation, we both reverse the direction of iteration and start at the other end of the chain. */ 17799bf0dad6SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 17809bf0dad6SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 17819bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 17829bf0dad6SMatthew G. Knepley PetscInt c; 17839bf0dad6SMatthew G. Knepley 17849bf0dad6SMatthew G. Knepley if (rev) { 17859bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 17869bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 17879bf0dad6SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 17889bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 17899bf0dad6SMatthew G. Knepley } 17909bf0dad6SMatthew G. Knepley /* Check for duplicate */ 17919bf0dad6SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 17929bf0dad6SMatthew G. Knepley if (closure[c] == cp) break; 17939bf0dad6SMatthew G. Knepley } 17949bf0dad6SMatthew G. Knepley if (c == closureSize) { 17959bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 17969bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 17979bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 17989bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 17999bf0dad6SMatthew G. Knepley closureSize += 2; 18009bf0dad6SMatthew G. Knepley fifoSize += 2; 18019bf0dad6SMatthew G. Knepley } 18029bf0dad6SMatthew G. Knepley } 18039bf0dad6SMatthew G. Knepley fifoStart += 2; 18049bf0dad6SMatthew G. Knepley } 18059bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 18069bf0dad6SMatthew G. Knepley if (points) *points = closure; 18079bf0dad6SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 18089bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 18099bf0dad6SMatthew G. Knepley } 18109bf0dad6SMatthew G. Knepley 18119bf0dad6SMatthew G. Knepley #undef __FUNCT__ 1812552f7358SJed Brown #define __FUNCT__ "DMPlexRestoreTransitiveClosure" 1813552f7358SJed Brown /*@C 1814552f7358SJed Brown DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the Sieve DAG 1815552f7358SJed Brown 1816552f7358SJed Brown Not collective 1817552f7358SJed Brown 1818552f7358SJed Brown Input Parameters: 1819552f7358SJed Brown + mesh - The DMPlex 1820552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1821552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 1822e5c84f05SJed Brown . numPoints - The number of points in the closure, so points[] is of size 2*numPoints, zeroed on exit 1823e5c84f05SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...], zeroed on exit 1824552f7358SJed Brown 1825552f7358SJed Brown Note: 18260298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 1827552f7358SJed Brown 18283813dfbdSMatthew G Knepley Fortran Notes: 18293813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 18303813dfbdSMatthew G Knepley include petsc.h90 in your code. 18313813dfbdSMatthew G Knepley 18323813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 18333813dfbdSMatthew G Knepley 1834552f7358SJed Brown Level: beginner 1835552f7358SJed Brown 1836552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1837552f7358SJed Brown @*/ 1838552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 1839552f7358SJed Brown { 1840552f7358SJed Brown PetscErrorCode ierr; 1841552f7358SJed Brown 1842552f7358SJed Brown PetscFunctionBegin; 1843552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1844e5c84f05SJed Brown if (numPoints) PetscValidIntPointer(numPoints,4); 1845e5c84f05SJed Brown if (points) PetscValidPointer(points,5); 1846552f7358SJed Brown ierr = DMRestoreWorkArray(dm, 0, PETSC_INT, points);CHKERRQ(ierr); 18474ff43b2cSJed Brown if (numPoints) *numPoints = 0; 1848552f7358SJed Brown PetscFunctionReturn(0); 1849552f7358SJed Brown } 1850552f7358SJed Brown 1851552f7358SJed Brown #undef __FUNCT__ 1852552f7358SJed Brown #define __FUNCT__ "DMPlexGetMaxSizes" 1853552f7358SJed Brown /*@ 1854552f7358SJed Brown DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the Sieve DAG 1855552f7358SJed Brown 1856552f7358SJed Brown Not collective 1857552f7358SJed Brown 1858552f7358SJed Brown Input Parameter: 1859552f7358SJed Brown . mesh - The DMPlex 1860552f7358SJed Brown 1861552f7358SJed Brown Output Parameters: 1862552f7358SJed Brown + maxConeSize - The maximum number of in-edges 1863552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 1864552f7358SJed Brown 1865552f7358SJed Brown Level: beginner 1866552f7358SJed Brown 1867552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 1868552f7358SJed Brown @*/ 1869552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 1870552f7358SJed Brown { 1871552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1872552f7358SJed Brown 1873552f7358SJed Brown PetscFunctionBegin; 1874552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1875552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 1876552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 1877552f7358SJed Brown PetscFunctionReturn(0); 1878552f7358SJed Brown } 1879552f7358SJed Brown 1880552f7358SJed Brown #undef __FUNCT__ 1881552f7358SJed Brown #define __FUNCT__ "DMSetUp_Plex" 1882552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 1883552f7358SJed Brown { 1884552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1885552f7358SJed Brown PetscInt size; 1886552f7358SJed Brown PetscErrorCode ierr; 1887552f7358SJed Brown 1888552f7358SJed Brown PetscFunctionBegin; 1889552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1890552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 1891552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 18921795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 18931795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 1894552f7358SJed Brown if (mesh->maxSupportSize) { 1895552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 1896552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 18971795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 1898552f7358SJed Brown } 1899552f7358SJed Brown PetscFunctionReturn(0); 1900552f7358SJed Brown } 1901552f7358SJed Brown 1902552f7358SJed Brown #undef __FUNCT__ 1903552f7358SJed Brown #define __FUNCT__ "DMCreateSubDM_Plex" 1904552f7358SJed Brown PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) 1905552f7358SJed Brown { 1906552f7358SJed Brown PetscErrorCode ierr; 1907552f7358SJed Brown 1908552f7358SJed Brown PetscFunctionBegin; 19094d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 19104d9407bcSMatthew G. Knepley ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 1911552f7358SJed Brown PetscFunctionReturn(0); 1912552f7358SJed Brown } 1913552f7358SJed Brown 1914552f7358SJed Brown #undef __FUNCT__ 1915552f7358SJed Brown #define __FUNCT__ "DMPlexSymmetrize" 1916552f7358SJed Brown /*@ 1917552f7358SJed Brown DMPlexSymmetrize - Creates support (out-edge) information from cone (in-edge) inoformation 1918552f7358SJed Brown 1919552f7358SJed Brown Not collective 1920552f7358SJed Brown 1921552f7358SJed Brown Input Parameter: 1922552f7358SJed Brown . mesh - The DMPlex 1923552f7358SJed Brown 1924552f7358SJed Brown Output Parameter: 1925552f7358SJed Brown 1926552f7358SJed Brown Note: 1927552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 1928552f7358SJed Brown 1929552f7358SJed Brown Level: beginner 1930552f7358SJed Brown 1931552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 1932552f7358SJed Brown @*/ 1933552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 1934552f7358SJed Brown { 1935552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1936552f7358SJed Brown PetscInt *offsets; 1937552f7358SJed Brown PetscInt supportSize; 1938552f7358SJed Brown PetscInt pStart, pEnd, p; 1939552f7358SJed Brown PetscErrorCode ierr; 1940552f7358SJed Brown 1941552f7358SJed Brown PetscFunctionBegin; 1942552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 194382f516ccSBarry Smith if (mesh->supports) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 1944552f7358SJed Brown /* Calculate support sizes */ 1945552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1946552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1947552f7358SJed Brown PetscInt dof, off, c; 1948552f7358SJed Brown 1949552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1950552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1951552f7358SJed Brown for (c = off; c < off+dof; ++c) { 1952552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 1953552f7358SJed Brown } 1954552f7358SJed Brown } 1955552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1956552f7358SJed Brown PetscInt dof; 1957552f7358SJed Brown 1958552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 19590d644c17SKarl Rupp 1960552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 1961552f7358SJed Brown } 1962552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 1963552f7358SJed Brown /* Calculate supports */ 1964552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 19651795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 19661795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 1967552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1968552f7358SJed Brown PetscInt dof, off, c; 1969552f7358SJed Brown 1970552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1971552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1972552f7358SJed Brown for (c = off; c < off+dof; ++c) { 1973552f7358SJed Brown const PetscInt q = mesh->cones[c]; 1974552f7358SJed Brown PetscInt offS; 1975552f7358SJed Brown 1976552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 19770d644c17SKarl Rupp 1978552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 1979552f7358SJed Brown ++offsets[q]; 1980552f7358SJed Brown } 1981552f7358SJed Brown } 1982552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 1983552f7358SJed Brown PetscFunctionReturn(0); 1984552f7358SJed Brown } 1985552f7358SJed Brown 1986552f7358SJed Brown #undef __FUNCT__ 1987552f7358SJed Brown #define __FUNCT__ "DMPlexStratify" 1988552f7358SJed Brown /*@ 1989552f7358SJed Brown DMPlexStratify - The Sieve DAG for most topologies is a graded poset (http://en.wikipedia.org/wiki/Graded_poset), and 1990552f7358SJed Brown can be illustrated by Hasse Diagram (a http://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 1991552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 1992552f7358SJed Brown the DAG. 1993552f7358SJed Brown 1994bf4602e4SToby Isaac Collective on dm 1995552f7358SJed Brown 1996552f7358SJed Brown Input Parameter: 1997552f7358SJed Brown . mesh - The DMPlex 1998552f7358SJed Brown 1999552f7358SJed Brown Output Parameter: 2000552f7358SJed Brown 2001552f7358SJed Brown Notes: 2002150b719bSJed Brown Concretely, DMPlexStratify() creates a new label named "depth" containing the dimension of each element: 0 for vertices, 2003150b719bSJed Brown 1 for edges, and so on. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 2004c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 2005150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 2006552f7358SJed Brown 2007150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 2008552f7358SJed Brown 2009552f7358SJed Brown Level: beginner 2010552f7358SJed Brown 2011552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSymmetrize() 2012552f7358SJed Brown @*/ 2013552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 2014552f7358SJed Brown { 2015df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2016aa50250dSMatthew G. Knepley DMLabel label; 2017552f7358SJed Brown PetscInt pStart, pEnd, p; 2018552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 2019552f7358SJed Brown PetscErrorCode ierr; 2020552f7358SJed Brown 2021552f7358SJed Brown PetscFunctionBegin; 2022552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2023552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2024552f7358SJed Brown /* Calculate depth */ 2025aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2026c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 2027aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2028552f7358SJed Brown /* Initialize roots and count leaves */ 2029552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2030552f7358SJed Brown PetscInt coneSize, supportSize; 2031552f7358SJed Brown 2032552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2033552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2034552f7358SJed Brown if (!coneSize && supportSize) { 2035552f7358SJed Brown ++numRoots; 2036aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 0);CHKERRQ(ierr); 2037552f7358SJed Brown } else if (!supportSize && coneSize) { 2038552f7358SJed Brown ++numLeaves; 2039552f7358SJed Brown } else if (!supportSize && !coneSize) { 2040552f7358SJed Brown /* Isolated points */ 2041aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 0);CHKERRQ(ierr); 2042552f7358SJed Brown } 2043552f7358SJed Brown } 2044552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 2045552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2046552f7358SJed Brown PetscInt coneSize, supportSize; 2047552f7358SJed Brown 2048552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2049552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2050552f7358SJed Brown if (!supportSize && coneSize) { 2051aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 1);CHKERRQ(ierr); 2052552f7358SJed Brown } 2053552f7358SJed Brown } 2054552f7358SJed Brown } else { 205574ef644bSMatthew G. Knepley IS pointIS; 205674ef644bSMatthew G. Knepley PetscInt numPoints = 0, level = 0; 2057552f7358SJed Brown 205874ef644bSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, level, &pointIS);CHKERRQ(ierr); 205974ef644bSMatthew G. Knepley if (pointIS) {ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);} 206074ef644bSMatthew G. Knepley while (numPoints) { 206174ef644bSMatthew G. Knepley const PetscInt *points; 206274ef644bSMatthew G. Knepley const PetscInt newLevel = level+1; 206374ef644bSMatthew G. Knepley 206474ef644bSMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 206574ef644bSMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 206674ef644bSMatthew G. Knepley const PetscInt point = points[p]; 206774ef644bSMatthew G. Knepley const PetscInt *support; 206874ef644bSMatthew G. Knepley PetscInt supportSize, s; 206974ef644bSMatthew G. Knepley 207074ef644bSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, point, &supportSize);CHKERRQ(ierr); 207174ef644bSMatthew G. Knepley ierr = DMPlexGetSupport(dm, point, &support);CHKERRQ(ierr); 207274ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 207374ef644bSMatthew G. Knepley ierr = DMLabelSetValue(label, support[s], newLevel);CHKERRQ(ierr); 2074552f7358SJed Brown } 2075552f7358SJed Brown } 20765edfc765SMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 207774ef644bSMatthew G. Knepley ++level; 207874ef644bSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 207974ef644bSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, level, &pointIS);CHKERRQ(ierr); 208074ef644bSMatthew G. Knepley if (pointIS) {ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);} 208174ef644bSMatthew G. Knepley else {numPoints = 0;} 208274ef644bSMatthew G. Knepley } 208374ef644bSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 208474ef644bSMatthew G. Knepley } 2085bf4602e4SToby Isaac { /* just in case there is an empty process */ 2086bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 2087bf4602e4SToby Isaac 2088bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label,&numValues);CHKERRQ(ierr); 20896d1e82d3SBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 2090bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 2091bf4602e4SToby Isaac DMLabelAddStratum(label,v);CHKERRQ(ierr); 2092bf4602e4SToby Isaac } 2093bf4602e4SToby Isaac } 2094bf4602e4SToby Isaac 2095df0420ecSMatthew G. Knepley ierr = DMLabelGetState(label, &mesh->depthState);CHKERRQ(ierr); 2096552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2097552f7358SJed Brown PetscFunctionReturn(0); 2098552f7358SJed Brown } 2099552f7358SJed Brown 2100552f7358SJed Brown #undef __FUNCT__ 2101552f7358SJed Brown #define __FUNCT__ "DMPlexGetJoin" 2102552f7358SJed Brown /*@C 2103552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 2104552f7358SJed Brown 2105552f7358SJed Brown Not Collective 2106552f7358SJed Brown 2107552f7358SJed Brown Input Parameters: 2108552f7358SJed Brown + dm - The DMPlex object 2109552f7358SJed Brown . numPoints - The number of input points for the join 2110552f7358SJed Brown - points - The input points 2111552f7358SJed Brown 2112552f7358SJed Brown Output Parameters: 2113552f7358SJed Brown + numCoveredPoints - The number of points in the join 2114552f7358SJed Brown - coveredPoints - The points in the join 2115552f7358SJed Brown 2116552f7358SJed Brown Level: intermediate 2117552f7358SJed Brown 2118552f7358SJed Brown Note: Currently, this is restricted to a single level join 2119552f7358SJed Brown 21203813dfbdSMatthew G Knepley Fortran Notes: 21213813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 21223813dfbdSMatthew G Knepley include petsc.h90 in your code. 21233813dfbdSMatthew G Knepley 21243813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 21253813dfbdSMatthew G Knepley 2126552f7358SJed Brown .keywords: mesh 2127552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 2128552f7358SJed Brown @*/ 2129552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2130552f7358SJed Brown { 2131552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2132552f7358SJed Brown PetscInt *join[2]; 2133552f7358SJed Brown PetscInt joinSize, i = 0; 2134552f7358SJed Brown PetscInt dof, off, p, c, m; 2135552f7358SJed Brown PetscErrorCode ierr; 2136552f7358SJed Brown 2137552f7358SJed Brown PetscFunctionBegin; 2138552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2139552f7358SJed Brown PetscValidPointer(points, 2); 2140552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 2141552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 2142552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[0]);CHKERRQ(ierr); 2143552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[1]);CHKERRQ(ierr); 2144552f7358SJed Brown /* Copy in support of first point */ 2145552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 2146552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 2147552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 2148552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 2149552f7358SJed Brown } 2150552f7358SJed Brown /* Check each successive support */ 2151552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 2152552f7358SJed Brown PetscInt newJoinSize = 0; 2153552f7358SJed Brown 2154552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 2155552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 2156552f7358SJed Brown for (c = 0; c < dof; ++c) { 2157552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 2158552f7358SJed Brown 2159552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 2160552f7358SJed Brown if (point == join[i][m]) { 2161552f7358SJed Brown join[1-i][newJoinSize++] = point; 2162552f7358SJed Brown break; 2163552f7358SJed Brown } 2164552f7358SJed Brown } 2165552f7358SJed Brown } 2166552f7358SJed Brown joinSize = newJoinSize; 2167552f7358SJed Brown i = 1-i; 2168552f7358SJed Brown } 2169552f7358SJed Brown *numCoveredPoints = joinSize; 2170552f7358SJed Brown *coveredPoints = join[i]; 2171552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[1-i]);CHKERRQ(ierr); 2172552f7358SJed Brown PetscFunctionReturn(0); 2173552f7358SJed Brown } 2174552f7358SJed Brown 2175552f7358SJed Brown #undef __FUNCT__ 2176552f7358SJed Brown #define __FUNCT__ "DMPlexRestoreJoin" 2177552f7358SJed Brown /*@C 2178552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 2179552f7358SJed Brown 2180552f7358SJed Brown Not Collective 2181552f7358SJed Brown 2182552f7358SJed Brown Input Parameters: 2183552f7358SJed Brown + dm - The DMPlex object 2184552f7358SJed Brown . numPoints - The number of input points for the join 2185552f7358SJed Brown - points - The input points 2186552f7358SJed Brown 2187552f7358SJed Brown Output Parameters: 2188552f7358SJed Brown + numCoveredPoints - The number of points in the join 2189552f7358SJed Brown - coveredPoints - The points in the join 2190552f7358SJed Brown 21913813dfbdSMatthew G Knepley Fortran Notes: 21923813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 21933813dfbdSMatthew G Knepley include petsc.h90 in your code. 21943813dfbdSMatthew G Knepley 21953813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 21963813dfbdSMatthew G Knepley 2197552f7358SJed Brown Level: intermediate 2198552f7358SJed Brown 2199552f7358SJed Brown .keywords: mesh 2200552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 2201552f7358SJed Brown @*/ 2202552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2203552f7358SJed Brown { 2204552f7358SJed Brown PetscErrorCode ierr; 2205552f7358SJed Brown 2206552f7358SJed Brown PetscFunctionBegin; 2207552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2208d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 2209d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 2210d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 2211552f7358SJed Brown ierr = DMRestoreWorkArray(dm, 0, PETSC_INT, (void*) coveredPoints);CHKERRQ(ierr); 2212d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 2213552f7358SJed Brown PetscFunctionReturn(0); 2214552f7358SJed Brown } 2215552f7358SJed Brown 2216552f7358SJed Brown #undef __FUNCT__ 2217552f7358SJed Brown #define __FUNCT__ "DMPlexGetFullJoin" 2218552f7358SJed Brown /*@C 2219552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 2220552f7358SJed Brown 2221552f7358SJed Brown Not Collective 2222552f7358SJed Brown 2223552f7358SJed Brown Input Parameters: 2224552f7358SJed Brown + dm - The DMPlex object 2225552f7358SJed Brown . numPoints - The number of input points for the join 2226552f7358SJed Brown - points - The input points 2227552f7358SJed Brown 2228552f7358SJed Brown Output Parameters: 2229552f7358SJed Brown + numCoveredPoints - The number of points in the join 2230552f7358SJed Brown - coveredPoints - The points in the join 2231552f7358SJed Brown 22323813dfbdSMatthew G Knepley Fortran Notes: 22333813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 22343813dfbdSMatthew G Knepley include petsc.h90 in your code. 22353813dfbdSMatthew G Knepley 22363813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 22373813dfbdSMatthew G Knepley 2238552f7358SJed Brown Level: intermediate 2239552f7358SJed Brown 2240552f7358SJed Brown .keywords: mesh 2241552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 2242552f7358SJed Brown @*/ 2243552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2244552f7358SJed Brown { 2245552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2246552f7358SJed Brown PetscInt *offsets, **closures; 2247552f7358SJed Brown PetscInt *join[2]; 2248552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 224924c766afSToby Isaac PetscInt p, d, c, m, ms; 2250552f7358SJed Brown PetscErrorCode ierr; 2251552f7358SJed Brown 2252552f7358SJed Brown PetscFunctionBegin; 2253552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2254552f7358SJed Brown PetscValidPointer(points, 2); 2255552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 2256552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 2257552f7358SJed Brown 2258552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 22591795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 2260552f7358SJed Brown ierr = DMGetWorkArray(dm, numPoints*(depth+2), PETSC_INT, &offsets);CHKERRQ(ierr); 226124c766afSToby Isaac ms = mesh->maxSupportSize; 226224c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 2263552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &join[0]);CHKERRQ(ierr); 2264552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &join[1]);CHKERRQ(ierr); 2265552f7358SJed Brown 2266552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 2267552f7358SJed Brown PetscInt closureSize; 2268552f7358SJed Brown 2269552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 22700d644c17SKarl Rupp 2271552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 2272552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 2273552f7358SJed Brown PetscInt pStart, pEnd, i; 2274552f7358SJed Brown 2275552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 2276552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 2277552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 2278552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 2279552f7358SJed Brown break; 2280552f7358SJed Brown } 2281552f7358SJed Brown } 2282552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 2283552f7358SJed Brown } 228482f516ccSBarry Smith if (offsets[p*(depth+2)+depth+1] != closureSize) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(depth+2)+depth+1], closureSize); 2285552f7358SJed Brown } 2286552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 2287552f7358SJed Brown PetscInt dof; 2288552f7358SJed Brown 2289552f7358SJed Brown /* Copy in support of first point */ 2290552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 2291552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 2292552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 2293552f7358SJed Brown } 2294552f7358SJed Brown /* Check each successive cone */ 2295552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 2296552f7358SJed Brown PetscInt newJoinSize = 0; 2297552f7358SJed Brown 2298552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 2299552f7358SJed Brown for (c = 0; c < dof; ++c) { 2300552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 2301552f7358SJed Brown 2302552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 2303552f7358SJed Brown if (point == join[i][m]) { 2304552f7358SJed Brown join[1-i][newJoinSize++] = point; 2305552f7358SJed Brown break; 2306552f7358SJed Brown } 2307552f7358SJed Brown } 2308552f7358SJed Brown } 2309552f7358SJed Brown joinSize = newJoinSize; 2310552f7358SJed Brown i = 1-i; 2311552f7358SJed Brown } 2312552f7358SJed Brown if (joinSize) break; 2313552f7358SJed Brown } 2314552f7358SJed Brown *numCoveredPoints = joinSize; 2315552f7358SJed Brown *coveredPoints = join[i]; 2316552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 23170298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 2318552f7358SJed Brown } 2319552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 2320552f7358SJed Brown ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), PETSC_INT, &offsets);CHKERRQ(ierr); 2321552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[1-i]);CHKERRQ(ierr); 2322552f7358SJed Brown PetscFunctionReturn(0); 2323552f7358SJed Brown } 2324552f7358SJed Brown 2325552f7358SJed Brown #undef __FUNCT__ 2326552f7358SJed Brown #define __FUNCT__ "DMPlexGetMeet" 2327552f7358SJed Brown /*@C 2328552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 2329552f7358SJed Brown 2330552f7358SJed Brown Not Collective 2331552f7358SJed Brown 2332552f7358SJed Brown Input Parameters: 2333552f7358SJed Brown + dm - The DMPlex object 2334552f7358SJed Brown . numPoints - The number of input points for the meet 2335552f7358SJed Brown - points - The input points 2336552f7358SJed Brown 2337552f7358SJed Brown Output Parameters: 2338552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2339552f7358SJed Brown - coveredPoints - The points in the meet 2340552f7358SJed Brown 2341552f7358SJed Brown Level: intermediate 2342552f7358SJed Brown 2343552f7358SJed Brown Note: Currently, this is restricted to a single level meet 2344552f7358SJed Brown 23453813dfbdSMatthew G Knepley Fortran Notes: 23463813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 23473813dfbdSMatthew G Knepley include petsc.h90 in your code. 23483813dfbdSMatthew G Knepley 23493813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 23503813dfbdSMatthew G Knepley 2351552f7358SJed Brown .keywords: mesh 2352552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 2353552f7358SJed Brown @*/ 2354552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 2355552f7358SJed Brown { 2356552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2357552f7358SJed Brown PetscInt *meet[2]; 2358552f7358SJed Brown PetscInt meetSize, i = 0; 2359552f7358SJed Brown PetscInt dof, off, p, c, m; 2360552f7358SJed Brown PetscErrorCode ierr; 2361552f7358SJed Brown 2362552f7358SJed Brown PetscFunctionBegin; 2363552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2364552f7358SJed Brown PetscValidPointer(points, 2); 2365552f7358SJed Brown PetscValidPointer(numCoveringPoints, 3); 2366552f7358SJed Brown PetscValidPointer(coveringPoints, 4); 2367552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[0]);CHKERRQ(ierr); 2368552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[1]);CHKERRQ(ierr); 2369552f7358SJed Brown /* Copy in cone of first point */ 2370552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 2371552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 2372552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 2373552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 2374552f7358SJed Brown } 2375552f7358SJed Brown /* Check each successive cone */ 2376552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 2377552f7358SJed Brown PetscInt newMeetSize = 0; 2378552f7358SJed Brown 2379552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 2380552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 2381552f7358SJed Brown for (c = 0; c < dof; ++c) { 2382552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 2383552f7358SJed Brown 2384552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 2385552f7358SJed Brown if (point == meet[i][m]) { 2386552f7358SJed Brown meet[1-i][newMeetSize++] = point; 2387552f7358SJed Brown break; 2388552f7358SJed Brown } 2389552f7358SJed Brown } 2390552f7358SJed Brown } 2391552f7358SJed Brown meetSize = newMeetSize; 2392552f7358SJed Brown i = 1-i; 2393552f7358SJed Brown } 2394552f7358SJed Brown *numCoveringPoints = meetSize; 2395552f7358SJed Brown *coveringPoints = meet[i]; 2396552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[1-i]);CHKERRQ(ierr); 2397552f7358SJed Brown PetscFunctionReturn(0); 2398552f7358SJed Brown } 2399552f7358SJed Brown 2400552f7358SJed Brown #undef __FUNCT__ 2401552f7358SJed Brown #define __FUNCT__ "DMPlexRestoreMeet" 2402552f7358SJed Brown /*@C 2403552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 2404552f7358SJed Brown 2405552f7358SJed Brown Not Collective 2406552f7358SJed Brown 2407552f7358SJed Brown Input Parameters: 2408552f7358SJed Brown + dm - The DMPlex object 2409552f7358SJed Brown . numPoints - The number of input points for the meet 2410552f7358SJed Brown - points - The input points 2411552f7358SJed Brown 2412552f7358SJed Brown Output Parameters: 2413552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2414552f7358SJed Brown - coveredPoints - The points in the meet 2415552f7358SJed Brown 2416552f7358SJed Brown Level: intermediate 2417552f7358SJed Brown 24183813dfbdSMatthew G Knepley Fortran Notes: 24193813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 24203813dfbdSMatthew G Knepley include petsc.h90 in your code. 24213813dfbdSMatthew G Knepley 24223813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 24233813dfbdSMatthew G Knepley 2424552f7358SJed Brown .keywords: mesh 2425552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 2426552f7358SJed Brown @*/ 2427552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2428552f7358SJed Brown { 2429552f7358SJed Brown PetscErrorCode ierr; 2430552f7358SJed Brown 2431552f7358SJed Brown PetscFunctionBegin; 2432552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2433d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 2434d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 2435d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 2436552f7358SJed Brown ierr = DMRestoreWorkArray(dm, 0, PETSC_INT, (void*) coveredPoints);CHKERRQ(ierr); 2437d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 2438552f7358SJed Brown PetscFunctionReturn(0); 2439552f7358SJed Brown } 2440552f7358SJed Brown 2441552f7358SJed Brown #undef __FUNCT__ 2442552f7358SJed Brown #define __FUNCT__ "DMPlexGetFullMeet" 2443552f7358SJed Brown /*@C 2444552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 2445552f7358SJed Brown 2446552f7358SJed Brown Not Collective 2447552f7358SJed Brown 2448552f7358SJed Brown Input Parameters: 2449552f7358SJed Brown + dm - The DMPlex object 2450552f7358SJed Brown . numPoints - The number of input points for the meet 2451552f7358SJed Brown - points - The input points 2452552f7358SJed Brown 2453552f7358SJed Brown Output Parameters: 2454552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2455552f7358SJed Brown - coveredPoints - The points in the meet 2456552f7358SJed Brown 2457552f7358SJed Brown Level: intermediate 2458552f7358SJed Brown 24593813dfbdSMatthew G Knepley Fortran Notes: 24603813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 24613813dfbdSMatthew G Knepley include petsc.h90 in your code. 24623813dfbdSMatthew G Knepley 24633813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 24643813dfbdSMatthew G Knepley 2465552f7358SJed Brown .keywords: mesh 2466552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 2467552f7358SJed Brown @*/ 2468552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2469552f7358SJed Brown { 2470552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2471552f7358SJed Brown PetscInt *offsets, **closures; 2472552f7358SJed Brown PetscInt *meet[2]; 2473552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 247424c766afSToby Isaac PetscInt p, h, c, m, mc; 2475552f7358SJed Brown PetscErrorCode ierr; 2476552f7358SJed Brown 2477552f7358SJed Brown PetscFunctionBegin; 2478552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2479552f7358SJed Brown PetscValidPointer(points, 2); 2480552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 2481552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 2482552f7358SJed Brown 2483552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 2484785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 2485552f7358SJed Brown ierr = DMGetWorkArray(dm, numPoints*(height+2), PETSC_INT, &offsets);CHKERRQ(ierr); 248624c766afSToby Isaac mc = mesh->maxConeSize; 248724c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 2488552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &meet[0]);CHKERRQ(ierr); 2489552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &meet[1]);CHKERRQ(ierr); 2490552f7358SJed Brown 2491552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 2492552f7358SJed Brown PetscInt closureSize; 2493552f7358SJed Brown 2494552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 24950d644c17SKarl Rupp 2496552f7358SJed Brown offsets[p*(height+2)+0] = 0; 2497552f7358SJed Brown for (h = 0; h < height+1; ++h) { 2498552f7358SJed Brown PetscInt pStart, pEnd, i; 2499552f7358SJed Brown 2500552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 2501552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 2502552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 2503552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 2504552f7358SJed Brown break; 2505552f7358SJed Brown } 2506552f7358SJed Brown } 2507552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 2508552f7358SJed Brown } 250982f516ccSBarry Smith if (offsets[p*(height+2)+height+1] != closureSize) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(height+2)+height+1], closureSize); 2510552f7358SJed Brown } 2511552f7358SJed Brown for (h = 0; h < height+1; ++h) { 2512552f7358SJed Brown PetscInt dof; 2513552f7358SJed Brown 2514552f7358SJed Brown /* Copy in cone of first point */ 2515552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 2516552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 2517552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 2518552f7358SJed Brown } 2519552f7358SJed Brown /* Check each successive cone */ 2520552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 2521552f7358SJed Brown PetscInt newMeetSize = 0; 2522552f7358SJed Brown 2523552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 2524552f7358SJed Brown for (c = 0; c < dof; ++c) { 2525552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 2526552f7358SJed Brown 2527552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 2528552f7358SJed Brown if (point == meet[i][m]) { 2529552f7358SJed Brown meet[1-i][newMeetSize++] = point; 2530552f7358SJed Brown break; 2531552f7358SJed Brown } 2532552f7358SJed Brown } 2533552f7358SJed Brown } 2534552f7358SJed Brown meetSize = newMeetSize; 2535552f7358SJed Brown i = 1-i; 2536552f7358SJed Brown } 2537552f7358SJed Brown if (meetSize) break; 2538552f7358SJed Brown } 2539552f7358SJed Brown *numCoveredPoints = meetSize; 2540552f7358SJed Brown *coveredPoints = meet[i]; 2541552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 25420298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 2543552f7358SJed Brown } 2544552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 2545552f7358SJed Brown ierr = DMRestoreWorkArray(dm, numPoints*(height+2), PETSC_INT, &offsets);CHKERRQ(ierr); 2546552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[1-i]);CHKERRQ(ierr); 2547552f7358SJed Brown PetscFunctionReturn(0); 2548552f7358SJed Brown } 2549552f7358SJed Brown 2550552f7358SJed Brown #undef __FUNCT__ 25514e3744c5SMatthew G. Knepley #define __FUNCT__ "DMPlexEqual" 25524e3744c5SMatthew G. Knepley /*@C 25534e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 25544e3744c5SMatthew G. Knepley 25554e3744c5SMatthew G. Knepley Not Collective 25564e3744c5SMatthew G. Knepley 25574e3744c5SMatthew G. Knepley Input Parameters: 25584e3744c5SMatthew G. Knepley + dmA - A DMPlex object 25594e3744c5SMatthew G. Knepley - dmB - A DMPlex object 25604e3744c5SMatthew G. Knepley 25614e3744c5SMatthew G. Knepley Output Parameters: 25624e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 25634e3744c5SMatthew G. Knepley 25644e3744c5SMatthew G. Knepley Level: intermediate 25654e3744c5SMatthew G. Knepley 25664e3744c5SMatthew G. Knepley Notes: 25674e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 25684e3744c5SMatthew G. Knepley 25694e3744c5SMatthew G. Knepley .keywords: mesh 25704e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 25714e3744c5SMatthew G. Knepley @*/ 25724e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 25734e3744c5SMatthew G. Knepley { 25744e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 25754e3744c5SMatthew G. Knepley PetscErrorCode ierr; 25764e3744c5SMatthew G. Knepley 25774e3744c5SMatthew G. Knepley PetscFunctionBegin; 25784e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 25794e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 25804e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 25814e3744c5SMatthew G. Knepley 25824e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 25834e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 25844e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 25854e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 25864e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 25874e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 25884e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 25894e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 25904e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 25914e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 25924e3744c5SMatthew G. Knepley 25934e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 25944e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 25954e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 25964e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 25974e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 25984e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 25994e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 26004e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 26014e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 26024e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 26034e3744c5SMatthew G. Knepley } 26044e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 26054e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 26064e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 26074e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 26084e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 26094e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 26104e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 26114e3744c5SMatthew G. Knepley } 26124e3744c5SMatthew G. Knepley } 26134e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 26144e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 26154e3744c5SMatthew G. Knepley } 26164e3744c5SMatthew G. Knepley 26174e3744c5SMatthew G. Knepley #undef __FUNCT__ 261818ad9376SMatthew G. Knepley #define __FUNCT__ "DMPlexGetNumFaceVertices" 261918ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 2620a6dfd86eSKarl Rupp { 262182f516ccSBarry Smith MPI_Comm comm; 2622552f7358SJed Brown PetscErrorCode ierr; 2623552f7358SJed Brown 2624552f7358SJed Brown PetscFunctionBegin; 262582f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2626552f7358SJed Brown PetscValidPointer(numFaceVertices,3); 2627552f7358SJed Brown switch (cellDim) { 2628552f7358SJed Brown case 0: 2629552f7358SJed Brown *numFaceVertices = 0; 2630552f7358SJed Brown break; 2631552f7358SJed Brown case 1: 2632552f7358SJed Brown *numFaceVertices = 1; 2633552f7358SJed Brown break; 2634552f7358SJed Brown case 2: 2635552f7358SJed Brown switch (numCorners) { 263619436ca2SJed Brown case 3: /* triangle */ 263719436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 2638552f7358SJed Brown break; 263919436ca2SJed Brown case 4: /* quadrilateral */ 264019436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 2641552f7358SJed Brown break; 264219436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 264319436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 2644552f7358SJed Brown break; 264519436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 264619436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 2647552f7358SJed Brown break; 2648552f7358SJed Brown default: 2649f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 2650552f7358SJed Brown } 2651552f7358SJed Brown break; 2652552f7358SJed Brown case 3: 2653552f7358SJed Brown switch (numCorners) { 265419436ca2SJed Brown case 4: /* tetradehdron */ 265519436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 2656552f7358SJed Brown break; 265719436ca2SJed Brown case 6: /* tet cohesive cells */ 265819436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 2659552f7358SJed Brown break; 266019436ca2SJed Brown case 8: /* hexahedron */ 266119436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 2662552f7358SJed Brown break; 266319436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 266419436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2665552f7358SJed Brown break; 266619436ca2SJed Brown case 10: /* quadratic tetrahedron */ 266719436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2668552f7358SJed Brown break; 266919436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 267019436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2671552f7358SJed Brown break; 267219436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 267319436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2674552f7358SJed Brown break; 267519436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 267619436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 2677552f7358SJed Brown break; 2678552f7358SJed Brown default: 2679f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 2680552f7358SJed Brown } 2681552f7358SJed Brown break; 2682552f7358SJed Brown default: 2683f347f43bSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 2684552f7358SJed Brown } 2685552f7358SJed Brown PetscFunctionReturn(0); 2686552f7358SJed Brown } 2687552f7358SJed Brown 2688552f7358SJed Brown #undef __FUNCT__ 2689aa50250dSMatthew G. Knepley #define __FUNCT__ "DMPlexGetDepthLabel" 2690552f7358SJed Brown /*@ 2691aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 2692552f7358SJed Brown 2693552f7358SJed Brown Not Collective 2694552f7358SJed Brown 2695aa50250dSMatthew G. Knepley Input Parameter: 2696552f7358SJed Brown . dm - The DMPlex object 2697552f7358SJed Brown 2698aa50250dSMatthew G. Knepley Output Parameter: 2699aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 2700552f7358SJed Brown 2701552f7358SJed Brown Level: developer 2702552f7358SJed Brown 2703aa50250dSMatthew G. Knepley .keywords: mesh, points 2704aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 2705aa50250dSMatthew G. Knepley @*/ 2706aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 2707aa50250dSMatthew G. Knepley { 2708aa50250dSMatthew G. Knepley PetscErrorCode ierr; 2709aa50250dSMatthew G. Knepley 2710aa50250dSMatthew G. Knepley PetscFunctionBegin; 2711aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2712aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 2713c58f1c22SToby Isaac if (!dm->depthLabel) {ierr = DMGetLabel(dm, "depth", &dm->depthLabel);CHKERRQ(ierr);} 2714c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 2715aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 2716aa50250dSMatthew G. Knepley } 2717aa50250dSMatthew G. Knepley 2718aa50250dSMatthew G. Knepley #undef __FUNCT__ 2719aa50250dSMatthew G. Knepley #define __FUNCT__ "DMPlexGetDepth" 2720aa50250dSMatthew G. Knepley /*@ 2721aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 2722aa50250dSMatthew G. Knepley 2723aa50250dSMatthew G. Knepley Not Collective 2724aa50250dSMatthew G. Knepley 2725aa50250dSMatthew G. Knepley Input Parameter: 2726aa50250dSMatthew G. Knepley . dm - The DMPlex object 2727aa50250dSMatthew G. Knepley 2728aa50250dSMatthew G. Knepley Output Parameter: 2729aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 2730aa50250dSMatthew G. Knepley 2731aa50250dSMatthew G. Knepley Level: developer 2732552f7358SJed Brown 2733552f7358SJed Brown .keywords: mesh, points 2734aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepthLabel(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 2735552f7358SJed Brown @*/ 2736552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 2737552f7358SJed Brown { 2738aa50250dSMatthew G. Knepley DMLabel label; 2739aa50250dSMatthew G. Knepley PetscInt d = 0; 2740552f7358SJed Brown PetscErrorCode ierr; 2741552f7358SJed Brown 2742552f7358SJed Brown PetscFunctionBegin; 2743552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2744552f7358SJed Brown PetscValidPointer(depth, 2); 2745aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2746aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 2747552f7358SJed Brown *depth = d-1; 2748552f7358SJed Brown PetscFunctionReturn(0); 2749552f7358SJed Brown } 2750552f7358SJed Brown 2751552f7358SJed Brown #undef __FUNCT__ 2752552f7358SJed Brown #define __FUNCT__ "DMPlexGetDepthStratum" 2753552f7358SJed Brown /*@ 2754552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 2755552f7358SJed Brown 2756552f7358SJed Brown Not Collective 2757552f7358SJed Brown 2758552f7358SJed Brown Input Parameters: 2759552f7358SJed Brown + dm - The DMPlex object 2760552f7358SJed Brown - stratumValue - The requested depth 2761552f7358SJed Brown 2762552f7358SJed Brown Output Parameters: 2763552f7358SJed Brown + start - The first point at this depth 2764552f7358SJed Brown - end - One beyond the last point at this depth 2765552f7358SJed Brown 2766552f7358SJed Brown Level: developer 2767552f7358SJed Brown 2768552f7358SJed Brown .keywords: mesh, points 2769552f7358SJed Brown .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth() 2770552f7358SJed Brown @*/ 27710adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 27720adebc6cSBarry Smith { 2773aa50250dSMatthew G. Knepley DMLabel label; 277463d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 2775552f7358SJed Brown PetscErrorCode ierr; 2776552f7358SJed Brown 2777552f7358SJed Brown PetscFunctionBegin; 2778552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 277963d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 278063d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 2781552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 27820d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 278363d1a920SMatthew G. Knepley if (stratumValue < 0) { 278463d1a920SMatthew G. Knepley if (start) *start = pStart; 278563d1a920SMatthew G. Knepley if (end) *end = pEnd; 278663d1a920SMatthew G. Knepley PetscFunctionReturn(0); 2787552f7358SJed Brown } 2788aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 278963d1a920SMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 279063d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 2791552f7358SJed Brown PetscFunctionReturn(0); 2792552f7358SJed Brown } 2793552f7358SJed Brown 2794552f7358SJed Brown #undef __FUNCT__ 2795552f7358SJed Brown #define __FUNCT__ "DMPlexGetHeightStratum" 2796552f7358SJed Brown /*@ 2797552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 2798552f7358SJed Brown 2799552f7358SJed Brown Not Collective 2800552f7358SJed Brown 2801552f7358SJed Brown Input Parameters: 2802552f7358SJed Brown + dm - The DMPlex object 2803552f7358SJed Brown - stratumValue - The requested height 2804552f7358SJed Brown 2805552f7358SJed Brown Output Parameters: 2806552f7358SJed Brown + start - The first point at this height 2807552f7358SJed Brown - end - One beyond the last point at this height 2808552f7358SJed Brown 2809552f7358SJed Brown Level: developer 2810552f7358SJed Brown 2811552f7358SJed Brown .keywords: mesh, points 2812552f7358SJed Brown .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth() 2813552f7358SJed Brown @*/ 28140adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 28150adebc6cSBarry Smith { 2816aa50250dSMatthew G. Knepley DMLabel label; 281763d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 2818552f7358SJed Brown PetscErrorCode ierr; 2819552f7358SJed Brown 2820552f7358SJed Brown PetscFunctionBegin; 2821552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 282263d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 282363d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 2824552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 28250d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 282663d1a920SMatthew G. Knepley if (stratumValue < 0) { 282763d1a920SMatthew G. Knepley if (start) *start = pStart; 282863d1a920SMatthew G. Knepley if (end) *end = pEnd; 282963d1a920SMatthew G. Knepley PetscFunctionReturn(0); 2830552f7358SJed Brown } 2831aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2832aa50250dSMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found");CHKERRQ(ierr); 283363d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 283463d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 2835552f7358SJed Brown PetscFunctionReturn(0); 2836552f7358SJed Brown } 2837552f7358SJed Brown 2838552f7358SJed Brown #undef __FUNCT__ 2839552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSectionInitial" 2840552f7358SJed Brown /* Set the number of dof on each point and separate by fields */ 2841a6dfd86eSKarl Rupp PetscErrorCode DMPlexCreateSectionInitial(DM dm, PetscInt dim, PetscInt numFields,const PetscInt numComp[],const PetscInt numDof[], PetscSection *section) 2842a6dfd86eSKarl Rupp { 2843ee55978aSMatthew G. Knepley PetscInt *pMax; 2844916f0f19SMatthew G. Knepley PetscInt depth, pStart = 0, pEnd = 0; 2845ee55978aSMatthew G. Knepley PetscInt Nf, p, d, dep, f; 2846fa716be8SMatthew G. Knepley PetscBool *isFE; 2847552f7358SJed Brown PetscErrorCode ierr; 2848552f7358SJed Brown 2849552f7358SJed Brown PetscFunctionBegin; 2850fa716be8SMatthew G. Knepley ierr = PetscMalloc1(numFields, &isFE);CHKERRQ(ierr); 2851ee55978aSMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 2852fa716be8SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 2853fa716be8SMatthew G. Knepley PetscObject obj; 2854fa716be8SMatthew G. Knepley PetscClassId id; 2855fa716be8SMatthew G. Knepley 2856ee55978aSMatthew G. Knepley isFE[f] = PETSC_FALSE; 2857ee55978aSMatthew G. Knepley if (f >= Nf) continue; 2858fa716be8SMatthew G. Knepley ierr = DMGetField(dm, f, &obj);CHKERRQ(ierr); 2859fa716be8SMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 2860fa716be8SMatthew G. Knepley if (id == PETSCFE_CLASSID) {isFE[f] = PETSC_TRUE;} 2861fa716be8SMatthew G. Knepley else if (id == PETSCFV_CLASSID) {isFE[f] = PETSC_FALSE;} 2862552f7358SJed Brown } 286382f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), section);CHKERRQ(ierr); 2864552f7358SJed Brown if (numFields > 0) { 2865552f7358SJed Brown ierr = PetscSectionSetNumFields(*section, numFields);CHKERRQ(ierr); 2866552f7358SJed Brown if (numComp) { 2867552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2868552f7358SJed Brown ierr = PetscSectionSetFieldComponents(*section, f, numComp[f]);CHKERRQ(ierr); 2869552f7358SJed Brown } 2870552f7358SJed Brown } 2871552f7358SJed Brown } 2872552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2873552f7358SJed Brown ierr = PetscSectionSetChart(*section, pStart, pEnd);CHKERRQ(ierr); 2874916f0f19SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 28759ac3fadcSMatthew G. Knepley ierr = PetscMalloc1(depth+1,&pMax);CHKERRQ(ierr); 28769ac3fadcSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, depth >= 0 ? &pMax[depth] : NULL, depth>1 ? &pMax[depth-1] : NULL, depth>2 ? &pMax[1] : NULL, &pMax[0]);CHKERRQ(ierr); 2877916f0f19SMatthew G. Knepley for (dep = 0; dep <= depth; ++dep) { 2878916f0f19SMatthew G. Knepley d = dim == depth ? dep : (!dep ? 0 : dim); 2879916f0f19SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, dep, &pStart, &pEnd);CHKERRQ(ierr); 2880fa716be8SMatthew G. Knepley pMax[dep] = pMax[dep] < 0 ? pEnd : pMax[dep]; 2881552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2882ee55978aSMatthew G. Knepley PetscInt tot = 0; 2883ee55978aSMatthew G. Knepley 2884552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2885fa716be8SMatthew G. Knepley if (isFE[f] && p >= pMax[dep]) continue; 2886552f7358SJed Brown ierr = PetscSectionSetFieldDof(*section, p, f, numDof[f*(dim+1)+d]);CHKERRQ(ierr); 2887ee55978aSMatthew G. Knepley tot += numDof[f*(dim+1)+d]; 2888552f7358SJed Brown } 2889ee55978aSMatthew G. Knepley ierr = PetscSectionSetDof(*section, p, tot);CHKERRQ(ierr); 2890552f7358SJed Brown } 2891552f7358SJed Brown } 28929ac3fadcSMatthew G. Knepley ierr = PetscFree(pMax);CHKERRQ(ierr); 2893fa716be8SMatthew G. Knepley ierr = PetscFree(isFE);CHKERRQ(ierr); 2894552f7358SJed Brown PetscFunctionReturn(0); 2895552f7358SJed Brown } 2896552f7358SJed Brown 2897552f7358SJed Brown #undef __FUNCT__ 2898552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSectionBCDof" 2899552f7358SJed Brown /* Set the number of dof on each point and separate by fields 2900ab1d0545SMatthew G. Knepley If bcComps is NULL or the IS is NULL, constrain every dof on the point 2901552f7358SJed Brown */ 2902ab1d0545SMatthew G. Knepley PetscErrorCode DMPlexCreateSectionBCDof(DM dm, PetscInt numBC, const PetscInt bcField[], const IS bcComps[], const IS bcPoints[], PetscSection section) 2903a6dfd86eSKarl Rupp { 2904552f7358SJed Brown PetscInt numFields; 2905552f7358SJed Brown PetscInt bc; 2906a68b90caSToby Isaac PetscSection aSec; 2907552f7358SJed Brown PetscErrorCode ierr; 2908552f7358SJed Brown 2909552f7358SJed Brown PetscFunctionBegin; 2910552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 2911552f7358SJed Brown for (bc = 0; bc < numBC; ++bc) { 2912552f7358SJed Brown PetscInt field = 0; 2913ab1d0545SMatthew G. Knepley const PetscInt *comp; 2914552f7358SJed Brown const PetscInt *idx; 2915ab1d0545SMatthew G. Knepley PetscInt Nc = -1, n, i; 2916552f7358SJed Brown 29170d644c17SKarl Rupp if (numFields) field = bcField[bc]; 2918ab1d0545SMatthew G. Knepley if (bcComps && bcComps[bc]) {ierr = ISGetLocalSize(bcComps[bc], &Nc);CHKERRQ(ierr);} 2919ab1d0545SMatthew G. Knepley if (bcComps && bcComps[bc]) {ierr = ISGetIndices(bcComps[bc], &comp);CHKERRQ(ierr);} 2920552f7358SJed Brown ierr = ISGetLocalSize(bcPoints[bc], &n);CHKERRQ(ierr); 2921552f7358SJed Brown ierr = ISGetIndices(bcPoints[bc], &idx);CHKERRQ(ierr); 2922552f7358SJed Brown for (i = 0; i < n; ++i) { 2923552f7358SJed Brown const PetscInt p = idx[i]; 292406ff1081SMatthew G. Knepley PetscInt numConst; 2925552f7358SJed Brown 2926552f7358SJed Brown if (numFields) { 2927552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, p, field, &numConst);CHKERRQ(ierr); 2928552f7358SJed Brown } else { 2929552f7358SJed Brown ierr = PetscSectionGetDof(section, p, &numConst);CHKERRQ(ierr); 2930552f7358SJed Brown } 293106ff1081SMatthew G. Knepley /* If Nc < 0, constrain every dof on the point */ 293206ff1081SMatthew G. Knepley if (Nc > 0) numConst = PetscMin(numConst, Nc); 293306ff1081SMatthew G. Knepley if (numFields) {ierr = PetscSectionAddFieldConstraintDof(section, p, field, numConst);CHKERRQ(ierr);} 2934552f7358SJed Brown ierr = PetscSectionAddConstraintDof(section, p, numConst);CHKERRQ(ierr); 2935552f7358SJed Brown } 2936552f7358SJed Brown ierr = ISRestoreIndices(bcPoints[bc], &idx);CHKERRQ(ierr); 293706ff1081SMatthew G. Knepley if (bcComps && bcComps[bc]) {ierr = ISRestoreIndices(bcComps[bc], &comp);CHKERRQ(ierr);} 2938552f7358SJed Brown } 2939a17985deSToby Isaac ierr = DMPlexGetAnchors(dm, &aSec, NULL);CHKERRQ(ierr); 2940a68b90caSToby Isaac if (aSec) { 2941a68b90caSToby Isaac PetscInt aStart, aEnd, a; 2942a68b90caSToby Isaac 2943a68b90caSToby Isaac ierr = PetscSectionGetChart(aSec, &aStart, &aEnd);CHKERRQ(ierr); 2944a68b90caSToby Isaac for (a = aStart; a < aEnd; a++) { 2945ab1d0545SMatthew G. Knepley PetscInt dof, f; 2946a68b90caSToby Isaac 2947a68b90caSToby Isaac ierr = PetscSectionGetDof(aSec, a, &dof);CHKERRQ(ierr); 2948a68b90caSToby Isaac if (dof) { 2949a68b90caSToby Isaac /* if there are point-to-point constraints, then all dofs are constrained */ 2950a68b90caSToby Isaac ierr = PetscSectionGetDof(section, a, &dof);CHKERRQ(ierr); 2951a68b90caSToby Isaac ierr = PetscSectionSetConstraintDof(section, a, dof);CHKERRQ(ierr); 2952a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 2953a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &dof);CHKERRQ(ierr); 2954a68b90caSToby Isaac ierr = PetscSectionSetFieldConstraintDof(section, a, f, dof);CHKERRQ(ierr); 2955a68b90caSToby Isaac } 2956a68b90caSToby Isaac } 2957a68b90caSToby Isaac } 2958a68b90caSToby Isaac } 2959552f7358SJed Brown PetscFunctionReturn(0); 2960552f7358SJed Brown } 2961552f7358SJed Brown 2962552f7358SJed Brown #undef __FUNCT__ 2963ab1d0545SMatthew G. Knepley #define __FUNCT__ "DMPlexCreateSectionBCIndicesField" 2964ab1d0545SMatthew G. Knepley /* Set the constrained field indices on each point 2965ab1d0545SMatthew G. Knepley If bcComps is NULL or the IS is NULL, constrain every dof on the point 2966ab1d0545SMatthew G. Knepley */ 2967ab1d0545SMatthew G. Knepley PetscErrorCode DMPlexCreateSectionBCIndicesField(DM dm, PetscInt numBC,const PetscInt bcField[], const IS bcComps[], const IS bcPoints[], PetscSection section) 29680adebc6cSBarry Smith { 2969ab1d0545SMatthew G. Knepley PetscSection aSec; 2970ab1d0545SMatthew G. Knepley PetscInt *indices; 2971ab1d0545SMatthew G. Knepley PetscInt numFields, maxDof, pStart, pEnd, p, bc, f, d; 2972552f7358SJed Brown PetscErrorCode ierr; 2973552f7358SJed Brown 2974552f7358SJed Brown PetscFunctionBegin; 2975552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 2976ab1d0545SMatthew G. Knepley if (!numFields) PetscFunctionReturn(0); 2977ab1d0545SMatthew G. Knepley /* Initialize all field indices to -1 */ 2978552f7358SJed Brown ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 2979ab1d0545SMatthew G. Knepley ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 2980ab1d0545SMatthew G. Knepley ierr = PetscMalloc1(maxDof, &indices);CHKERRQ(ierr); 2981ab1d0545SMatthew G. Knepley for (d = 0; d < maxDof; ++d) indices[d] = -1; 2982ab1d0545SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) for (f = 0; f < numFields; ++f) {ierr = PetscSectionSetFieldConstraintIndices(section, p, f, indices);CHKERRQ(ierr);} 2983ab1d0545SMatthew G. Knepley /* Handle BC constraints */ 2984ab1d0545SMatthew G. Knepley for (bc = 0; bc < numBC; ++bc) { 2985ab1d0545SMatthew G. Knepley const PetscInt field = bcField[bc]; 2986ab1d0545SMatthew G. Knepley const PetscInt *comp, *idx; 2987ab1d0545SMatthew G. Knepley PetscInt Nc = -1, n, i; 2988552f7358SJed Brown 2989ab1d0545SMatthew G. Knepley if (bcComps && bcComps[bc]) {ierr = ISGetLocalSize(bcComps[bc], &Nc);CHKERRQ(ierr);} 2990ab1d0545SMatthew G. Knepley if (bcComps && bcComps[bc]) {ierr = ISGetIndices(bcComps[bc], &comp);CHKERRQ(ierr);} 2991ab1d0545SMatthew G. Knepley ierr = ISGetLocalSize(bcPoints[bc], &n);CHKERRQ(ierr); 2992ab1d0545SMatthew G. Knepley ierr = ISGetIndices(bcPoints[bc], &idx);CHKERRQ(ierr); 2993ab1d0545SMatthew G. Knepley for (i = 0; i < n; ++i) { 2994ab1d0545SMatthew G. Knepley const PetscInt p = idx[i]; 2995ab1d0545SMatthew G. Knepley const PetscInt *find; 2996ab1d0545SMatthew G. Knepley PetscInt fcdof, c; 2997ab1d0545SMatthew G. Knepley 2998ab1d0545SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, field, &fcdof);CHKERRQ(ierr); 2999ab1d0545SMatthew G. Knepley if (Nc < 0) { 3000ab1d0545SMatthew G. Knepley for (d = 0; d < fcdof; ++d) indices[d] = d; 3001552f7358SJed Brown } else { 3002ab1d0545SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, p, field, &find);CHKERRQ(ierr); 3003ab1d0545SMatthew G. Knepley for (d = 0; d < fcdof; ++d) {if (find[d] < 0) break; indices[d] = find[d];} 3004ab1d0545SMatthew G. Knepley for (c = 0; c < Nc; ++c) indices[d+c] = comp[c]; 3005ab1d0545SMatthew G. Knepley ierr = PetscSortInt(d+Nc, indices);CHKERRQ(ierr); 3006ab1d0545SMatthew G. Knepley for (c = d+Nc; c < fcdof; ++c) indices[c] = -1; 3007552f7358SJed Brown } 3008ab1d0545SMatthew G. Knepley ierr = PetscSectionSetFieldConstraintIndices(section, p, field, indices);CHKERRQ(ierr); 3009552f7358SJed Brown } 3010ab1d0545SMatthew G. Knepley if (bcComps && bcComps[bc]) {ierr = ISRestoreIndices(bcComps[bc], &comp);CHKERRQ(ierr);} 3011ab1d0545SMatthew G. Knepley ierr = ISRestoreIndices(bcPoints[bc], &idx);CHKERRQ(ierr); 3012552f7358SJed Brown } 3013ab1d0545SMatthew G. Knepley /* Handle anchors */ 3014ab1d0545SMatthew G. Knepley ierr = DMPlexGetAnchors(dm, &aSec, NULL);CHKERRQ(ierr); 3015ab1d0545SMatthew G. Knepley if (aSec) { 3016ab1d0545SMatthew G. Knepley PetscInt aStart, aEnd, a; 3017552f7358SJed Brown 3018ab1d0545SMatthew G. Knepley for (d = 0; d < maxDof; ++d) indices[d] = d; 3019ab1d0545SMatthew G. Knepley ierr = PetscSectionGetChart(aSec, &aStart, &aEnd);CHKERRQ(ierr); 3020ab1d0545SMatthew G. Knepley for (a = aStart; a < aEnd; a++) { 3021ab1d0545SMatthew G. Knepley PetscInt dof, fdof, f; 3022ab1d0545SMatthew G. Knepley 3023ab1d0545SMatthew G. Knepley ierr = PetscSectionGetDof(aSec, a, &dof);CHKERRQ(ierr); 3024ab1d0545SMatthew G. Knepley if (dof) { 3025ab1d0545SMatthew G. Knepley /* if there are point-to-point constraints, then all dofs are constrained */ 3026ab1d0545SMatthew G. Knepley for (f = 0; f < numFields; f++) { 3027ab1d0545SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, a, f, &fdof);CHKERRQ(ierr); 3028ab1d0545SMatthew G. Knepley ierr = PetscSectionSetFieldConstraintIndices(section, a, f, indices);CHKERRQ(ierr); 3029ab1d0545SMatthew G. Knepley } 3030ab1d0545SMatthew G. Knepley } 3031ab1d0545SMatthew G. Knepley } 3032ab1d0545SMatthew G. Knepley } 3033ab1d0545SMatthew G. Knepley ierr = PetscFree(indices);CHKERRQ(ierr); 3034ab1d0545SMatthew G. Knepley PetscFunctionReturn(0); 3035ab1d0545SMatthew G. Knepley } 3036ab1d0545SMatthew G. Knepley 3037ab1d0545SMatthew G. Knepley #undef __FUNCT__ 3038ab1d0545SMatthew G. Knepley #define __FUNCT__ "DMPlexCreateSectionBCIndices" 3039ab1d0545SMatthew G. Knepley /* Set the constrained indices on each point */ 3040ab1d0545SMatthew G. Knepley PetscErrorCode DMPlexCreateSectionBCIndices(DM dm, PetscSection section) 3041ab1d0545SMatthew G. Knepley { 3042ab1d0545SMatthew G. Knepley PetscInt *indices; 3043ab1d0545SMatthew G. Knepley PetscInt numFields, maxDof, pStart, pEnd, p, f, d; 3044ab1d0545SMatthew G. Knepley PetscErrorCode ierr; 3045ab1d0545SMatthew G. Knepley 3046ab1d0545SMatthew G. Knepley PetscFunctionBegin; 3047ab1d0545SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 3048ab1d0545SMatthew G. Knepley ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 3049ab1d0545SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3050ab1d0545SMatthew G. Knepley ierr = PetscMalloc1(maxDof, &indices);CHKERRQ(ierr); 3051ab1d0545SMatthew G. Knepley for (d = 0; d < maxDof; ++d) indices[d] = -1; 3052552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3053552f7358SJed Brown PetscInt cdof, d; 3054552f7358SJed Brown 3055552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 3056552f7358SJed Brown if (cdof) { 3057552f7358SJed Brown if (numFields) { 3058552f7358SJed Brown PetscInt numConst = 0, foff = 0; 3059552f7358SJed Brown 3060552f7358SJed Brown for (f = 0; f < numFields; ++f) { 3061ab1d0545SMatthew G. Knepley const PetscInt *find; 3062ab1d0545SMatthew G. Knepley PetscInt fcdof, fdof; 3063552f7358SJed Brown 3064552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 3065ab1d0545SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 3066ab1d0545SMatthew G. Knepley /* Change constraint numbering from field component to local dof number */ 3067ab1d0545SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, p, f, &find);CHKERRQ(ierr); 3068ab1d0545SMatthew G. Knepley for (d = 0; d < fcdof; ++d) indices[numConst+d] = find[d] + foff; 3069ab1d0545SMatthew G. Knepley numConst += fcdof; 3070552f7358SJed Brown foff += fdof; 3071552f7358SJed Brown } 3072552f7358SJed Brown if (cdof != numConst) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Total number of field constraints %D should be %D", numConst, cdof); 3073552f7358SJed Brown } else { 30740d644c17SKarl Rupp for (d = 0; d < cdof; ++d) indices[d] = d; 3075552f7358SJed Brown } 3076552f7358SJed Brown ierr = PetscSectionSetConstraintIndices(section, p, indices);CHKERRQ(ierr); 3077552f7358SJed Brown } 3078552f7358SJed Brown } 3079552f7358SJed Brown ierr = PetscFree(indices);CHKERRQ(ierr); 3080552f7358SJed Brown PetscFunctionReturn(0); 3081552f7358SJed Brown } 3082552f7358SJed Brown 3083552f7358SJed Brown #undef __FUNCT__ 3084552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSection" 3085552f7358SJed Brown /*@C 3086552f7358SJed Brown DMPlexCreateSection - Create a PetscSection based upon the dof layout specification provided. 3087552f7358SJed Brown 3088552f7358SJed Brown Not Collective 3089552f7358SJed Brown 3090552f7358SJed Brown Input Parameters: 3091552f7358SJed Brown + dm - The DMPlex object 3092552f7358SJed Brown . dim - The spatial dimension of the problem 3093552f7358SJed Brown . numFields - The number of fields in the problem 3094552f7358SJed Brown . numComp - An array of size numFields that holds the number of components for each field 3095552f7358SJed Brown . numDof - An array of size numFields*(dim+1) which holds the number of dof for each field on a mesh piece of dimension d 3096552f7358SJed Brown . numBC - The number of boundary conditions 3097552f7358SJed Brown . bcField - An array of size numBC giving the field number for each boundry condition 3098ab1d0545SMatthew G. Knepley . bcComps - [Optional] An array of size numBC giving an IS holding the field components to which each boundary condition applies 3099ab1d0545SMatthew G. Knepley . bcPoints - An array of size numBC giving an IS holding the Plex points to which each boundary condition applies 3100f8f126e8SMatthew G. Knepley - perm - Optional permutation of the chart, or NULL 3101552f7358SJed Brown 3102552f7358SJed Brown Output Parameter: 3103552f7358SJed Brown . section - The PetscSection object 3104552f7358SJed Brown 3105552f7358SJed Brown Notes: numDof[f*(dim+1)+d] gives the number of dof for field f on sieve points of dimension d. For instance, numDof[1] is the 3106f8f126e8SMatthew G. Knepley number of dof for field 0 on each edge. 3107f8f126e8SMatthew G. Knepley 3108f8f126e8SMatthew G. Knepley The chart permutation is the same one set using PetscSectionSetPermutation() 3109552f7358SJed Brown 3110552f7358SJed Brown Level: developer 3111552f7358SJed Brown 31123813dfbdSMatthew G Knepley Fortran Notes: 31133813dfbdSMatthew G Knepley A Fortran 90 version is available as DMPlexCreateSectionF90() 31143813dfbdSMatthew G Knepley 3115552f7358SJed Brown .keywords: mesh, elements 3116f8f126e8SMatthew G. Knepley .seealso: DMPlexCreate(), PetscSectionCreate(), PetscSectionSetPermutation() 3117552f7358SJed Brown @*/ 3118ab1d0545SMatthew G. Knepley PetscErrorCode DMPlexCreateSection(DM dm, PetscInt dim, PetscInt numFields,const PetscInt numComp[],const PetscInt numDof[], PetscInt numBC,const PetscInt bcField[], const IS bcComps[], const IS bcPoints[], IS perm, PetscSection *section) 3119a6dfd86eSKarl Rupp { 3120a68b90caSToby Isaac PetscSection aSec; 3121552f7358SJed Brown PetscErrorCode ierr; 3122552f7358SJed Brown 3123552f7358SJed Brown PetscFunctionBegin; 3124552f7358SJed Brown ierr = DMPlexCreateSectionInitial(dm, dim, numFields, numComp, numDof, section);CHKERRQ(ierr); 3125ab1d0545SMatthew G. Knepley ierr = DMPlexCreateSectionBCDof(dm, numBC, bcField, bcComps, bcPoints, *section);CHKERRQ(ierr); 3126f8f126e8SMatthew G. Knepley if (perm) {ierr = PetscSectionSetPermutation(*section, perm);CHKERRQ(ierr);} 3127552f7358SJed Brown ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 3128a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,NULL);CHKERRQ(ierr); 3129ab1d0545SMatthew G. Knepley if (numBC || aSec) { 3130ab1d0545SMatthew G. Knepley ierr = DMPlexCreateSectionBCIndicesField(dm, numBC, bcField, bcComps, bcPoints, *section);CHKERRQ(ierr); 3131ab1d0545SMatthew G. Knepley ierr = DMPlexCreateSectionBCIndices(dm, *section);CHKERRQ(ierr); 3132ab1d0545SMatthew G. Knepley } 3133ce1779c8SBarry Smith ierr = PetscSectionViewFromOptions(*section,NULL,"-section_view");CHKERRQ(ierr); 3134552f7358SJed Brown PetscFunctionReturn(0); 3135552f7358SJed Brown } 3136552f7358SJed Brown 3137552f7358SJed Brown #undef __FUNCT__ 3138552f7358SJed Brown #define __FUNCT__ "DMCreateCoordinateDM_Plex" 31390adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 31400adebc6cSBarry Smith { 3141efe440bfSMatthew G. Knepley PetscSection section, s; 3142efe440bfSMatthew G. Knepley Mat m; 31433e922f36SToby Isaac PetscInt maxHeight; 3144552f7358SJed Brown PetscErrorCode ierr; 3145552f7358SJed Brown 3146552f7358SJed Brown PetscFunctionBegin; 314738221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 31483e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 31493e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 315082f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 3151552f7358SJed Brown ierr = DMSetDefaultSection(*cdm, section);CHKERRQ(ierr); 31521d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 3153efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 3154efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 3155efe440bfSMatthew G. Knepley ierr = DMSetDefaultConstraints(*cdm, s, m);CHKERRQ(ierr); 3156efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 3157efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 3158552f7358SJed Brown PetscFunctionReturn(0); 3159552f7358SJed Brown } 3160552f7358SJed Brown 3161552f7358SJed Brown #undef __FUNCT__ 3162552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeSection" 31630adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 31640adebc6cSBarry Smith { 3165552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3166552f7358SJed Brown 3167552f7358SJed Brown PetscFunctionBegin; 3168552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3169552f7358SJed Brown if (section) *section = mesh->coneSection; 3170552f7358SJed Brown PetscFunctionReturn(0); 3171552f7358SJed Brown } 3172552f7358SJed Brown 3173552f7358SJed Brown #undef __FUNCT__ 31748cb4d582SMatthew G. Knepley #define __FUNCT__ "DMPlexGetSupportSection" 31758cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 31768cb4d582SMatthew G. Knepley { 31778cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 31788cb4d582SMatthew G. Knepley 31798cb4d582SMatthew G. Knepley PetscFunctionBegin; 31808cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 31818cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 31828cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 31838cb4d582SMatthew G. Knepley } 31848cb4d582SMatthew G. Knepley 31858cb4d582SMatthew G. Knepley #undef __FUNCT__ 3186552f7358SJed Brown #define __FUNCT__ "DMPlexGetCones" 3187a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 3188a6dfd86eSKarl Rupp { 3189552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3190552f7358SJed Brown 3191552f7358SJed Brown PetscFunctionBegin; 3192552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3193552f7358SJed Brown if (cones) *cones = mesh->cones; 3194552f7358SJed Brown PetscFunctionReturn(0); 3195552f7358SJed Brown } 3196552f7358SJed Brown 3197552f7358SJed Brown #undef __FUNCT__ 3198552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeOrientations" 3199a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 3200a6dfd86eSKarl Rupp { 3201552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3202552f7358SJed Brown 3203552f7358SJed Brown PetscFunctionBegin; 3204552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3205552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 3206552f7358SJed Brown PetscFunctionReturn(0); 3207552f7358SJed Brown } 3208552f7358SJed Brown 3209552f7358SJed Brown /******************************** FEM Support **********************************/ 3210552f7358SJed Brown 3211552f7358SJed Brown #undef __FUNCT__ 32121a271a75SMatthew G. Knepley #define __FUNCT__ "DMPlexVecGetClosure_Depth1_Static" 32131a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3214a6dfd86eSKarl Rupp { 3215552f7358SJed Brown PetscScalar *array, *vArray; 3216d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 32171a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 3218552f7358SJed Brown PetscErrorCode ierr; 3219552f7358SJed Brown 32201b406b76SMatthew G. Knepley PetscFunctionBeginHot; 32212a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 32225a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 32235a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 32245a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 32253f7cbbe7SMatthew G. Knepley if (!values || !*values) { 32269df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 32279df71ca4SMatthew G. Knepley PetscInt dof; 3228d9917b9dSMatthew G. Knepley 32299df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 32309df71ca4SMatthew G. Knepley size += dof; 32319df71ca4SMatthew G. Knepley } 32329df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 32339df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 32342a3aaacfSMatthew G. Knepley PetscInt dof; 32355a1bb5cfSMatthew G. Knepley 32365a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 32372a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 32385a1bb5cfSMatthew G. Knepley size += dof; 32395a1bb5cfSMatthew G. Knepley } 32403f7cbbe7SMatthew G. Knepley if (!values) { 32413f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 32423f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 32433f7cbbe7SMatthew G. Knepley } 32445a1bb5cfSMatthew G. Knepley ierr = DMGetWorkArray(dm, size, PETSC_SCALAR, &array);CHKERRQ(ierr); 3245982e9ed1SMatthew G. Knepley } else { 3246982e9ed1SMatthew G. Knepley array = *values; 3247982e9ed1SMatthew G. Knepley } 32489df71ca4SMatthew G. Knepley size = 0; 32495a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 32509df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 32519df71ca4SMatthew G. Knepley PetscInt dof, off, d; 32529df71ca4SMatthew G. Knepley PetscScalar *varr; 3253d9917b9dSMatthew G. Knepley 32549df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 32559df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 32569df71ca4SMatthew G. Knepley varr = &vArray[off]; 32571a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 32581a271a75SMatthew G. Knepley array[offset] = varr[d]; 32599df71ca4SMatthew G. Knepley } 32609df71ca4SMatthew G. Knepley size += dof; 32619df71ca4SMatthew G. Knepley } 32629df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 32639df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 32649df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 32655a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 32665a1bb5cfSMatthew G. Knepley PetscScalar *varr; 32675a1bb5cfSMatthew G. Knepley 326852ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 32695a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 32705a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 32715a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 32725a1bb5cfSMatthew G. Knepley if (o >= 0) { 32731a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 32741a271a75SMatthew G. Knepley array[offset] = varr[d]; 32755a1bb5cfSMatthew G. Knepley } 32765a1bb5cfSMatthew G. Knepley } else { 32771a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 32781a271a75SMatthew G. Knepley array[offset] = varr[d]; 32795a1bb5cfSMatthew G. Knepley } 32805a1bb5cfSMatthew G. Knepley } 32819df71ca4SMatthew G. Knepley size += dof; 32825a1bb5cfSMatthew G. Knepley } 32835a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 32849df71ca4SMatthew G. Knepley if (!*values) { 32855a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 32865a1bb5cfSMatthew G. Knepley *values = array; 32879df71ca4SMatthew G. Knepley } else { 32889df71ca4SMatthew G. Knepley if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %d < actual size %d", *csize, size); 32898c312ff3SMatthew G. Knepley *csize = size; 32909df71ca4SMatthew G. Knepley } 32915a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 32925a1bb5cfSMatthew G. Knepley } 3293d9917b9dSMatthew G. Knepley 3294d9917b9dSMatthew G. Knepley #undef __FUNCT__ 32951a271a75SMatthew G. Knepley #define __FUNCT__ "DMPlexVecGetClosure_Static" 32961a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Static(PetscSection section, PetscInt numPoints, const PetscInt points[], const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 32971a271a75SMatthew G. Knepley { 32981a271a75SMatthew G. Knepley PetscInt offset = 0, p; 32991a271a75SMatthew G. Knepley PetscErrorCode ierr; 33001a271a75SMatthew G. Knepley 33011a271a75SMatthew G. Knepley PetscFunctionBeginHot; 3302fe02ba77SJed Brown *size = 0; 33031a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 33041a271a75SMatthew G. Knepley const PetscInt point = points[p]; 33051a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 33061a271a75SMatthew G. Knepley PetscInt dof, off, d; 33071a271a75SMatthew G. Knepley const PetscScalar *varr; 33081a271a75SMatthew G. Knepley 33091a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 33101a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 33111a271a75SMatthew G. Knepley varr = &vArray[off]; 33121a271a75SMatthew G. Knepley if (o >= 0) { 33131a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) array[offset] = varr[d]; 33141a271a75SMatthew G. Knepley } else { 33151a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) array[offset] = varr[d]; 33161a271a75SMatthew G. Knepley } 33171a271a75SMatthew G. Knepley } 33181a271a75SMatthew G. Knepley *size = offset; 33191a271a75SMatthew G. Knepley PetscFunctionReturn(0); 33201a271a75SMatthew G. Knepley } 33211a271a75SMatthew G. Knepley 33221a271a75SMatthew G. Knepley #undef __FUNCT__ 33231a271a75SMatthew G. Knepley #define __FUNCT__ "DMPlexVecGetClosure_Fields_Static" 33241a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Fields_Static(PetscSection section, PetscInt numPoints, const PetscInt points[], PetscInt numFields, const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 33251a271a75SMatthew G. Knepley { 33261a271a75SMatthew G. Knepley PetscInt offset = 0, f; 33271a271a75SMatthew G. Knepley PetscErrorCode ierr; 33281a271a75SMatthew G. Knepley 33291a271a75SMatthew G. Knepley PetscFunctionBeginHot; 3330fe02ba77SJed Brown *size = 0; 33311a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 33321a271a75SMatthew G. Knepley PetscInt fcomp, p; 33331a271a75SMatthew G. Knepley 33341a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 33351a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 33361a271a75SMatthew G. Knepley const PetscInt point = points[p]; 33371a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 33381a271a75SMatthew G. Knepley PetscInt fdof, foff, d, c; 33391a271a75SMatthew G. Knepley const PetscScalar *varr; 33401a271a75SMatthew G. Knepley 33411a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 33421a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 33431a271a75SMatthew G. Knepley varr = &vArray[foff]; 33441a271a75SMatthew G. Knepley if (o >= 0) { 33451a271a75SMatthew G. Knepley for (d = 0; d < fdof; ++d, ++offset) array[offset] = varr[d]; 33461a271a75SMatthew G. Knepley } else { 33471a271a75SMatthew G. Knepley for (d = fdof/fcomp-1; d >= 0; --d) { 33481a271a75SMatthew G. Knepley for (c = 0; c < fcomp; ++c, ++offset) { 33491a271a75SMatthew G. Knepley array[offset] = varr[d*fcomp+c]; 33501a271a75SMatthew G. Knepley } 33511a271a75SMatthew G. Knepley } 33521a271a75SMatthew G. Knepley } 33531a271a75SMatthew G. Knepley } 33541a271a75SMatthew G. Knepley } 33551a271a75SMatthew G. Knepley *size = offset; 33561a271a75SMatthew G. Knepley PetscFunctionReturn(0); 33571a271a75SMatthew G. Knepley } 33581a271a75SMatthew G. Knepley 33591a271a75SMatthew G. Knepley #undef __FUNCT__ 3360552f7358SJed Brown #define __FUNCT__ "DMPlexVecGetClosure" 3361552f7358SJed Brown /*@C 3362552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 3363552f7358SJed Brown 3364552f7358SJed Brown Not collective 3365552f7358SJed Brown 3366552f7358SJed Brown Input Parameters: 3367552f7358SJed Brown + dm - The DM 3368552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 3369552f7358SJed Brown . v - The local vector 3370552f7358SJed Brown - point - The sieve point in the DM 3371552f7358SJed Brown 3372552f7358SJed Brown Output Parameters: 3373552f7358SJed Brown + csize - The number of values in the closure, or NULL 3374552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 3375552f7358SJed Brown 3376552f7358SJed Brown Fortran Notes: 3377552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 3378552f7358SJed Brown include petsc.h90 in your code. 3379552f7358SJed Brown 3380552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 3381552f7358SJed Brown 3382552f7358SJed Brown Level: intermediate 3383552f7358SJed Brown 3384552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 3385552f7358SJed Brown @*/ 3386552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3387552f7358SJed Brown { 3388552f7358SJed Brown PetscSection clSection; 3389d9917b9dSMatthew G. Knepley IS clPoints; 3390552f7358SJed Brown PetscScalar *array, *vArray; 3391552f7358SJed Brown PetscInt *points = NULL; 3392d9917b9dSMatthew G. Knepley const PetscInt *clp; 33931a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, size; 3394552f7358SJed Brown PetscErrorCode ierr; 3395552f7358SJed Brown 3396d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 3397552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3398552f7358SJed Brown if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 33991a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 34001a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 3401552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3402552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 3403552f7358SJed Brown if (depth == 1 && numFields < 2) { 34041a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 3405552f7358SJed Brown PetscFunctionReturn(0); 3406552f7358SJed Brown } 34071a271a75SMatthew G. Knepley /* Get points */ 3408d9917b9dSMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 3409d9917b9dSMatthew G. Knepley if (!clPoints) { 34101a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, q; 3411552f7358SJed Brown 34121a271a75SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3413552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 3414552f7358SJed Brown /* Compress out points not in the section */ 3415552f7358SJed Brown for (p = 0, q = 0; p < numPoints*2; p += 2) { 3416552f7358SJed Brown if ((points[p] >= pStart) && (points[p] < pEnd)) { 3417552f7358SJed Brown points[q*2] = points[p]; 3418552f7358SJed Brown points[q*2+1] = points[p+1]; 3419552f7358SJed Brown ++q; 3420552f7358SJed Brown } 3421552f7358SJed Brown } 3422552f7358SJed Brown numPoints = q; 3423d9917b9dSMatthew G. Knepley } else { 3424d9917b9dSMatthew G. Knepley PetscInt dof, off; 3425552f7358SJed Brown 3426d9917b9dSMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 3427d9917b9dSMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 3428d9917b9dSMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 34291a271a75SMatthew G. Knepley numPoints = dof/2; 3430d9917b9dSMatthew G. Knepley points = (PetscInt *) &clp[off]; 3431552f7358SJed Brown } 34321a271a75SMatthew G. Knepley /* Get array */ 3433552f7358SJed Brown if (!values || !*values) { 34341a271a75SMatthew G. Knepley PetscInt asize = 0, dof, p; 3435552f7358SJed Brown 34361a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3437552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 34381a271a75SMatthew G. Knepley asize += dof; 3439552f7358SJed Brown } 3440bd6c0d32SMatthew G. Knepley if (!values) { 3441d9917b9dSMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 34421a271a75SMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 34431a271a75SMatthew G. Knepley if (csize) *csize = asize; 3444bd6c0d32SMatthew G. Knepley PetscFunctionReturn(0); 3445bd6c0d32SMatthew G. Knepley } 34461a271a75SMatthew G. Knepley ierr = DMGetWorkArray(dm, asize, PETSC_SCALAR, &array);CHKERRQ(ierr); 3447d0f6b257SMatthew G. Knepley } else { 3448d0f6b257SMatthew G. Knepley array = *values; 3449d0f6b257SMatthew G. Knepley } 3450552f7358SJed Brown ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 34511a271a75SMatthew G. Knepley /* Get values */ 3452ef90cfe2SMatthew G. Knepley if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(section, numPoints, points, numFields, vArray, &size, array);CHKERRQ(ierr);} 34531a271a75SMatthew G. Knepley else {ierr = DMPlexVecGetClosure_Static(section, numPoints, points, vArray, &size, array);CHKERRQ(ierr);} 34541a271a75SMatthew G. Knepley /* Cleanup points */ 34551a271a75SMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 34561a271a75SMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 34571a271a75SMatthew G. Knepley /* Cleanup array */ 3458552f7358SJed Brown ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 3459d0f6b257SMatthew G. Knepley if (!*values) { 3460552f7358SJed Brown if (csize) *csize = size; 3461552f7358SJed Brown *values = array; 3462d0f6b257SMatthew G. Knepley } else { 3463f347f43bSBarry Smith if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 3464d0f6b257SMatthew G. Knepley *csize = size; 3465d0f6b257SMatthew G. Knepley } 3466552f7358SJed Brown PetscFunctionReturn(0); 3467552f7358SJed Brown } 3468552f7358SJed Brown 3469552f7358SJed Brown #undef __FUNCT__ 3470552f7358SJed Brown #define __FUNCT__ "DMPlexVecRestoreClosure" 3471552f7358SJed Brown /*@C 3472552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 3473552f7358SJed Brown 3474552f7358SJed Brown Not collective 3475552f7358SJed Brown 3476552f7358SJed Brown Input Parameters: 3477552f7358SJed Brown + dm - The DM 34780298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 3479552f7358SJed Brown . v - The local vector 3480552f7358SJed Brown . point - The sieve point in the DM 34810298fd71SBarry Smith . csize - The number of values in the closure, or NULL 3482552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 3483552f7358SJed Brown 34843813dfbdSMatthew G Knepley Fortran Notes: 34853813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 34863813dfbdSMatthew G Knepley include petsc.h90 in your code. 34873813dfbdSMatthew G Knepley 34883813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 34893813dfbdSMatthew G Knepley 3490552f7358SJed Brown Level: intermediate 3491552f7358SJed Brown 3492552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 3493552f7358SJed Brown @*/ 34947c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3495a6dfd86eSKarl Rupp { 3496552f7358SJed Brown PetscInt size = 0; 3497552f7358SJed Brown PetscErrorCode ierr; 3498552f7358SJed Brown 3499552f7358SJed Brown PetscFunctionBegin; 3500552f7358SJed Brown /* Should work without recalculating size */ 3501552f7358SJed Brown ierr = DMRestoreWorkArray(dm, size, PETSC_SCALAR, (void*) values);CHKERRQ(ierr); 3502552f7358SJed Brown PetscFunctionReturn(0); 3503552f7358SJed Brown } 3504552f7358SJed Brown 3505552f7358SJed Brown PETSC_STATIC_INLINE void add (PetscScalar *x, PetscScalar y) {*x += y;} 3506552f7358SJed Brown PETSC_STATIC_INLINE void insert(PetscScalar *x, PetscScalar y) {*x = y;} 3507552f7358SJed Brown 3508552f7358SJed Brown #undef __FUNCT__ 3509552f7358SJed Brown #define __FUNCT__ "updatePoint_private" 35101a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode updatePoint_private(PetscSection section, PetscInt point, PetscInt dof, void (*fuse)(PetscScalar*, PetscScalar), PetscBool setBC, PetscInt orientation, const PetscScalar values[], PetscScalar array[]) 3511552f7358SJed Brown { 3512552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 3513552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 3514552f7358SJed Brown PetscScalar *a; 3515552f7358SJed Brown PetscInt off, cind = 0, k; 3516552f7358SJed Brown PetscErrorCode ierr; 3517552f7358SJed Brown 3518552f7358SJed Brown PetscFunctionBegin; 3519552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 3520552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 3521552f7358SJed Brown a = &array[off]; 3522552f7358SJed Brown if (!cdof || setBC) { 3523552f7358SJed Brown if (orientation >= 0) { 3524552f7358SJed Brown for (k = 0; k < dof; ++k) { 3525552f7358SJed Brown fuse(&a[k], values[k]); 3526552f7358SJed Brown } 3527552f7358SJed Brown } else { 3528552f7358SJed Brown for (k = 0; k < dof; ++k) { 3529552f7358SJed Brown fuse(&a[k], values[dof-k-1]); 3530552f7358SJed Brown } 3531552f7358SJed Brown } 3532552f7358SJed Brown } else { 3533552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 3534552f7358SJed Brown if (orientation >= 0) { 3535552f7358SJed Brown for (k = 0; k < dof; ++k) { 3536552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3537552f7358SJed Brown fuse(&a[k], values[k]); 3538552f7358SJed Brown } 3539552f7358SJed Brown } else { 3540552f7358SJed Brown for (k = 0; k < dof; ++k) { 3541552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3542552f7358SJed Brown fuse(&a[k], values[dof-k-1]); 3543552f7358SJed Brown } 3544552f7358SJed Brown } 3545552f7358SJed Brown } 3546552f7358SJed Brown PetscFunctionReturn(0); 3547552f7358SJed Brown } 3548552f7358SJed Brown 3549552f7358SJed Brown #undef __FUNCT__ 3550a5e93ea8SMatthew G. Knepley #define __FUNCT__ "updatePointBC_private" 35511a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode updatePointBC_private(PetscSection section, PetscInt point, PetscInt dof, void (*fuse)(PetscScalar*, PetscScalar), PetscInt orientation, const PetscScalar values[], PetscScalar array[]) 3552a5e93ea8SMatthew G. Knepley { 3553a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 3554a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 3555a5e93ea8SMatthew G. Knepley PetscScalar *a; 3556a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 3557a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 3558a5e93ea8SMatthew G. Knepley 3559a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 3560a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 3561a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 3562a5e93ea8SMatthew G. Knepley a = &array[off]; 3563a5e93ea8SMatthew G. Knepley if (cdof) { 3564a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 3565a5e93ea8SMatthew G. Knepley if (orientation >= 0) { 3566a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3567a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 3568a5e93ea8SMatthew G. Knepley fuse(&a[k], values[k]); 3569a5e93ea8SMatthew G. Knepley ++cind; 3570a5e93ea8SMatthew G. Knepley } 3571a5e93ea8SMatthew G. Knepley } 3572a5e93ea8SMatthew G. Knepley } else { 3573a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3574a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 3575a5e93ea8SMatthew G. Knepley fuse(&a[k], values[dof-k-1]); 3576a5e93ea8SMatthew G. Knepley ++cind; 3577a5e93ea8SMatthew G. Knepley } 3578a5e93ea8SMatthew G. Knepley } 3579a5e93ea8SMatthew G. Knepley } 3580a5e93ea8SMatthew G. Knepley } 3581a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 3582a5e93ea8SMatthew G. Knepley } 3583a5e93ea8SMatthew G. Knepley 3584a5e93ea8SMatthew G. Knepley #undef __FUNCT__ 3585552f7358SJed Brown #define __FUNCT__ "updatePointFields_private" 35861a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode updatePointFields_private(PetscSection section, PetscInt point, PetscInt o, PetscInt f, PetscInt fcomp, void (*fuse)(PetscScalar*, PetscScalar), PetscBool setBC, const PetscScalar values[], PetscInt *offset, PetscScalar array[]) 3587a6dfd86eSKarl Rupp { 3588552f7358SJed Brown PetscScalar *a; 35891a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 35901a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 35911a271a75SMatthew G. Knepley PetscInt cind = 0, k, c; 3592552f7358SJed Brown PetscErrorCode ierr; 3593552f7358SJed Brown 3594552f7358SJed Brown PetscFunctionBegin; 3595552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 3596552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 35971a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 35981a271a75SMatthew G. Knepley a = &array[foff]; 3599552f7358SJed Brown if (!fcdof || setBC) { 36001a271a75SMatthew G. Knepley if (o >= 0) { 36011a271a75SMatthew G. Knepley for (k = 0; k < fdof; ++k) fuse(&a[k], values[foffset+k]); 3602552f7358SJed Brown } else { 3603552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 3604552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 36051a271a75SMatthew G. Knepley fuse(&a[(fdof/fcomp-1-k)*fcomp+c], values[foffset+k*fcomp+c]); 3606552f7358SJed Brown } 3607552f7358SJed Brown } 3608552f7358SJed Brown } 3609552f7358SJed Brown } else { 3610552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 36111a271a75SMatthew G. Knepley if (o >= 0) { 3612552f7358SJed Brown for (k = 0; k < fdof; ++k) { 3613552f7358SJed Brown if ((cind < fcdof) && (k == fcdofs[cind])) {++cind; continue;} 36141a271a75SMatthew G. Knepley fuse(&a[k], values[foffset+k]); 3615552f7358SJed Brown } 3616552f7358SJed Brown } else { 3617552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 3618552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 3619552f7358SJed Brown if ((cind < fcdof) && (k*fcomp+c == fcdofs[cind])) {++cind; continue;} 36201a271a75SMatthew G. Knepley fuse(&a[(fdof/fcomp-1-k)*fcomp+c], values[foffset+k*fcomp+c]); 3621552f7358SJed Brown } 3622552f7358SJed Brown } 3623552f7358SJed Brown } 3624552f7358SJed Brown } 36251a271a75SMatthew G. Knepley *offset += fdof; 3626552f7358SJed Brown PetscFunctionReturn(0); 3627552f7358SJed Brown } 3628552f7358SJed Brown 3629552f7358SJed Brown #undef __FUNCT__ 3630a5e93ea8SMatthew G. Knepley #define __FUNCT__ "updatePointFieldsBC_private" 36311a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode updatePointFieldsBC_private(PetscSection section, PetscInt point, PetscInt o, PetscInt f, PetscInt fcomp, void (*fuse)(PetscScalar*, PetscScalar), const PetscScalar values[], PetscInt *offset, PetscScalar array[]) 3632a5e93ea8SMatthew G. Knepley { 3633a5e93ea8SMatthew G. Knepley PetscScalar *a; 36341a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 36351a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 36361a271a75SMatthew G. Knepley PetscInt cind = 0, k, c; 3637a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 3638a5e93ea8SMatthew G. Knepley 3639a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 3640a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 3641a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 36421a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 36431a271a75SMatthew G. Knepley a = &array[foff]; 3644a5e93ea8SMatthew G. Knepley if (fcdof) { 3645a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 36461a271a75SMatthew G. Knepley if (o >= 0) { 3647a5e93ea8SMatthew G. Knepley for (k = 0; k < fdof; ++k) { 3648a5e93ea8SMatthew G. Knepley if ((cind < fcdof) && (k == fcdofs[cind])) { 36491a271a75SMatthew G. Knepley fuse(&a[k], values[foffset+k]); 3650a5e93ea8SMatthew G. Knepley ++cind; 3651a5e93ea8SMatthew G. Knepley } 3652a5e93ea8SMatthew G. Knepley } 3653a5e93ea8SMatthew G. Knepley } else { 3654a5e93ea8SMatthew G. Knepley for (k = fdof/fcomp-1; k >= 0; --k) { 3655a5e93ea8SMatthew G. Knepley for (c = 0; c < fcomp; ++c) { 3656a5e93ea8SMatthew G. Knepley if ((cind < fcdof) && (k*fcomp+c == fcdofs[cind])) { 36571a271a75SMatthew G. Knepley fuse(&a[(fdof/fcomp-1-k)*fcomp+c], values[foffset+k*fcomp+c]); 3658a5e93ea8SMatthew G. Knepley ++cind; 3659a5e93ea8SMatthew G. Knepley } 3660a5e93ea8SMatthew G. Knepley } 3661a5e93ea8SMatthew G. Knepley } 3662a5e93ea8SMatthew G. Knepley } 3663a5e93ea8SMatthew G. Knepley } 36641a271a75SMatthew G. Knepley *offset += fdof; 3665a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 3666a5e93ea8SMatthew G. Knepley } 3667a5e93ea8SMatthew G. Knepley 3668a5e93ea8SMatthew G. Knepley #undef __FUNCT__ 36691b406b76SMatthew G. Knepley #define __FUNCT__ "DMPlexVecSetClosure_Static" 36701a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecSetClosure_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 3671a6dfd86eSKarl Rupp { 3672552f7358SJed Brown PetscScalar *array; 36731b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 36741b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 3675552f7358SJed Brown PetscErrorCode ierr; 3676552f7358SJed Brown 36771b406b76SMatthew G. Knepley PetscFunctionBeginHot; 3678b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3679b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 3680b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3681b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 3682b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 3683b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 3684b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 3685b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 3686b6ebb6e6SMatthew G. Knepley 3687b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 3688b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 3689b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 3690b6ebb6e6SMatthew G. Knepley { 3691b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 3692b6ebb6e6SMatthew G. Knepley PetscScalar *a; 3693b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 3694b6ebb6e6SMatthew G. Knepley 3695b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 3696b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 3697b6ebb6e6SMatthew G. Knepley a = &array[coff]; 3698b6ebb6e6SMatthew G. Knepley if (!cdof) { 3699b6ebb6e6SMatthew G. Knepley if (o >= 0) { 3700b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3701b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 3702b6ebb6e6SMatthew G. Knepley } 3703b6ebb6e6SMatthew G. Knepley } else { 3704b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3705b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 3706b6ebb6e6SMatthew G. Knepley } 3707b6ebb6e6SMatthew G. Knepley } 3708b6ebb6e6SMatthew G. Knepley } else { 3709b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 3710b6ebb6e6SMatthew G. Knepley if (o >= 0) { 3711b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3712b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3713b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 3714b6ebb6e6SMatthew G. Knepley } 3715b6ebb6e6SMatthew G. Knepley } else { 3716b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3717b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3718b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 3719b6ebb6e6SMatthew G. Knepley } 3720b6ebb6e6SMatthew G. Knepley } 3721b6ebb6e6SMatthew G. Knepley } 3722b6ebb6e6SMatthew G. Knepley } 3723b6ebb6e6SMatthew G. Knepley } 3724b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 3725b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 3726b6ebb6e6SMatthew G. Knepley } 37271b406b76SMatthew G. Knepley 37281b406b76SMatthew G. Knepley #undef __FUNCT__ 37291b406b76SMatthew G. Knepley #define __FUNCT__ "DMPlexVecSetClosure" 37301b406b76SMatthew G. Knepley /*@C 37311b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 37321b406b76SMatthew G. Knepley 37331b406b76SMatthew G. Knepley Not collective 37341b406b76SMatthew G. Knepley 37351b406b76SMatthew G. Knepley Input Parameters: 37361b406b76SMatthew G. Knepley + dm - The DM 37371b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 37381b406b76SMatthew G. Knepley . v - The local vector 37391b406b76SMatthew G. Knepley . point - The sieve point in the DM 37401b406b76SMatthew G. Knepley . values - The array of values 37411b406b76SMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 37421b406b76SMatthew G. Knepley 37431b406b76SMatthew G. Knepley Fortran Notes: 37441b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 37451b406b76SMatthew G. Knepley 37461b406b76SMatthew G. Knepley Level: intermediate 37471b406b76SMatthew G. Knepley 37481b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 37491b406b76SMatthew G. Knepley @*/ 37501b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 37511b406b76SMatthew G. Knepley { 37521b406b76SMatthew G. Knepley PetscSection clSection; 37531b406b76SMatthew G. Knepley IS clPoints; 37541b406b76SMatthew G. Knepley PetscScalar *array; 37551b406b76SMatthew G. Knepley PetscInt *points = NULL; 37561b406b76SMatthew G. Knepley const PetscInt *clp; 37571a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, p; 37581b406b76SMatthew G. Knepley PetscErrorCode ierr; 37591b406b76SMatthew G. Knepley 37601a271a75SMatthew G. Knepley PetscFunctionBeginHot; 37611b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37621b406b76SMatthew G. Knepley if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 37631a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 37641a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 37651b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 37661b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 37671b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 37681a271a75SMatthew G. Knepley ierr = DMPlexVecSetClosure_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 37691b406b76SMatthew G. Knepley PetscFunctionReturn(0); 37701b406b76SMatthew G. Knepley } 37711a271a75SMatthew G. Knepley /* Get points */ 37721b406b76SMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 37731b406b76SMatthew G. Knepley if (!clPoints) { 37741a271a75SMatthew G. Knepley PetscInt pStart, pEnd, q; 37751a271a75SMatthew G. Knepley 37761a271a75SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3777552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 3778552f7358SJed Brown /* Compress out points not in the section */ 3779552f7358SJed Brown for (p = 0, q = 0; p < numPoints*2; p += 2) { 3780552f7358SJed Brown if ((points[p] >= pStart) && (points[p] < pEnd)) { 3781552f7358SJed Brown points[q*2] = points[p]; 3782552f7358SJed Brown points[q*2+1] = points[p+1]; 3783552f7358SJed Brown ++q; 3784552f7358SJed Brown } 3785552f7358SJed Brown } 3786552f7358SJed Brown numPoints = q; 37871b406b76SMatthew G. Knepley } else { 37881b406b76SMatthew G. Knepley PetscInt dof, off; 3789552f7358SJed Brown 37901b406b76SMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 37911b406b76SMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 37921b406b76SMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 37931a271a75SMatthew G. Knepley numPoints = dof/2; 37941b406b76SMatthew G. Knepley points = (PetscInt *) &clp[off]; 3795552f7358SJed Brown } 37961a271a75SMatthew G. Knepley /* Get array */ 3797552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 37981a271a75SMatthew G. Knepley /* Get values */ 3799ef90cfe2SMatthew G. Knepley if (numFields > 0) { 38001a271a75SMatthew G. Knepley PetscInt offset = 0, fcomp, f; 3801552f7358SJed Brown for (f = 0; f < numFields; ++f) { 38021a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 3803552f7358SJed Brown switch (mode) { 3804552f7358SJed Brown case INSERT_VALUES: 3805552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 38061a271a75SMatthew G. Knepley const PetscInt point = points[p]; 38071a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 38081a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_FALSE, values, &offset, array); 3809552f7358SJed Brown } break; 3810552f7358SJed Brown case INSERT_ALL_VALUES: 3811552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 38121a271a75SMatthew G. Knepley const PetscInt point = points[p]; 38131a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 38141a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_TRUE, values, &offset, array); 3815552f7358SJed Brown } break; 3816a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 3817a5e93ea8SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 38181a271a75SMatthew G. Knepley const PetscInt point = points[p]; 38191a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 38201a271a75SMatthew G. Knepley updatePointFieldsBC_private(section, point, o, f, fcomp, insert, values, &offset, array); 3821a5e93ea8SMatthew G. Knepley } break; 3822552f7358SJed Brown case ADD_VALUES: 3823552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 38241a271a75SMatthew G. Knepley const PetscInt point = points[p]; 38251a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 38261a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_FALSE, values, &offset, array); 3827552f7358SJed Brown } break; 3828552f7358SJed Brown case ADD_ALL_VALUES: 3829552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 38301a271a75SMatthew G. Knepley const PetscInt point = points[p]; 38311a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 38321a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_TRUE, values, &offset, array); 3833552f7358SJed Brown } break; 3834304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 3835304ab55fSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3836304ab55fSMatthew G. Knepley const PetscInt point = points[p]; 3837304ab55fSMatthew G. Knepley const PetscInt o = points[p+1]; 3838304ab55fSMatthew G. Knepley updatePointFieldsBC_private(section, point, o, f, fcomp, add, values, &offset, array); 3839304ab55fSMatthew G. Knepley } break; 3840552f7358SJed Brown default: 3841f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 3842552f7358SJed Brown } 38431a271a75SMatthew G. Knepley } 3844552f7358SJed Brown } else { 38451a271a75SMatthew G. Knepley PetscInt dof, off; 38461a271a75SMatthew G. Knepley 3847552f7358SJed Brown switch (mode) { 3848552f7358SJed Brown case INSERT_VALUES: 3849552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3850552f7358SJed Brown PetscInt o = points[p+1]; 3851552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3852552f7358SJed Brown updatePoint_private(section, points[p], dof, insert, PETSC_FALSE, o, &values[off], array); 3853552f7358SJed Brown } break; 3854552f7358SJed Brown case INSERT_ALL_VALUES: 3855552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3856552f7358SJed Brown PetscInt o = points[p+1]; 3857552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3858552f7358SJed Brown updatePoint_private(section, points[p], dof, insert, PETSC_TRUE, o, &values[off], array); 3859552f7358SJed Brown } break; 3860a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 3861a5e93ea8SMatthew G. Knepley for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3862a5e93ea8SMatthew G. Knepley PetscInt o = points[p+1]; 3863a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3864a5e93ea8SMatthew G. Knepley updatePointBC_private(section, points[p], dof, insert, o, &values[off], array); 3865a5e93ea8SMatthew G. Knepley } break; 3866552f7358SJed Brown case ADD_VALUES: 3867552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3868552f7358SJed Brown PetscInt o = points[p+1]; 3869552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3870552f7358SJed Brown updatePoint_private(section, points[p], dof, add, PETSC_FALSE, o, &values[off], array); 3871552f7358SJed Brown } break; 3872552f7358SJed Brown case ADD_ALL_VALUES: 3873552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3874552f7358SJed Brown PetscInt o = points[p+1]; 3875552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3876552f7358SJed Brown updatePoint_private(section, points[p], dof, add, PETSC_TRUE, o, &values[off], array); 3877552f7358SJed Brown } break; 3878304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 3879304ab55fSMatthew G. Knepley for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3880304ab55fSMatthew G. Knepley PetscInt o = points[p+1]; 3881304ab55fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3882304ab55fSMatthew G. Knepley updatePointBC_private(section, points[p], dof, add, o, &values[off], array); 3883304ab55fSMatthew G. Knepley } break; 3884552f7358SJed Brown default: 3885f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 3886552f7358SJed Brown } 3887552f7358SJed Brown } 38881a271a75SMatthew G. Knepley /* Cleanup points */ 38891a271a75SMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 38901a271a75SMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 38911a271a75SMatthew G. Knepley /* Cleanup array */ 3892552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 3893552f7358SJed Brown PetscFunctionReturn(0); 3894552f7358SJed Brown } 3895552f7358SJed Brown 3896552f7358SJed Brown #undef __FUNCT__ 3897e07394fbSMatthew G. Knepley #define __FUNCT__ "DMPlexVecSetFieldClosure_Internal" 3898e07394fbSMatthew G. Knepley PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM dm, PetscSection section, Vec v, PetscBool fieldActive[], PetscInt point, const PetscScalar values[], InsertMode mode) 3899e07394fbSMatthew G. Knepley { 3900e07394fbSMatthew G. Knepley PetscSection clSection; 3901e07394fbSMatthew G. Knepley IS clPoints; 3902e07394fbSMatthew G. Knepley PetscScalar *array; 3903e07394fbSMatthew G. Knepley PetscInt *points = NULL; 3904e07394fbSMatthew G. Knepley const PetscInt *clp; 3905e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 3906e07394fbSMatthew G. Knepley PetscInt offset = 0, fcomp, f; 3907e07394fbSMatthew G. Knepley PetscErrorCode ierr; 3908e07394fbSMatthew G. Knepley 3909e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 3910e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3911e07394fbSMatthew G. Knepley if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 3912e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 3913e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 3914e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 3915e07394fbSMatthew G. Knepley /* Get points */ 3916e07394fbSMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 3917e07394fbSMatthew G. Knepley if (!clPoints) { 3918e07394fbSMatthew G. Knepley PetscInt pStart, pEnd, q; 3919e07394fbSMatthew G. Knepley 3920e07394fbSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3921e07394fbSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 3922e07394fbSMatthew G. Knepley /* Compress out points not in the section */ 3923e07394fbSMatthew G. Knepley for (p = 0, q = 0; p < numPoints*2; p += 2) { 3924e07394fbSMatthew G. Knepley if ((points[p] >= pStart) && (points[p] < pEnd)) { 3925e07394fbSMatthew G. Knepley points[q*2] = points[p]; 3926e07394fbSMatthew G. Knepley points[q*2+1] = points[p+1]; 3927e07394fbSMatthew G. Knepley ++q; 3928e07394fbSMatthew G. Knepley } 3929e07394fbSMatthew G. Knepley } 3930e07394fbSMatthew G. Knepley numPoints = q; 3931e07394fbSMatthew G. Knepley } else { 3932e07394fbSMatthew G. Knepley PetscInt dof, off; 3933e07394fbSMatthew G. Knepley 3934e07394fbSMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 3935e07394fbSMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 3936e07394fbSMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 3937e07394fbSMatthew G. Knepley numPoints = dof/2; 3938e07394fbSMatthew G. Knepley points = (PetscInt *) &clp[off]; 3939e07394fbSMatthew G. Knepley } 3940e07394fbSMatthew G. Knepley /* Get array */ 3941e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 3942e07394fbSMatthew G. Knepley /* Get values */ 3943e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 3944e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 3945e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 3946e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3947e07394fbSMatthew G. Knepley PetscInt fdof; 3948e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 3949e07394fbSMatthew G. Knepley offset += fdof; 3950e07394fbSMatthew G. Knepley } 3951e07394fbSMatthew G. Knepley continue; 3952e07394fbSMatthew G. Knepley } 3953e07394fbSMatthew G. Knepley switch (mode) { 3954e07394fbSMatthew G. Knepley case INSERT_VALUES: 3955e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3956e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3957e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3958e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_FALSE, values, &offset, array); 3959e07394fbSMatthew G. Knepley } break; 3960e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 3961e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3962e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3963e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3964e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_TRUE, values, &offset, array); 3965e07394fbSMatthew G. Knepley } break; 3966e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 3967e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3968e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3969e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3970e07394fbSMatthew G. Knepley updatePointFieldsBC_private(section, point, o, f, fcomp, insert, values, &offset, array); 3971e07394fbSMatthew G. Knepley } break; 3972e07394fbSMatthew G. Knepley case ADD_VALUES: 3973e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3974e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3975e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3976e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_FALSE, values, &offset, array); 3977e07394fbSMatthew G. Knepley } break; 3978e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 3979e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3980e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3981e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3982e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_TRUE, values, &offset, array); 3983e07394fbSMatthew G. Knepley } break; 3984e07394fbSMatthew G. Knepley default: 3985f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 3986e07394fbSMatthew G. Knepley } 3987e07394fbSMatthew G. Knepley } 3988e07394fbSMatthew G. Knepley /* Cleanup points */ 3989e07394fbSMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 3990e07394fbSMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 3991e07394fbSMatthew G. Knepley /* Cleanup array */ 3992e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 3993e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 3994e07394fbSMatthew G. Knepley } 3995e07394fbSMatthew G. Knepley 3996e07394fbSMatthew G. Knepley #undef __FUNCT__ 3997552f7358SJed Brown #define __FUNCT__ "DMPlexPrintMatSetValues" 3998b0ecff45SMatthew G. Knepley PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 3999552f7358SJed Brown { 4000552f7358SJed Brown PetscMPIInt rank; 4001552f7358SJed Brown PetscInt i, j; 4002552f7358SJed Brown PetscErrorCode ierr; 4003552f7358SJed Brown 4004552f7358SJed Brown PetscFunctionBegin; 400582f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr); 4006f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for sieve point %D\n", rank, point);CHKERRQ(ierr); 4007e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 4008e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 4009b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 4010b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 4011e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 4012b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 4013519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 40147eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 4015552f7358SJed Brown #else 4016b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 4017552f7358SJed Brown #endif 4018552f7358SJed Brown } 401977a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 4020552f7358SJed Brown } 4021552f7358SJed Brown PetscFunctionReturn(0); 4022552f7358SJed Brown } 4023552f7358SJed Brown 4024552f7358SJed Brown #undef __FUNCT__ 4025415ce65aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetIndicesPoint_Internal" 4026552f7358SJed Brown /* . off - The global offset of this point */ 4027415ce65aSMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, PetscInt orientation, PetscInt indices[]) 4028a6dfd86eSKarl Rupp { 4029e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 4030552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 4031552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4032552f7358SJed Brown PetscInt cind = 0, k; 4033552f7358SJed Brown PetscErrorCode ierr; 4034552f7358SJed Brown 4035552f7358SJed Brown PetscFunctionBegin; 4036552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 4037552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4038552f7358SJed Brown if (!cdof || setBC) { 4039552f7358SJed Brown if (orientation >= 0) { 4040e6ccafaeSMatthew G Knepley for (k = 0; k < dof; ++k) indices[*loff+k] = off+k; 4041552f7358SJed Brown } else { 4042e6ccafaeSMatthew G Knepley for (k = 0; k < dof; ++k) indices[*loff+dof-k-1] = off+k; 4043552f7358SJed Brown } 4044552f7358SJed Brown } else { 4045552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 4046552f7358SJed Brown if (orientation >= 0) { 4047552f7358SJed Brown for (k = 0; k < dof; ++k) { 4048552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) { 4049552f7358SJed Brown /* Insert check for returning constrained indices */ 4050e6ccafaeSMatthew G Knepley indices[*loff+k] = -(off+k+1); 4051552f7358SJed Brown ++cind; 4052552f7358SJed Brown } else { 4053e6ccafaeSMatthew G Knepley indices[*loff+k] = off+k-cind; 4054552f7358SJed Brown } 4055552f7358SJed Brown } 4056552f7358SJed Brown } else { 4057552f7358SJed Brown for (k = 0; k < dof; ++k) { 4058552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) { 4059552f7358SJed Brown /* Insert check for returning constrained indices */ 4060e6ccafaeSMatthew G Knepley indices[*loff+dof-k-1] = -(off+k+1); 4061552f7358SJed Brown ++cind; 4062552f7358SJed Brown } else { 4063e6ccafaeSMatthew G Knepley indices[*loff+dof-k-1] = off+k-cind; 4064552f7358SJed Brown } 4065552f7358SJed Brown } 4066552f7358SJed Brown } 4067552f7358SJed Brown } 4068e6ccafaeSMatthew G Knepley *loff += dof; 4069552f7358SJed Brown PetscFunctionReturn(0); 4070552f7358SJed Brown } 4071552f7358SJed Brown 4072552f7358SJed Brown #undef __FUNCT__ 4073415ce65aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetIndicesPointFields_Internal" 4074552f7358SJed Brown /* . off - The global offset of this point */ 4075415ce65aSMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt foffs[], PetscBool setBC, PetscInt orientation, PetscInt indices[]) 4076a6dfd86eSKarl Rupp { 4077552f7358SJed Brown PetscInt numFields, foff, f; 4078552f7358SJed Brown PetscErrorCode ierr; 4079552f7358SJed Brown 4080552f7358SJed Brown PetscFunctionBegin; 4081552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4082552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 4083552f7358SJed Brown PetscInt fdof, fcomp, cfdof; 4084552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 4085552f7358SJed Brown PetscInt cind = 0, k, c; 4086552f7358SJed Brown 4087552f7358SJed Brown ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 4088552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4089552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 4090552f7358SJed Brown if (!cfdof || setBC) { 4091552f7358SJed Brown if (orientation >= 0) { 40920d644c17SKarl Rupp for (k = 0; k < fdof; ++k) indices[foffs[f]+k] = off+foff+k; 4093552f7358SJed Brown } else { 4094552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 4095552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 4096552f7358SJed Brown indices[foffs[f]+k*fcomp+c] = off+foff+(fdof/fcomp-1-k)*fcomp+c; 4097552f7358SJed Brown } 4098552f7358SJed Brown } 4099552f7358SJed Brown } 4100552f7358SJed Brown } else { 4101552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 4102552f7358SJed Brown if (orientation >= 0) { 4103552f7358SJed Brown for (k = 0; k < fdof; ++k) { 4104552f7358SJed Brown if ((cind < cfdof) && (k == fcdofs[cind])) { 4105552f7358SJed Brown indices[foffs[f]+k] = -(off+foff+k+1); 4106552f7358SJed Brown ++cind; 4107552f7358SJed Brown } else { 4108552f7358SJed Brown indices[foffs[f]+k] = off+foff+k-cind; 4109552f7358SJed Brown } 4110552f7358SJed Brown } 4111552f7358SJed Brown } else { 4112552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 4113552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 4114552f7358SJed Brown if ((cind < cfdof) && ((fdof/fcomp-1-k)*fcomp+c == fcdofs[cind])) { 4115552f7358SJed Brown indices[foffs[f]+k*fcomp+c] = -(off+foff+(fdof/fcomp-1-k)*fcomp+c+1); 4116552f7358SJed Brown ++cind; 4117552f7358SJed Brown } else { 4118552f7358SJed Brown indices[foffs[f]+k*fcomp+c] = off+foff+(fdof/fcomp-1-k)*fcomp+c-cind; 4119552f7358SJed Brown } 4120552f7358SJed Brown } 4121552f7358SJed Brown } 4122552f7358SJed Brown } 4123552f7358SJed Brown } 4124a9096520SToby Isaac foff += (setBC ? fdof : (fdof - cfdof)); 4125552f7358SJed Brown foffs[f] += fdof; 4126552f7358SJed Brown } 4127552f7358SJed Brown PetscFunctionReturn(0); 4128552f7358SJed Brown } 4129552f7358SJed Brown 4130552f7358SJed Brown #undef __FUNCT__ 4131f7c74593SToby Isaac #define __FUNCT__ "DMPlexAnchorsModifyMat" 41326ecaa68aSToby Isaac PetscErrorCode DMPlexAnchorsModifyMat(DM dm, PetscSection section, PetscInt numPoints, PetscInt numIndices, const PetscInt points[], const PetscScalar values[], PetscInt *outNumPoints, PetscInt *outNumIndices, PetscInt *outPoints[], PetscScalar *outValues[], PetscInt offsets[], PetscBool multiplyLeft) 4133d3d1a6afSToby Isaac { 4134d3d1a6afSToby Isaac Mat cMat; 4135d3d1a6afSToby Isaac PetscSection aSec, cSec; 4136d3d1a6afSToby Isaac IS aIS; 4137d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 4138d3d1a6afSToby Isaac const PetscInt *anchors; 4139e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 4140d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 4141d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 4142d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 4143d3d1a6afSToby Isaac PetscInt newOffsets[32]; 4144d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 4145d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 4146d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 41476ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 4148d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 4149d3d1a6afSToby Isaac PetscErrorCode ierr; 4150d3d1a6afSToby Isaac 4151d3d1a6afSToby Isaac PetscFunctionBegin; 4152d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4153d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 4154d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4155d3d1a6afSToby Isaac 4156a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 4157d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 4158d3d1a6afSToby Isaac if (aSec) { 4159d3d1a6afSToby Isaac ierr = PetscMemzero(newOffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 4160d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 4161d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 4162d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 4163d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 4164d3d1a6afSToby Isaac * into the global matrix anyway) */ 4165d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 4166d3d1a6afSToby Isaac PetscInt b = points[p]; 41674b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 4168d3d1a6afSToby Isaac 41694b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 41704b2f2278SToby Isaac if (!bSecDof) { 41714b2f2278SToby Isaac continue; 41724b2f2278SToby Isaac } 4173d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4174d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 4175d3d1a6afSToby Isaac } 4176d3d1a6afSToby Isaac if (bDof) { 4177d3d1a6afSToby Isaac /* this point is constrained */ 4178d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 4179d3d1a6afSToby Isaac PetscInt bOff, q; 4180d3d1a6afSToby Isaac 4181d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 4182d3d1a6afSToby Isaac newNumPoints += bDof; 4183d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 4184d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4185d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 4186d3d1a6afSToby Isaac PetscInt aDof; 4187d3d1a6afSToby Isaac 4188d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 4189d3d1a6afSToby Isaac newNumIndices += aDof; 4190d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 4191d3d1a6afSToby Isaac PetscInt fDof; 4192d3d1a6afSToby Isaac 4193d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 4194d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 4195d3d1a6afSToby Isaac } 4196d3d1a6afSToby Isaac } 4197d3d1a6afSToby Isaac } 4198d3d1a6afSToby Isaac else { 4199d3d1a6afSToby Isaac /* this point is not constrained */ 4200d3d1a6afSToby Isaac newNumPoints++; 42014b2f2278SToby Isaac newNumIndices += bSecDof; 4202d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 4203d3d1a6afSToby Isaac PetscInt fDof; 4204d3d1a6afSToby Isaac 4205d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 4206d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 4207d3d1a6afSToby Isaac } 4208d3d1a6afSToby Isaac } 4209d3d1a6afSToby Isaac } 4210d3d1a6afSToby Isaac } 4211d3d1a6afSToby Isaac if (!anyConstrained) { 421272b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 421372b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 421472b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 421572b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 421672b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 4217d3d1a6afSToby Isaac PetscFunctionReturn(0); 4218d3d1a6afSToby Isaac } 4219d3d1a6afSToby Isaac 42206ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 42216ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 42226ecaa68aSToby Isaac 4223d3d1a6afSToby Isaac for (f = 1; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 4224d3d1a6afSToby Isaac 42256ecaa68aSToby Isaac if (!outPoints && !outValues) { 42266ecaa68aSToby Isaac if (offsets) { 42276ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 42286ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 42296ecaa68aSToby Isaac } 42306ecaa68aSToby Isaac } 42316ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 42326ecaa68aSToby Isaac PetscFunctionReturn(0); 42336ecaa68aSToby Isaac } 42346ecaa68aSToby Isaac 4235f347f43bSBarry Smith if (numFields && newOffsets[numFields] != newNumIndices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 4236d3d1a6afSToby Isaac 4237f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 4238d3d1a6afSToby Isaac 4239d3d1a6afSToby Isaac /* workspaces */ 4240d3d1a6afSToby Isaac if (numFields) { 4241d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4242d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 4243d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints+1,PETSC_INT,&newPointOffsets[f]);CHKERRQ(ierr); 4244d3d1a6afSToby Isaac } 4245d3d1a6afSToby Isaac } 4246d3d1a6afSToby Isaac else { 4247d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 4248d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints,PETSC_INT,&newPointOffsets[0]);CHKERRQ(ierr); 4249d3d1a6afSToby Isaac } 4250d3d1a6afSToby Isaac 4251d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 4252d3d1a6afSToby Isaac if (numFields) { 42534b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 42544b2f2278SToby Isaac 4255d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4256d3d1a6afSToby Isaac PetscInt b = points[2*p]; 42574b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 4258d3d1a6afSToby Isaac 42594b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 42604b2f2278SToby Isaac if (!bSecDof) { 42614b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 42624b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 42634b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 42644b2f2278SToby Isaac } 42654b2f2278SToby Isaac continue; 42664b2f2278SToby Isaac } 4267d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4268d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4269d3d1a6afSToby Isaac } 4270d3d1a6afSToby Isaac if (bDof) { 4271d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4272d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 4273d3d1a6afSToby Isaac 4274d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 4275d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 4276d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4277d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 4278d3d1a6afSToby Isaac PetscInt aFDof; 4279d3d1a6afSToby Isaac 4280d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 4281d3d1a6afSToby Isaac allFDof += aFDof; 4282d3d1a6afSToby Isaac } 4283d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 4284d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 4285d3d1a6afSToby Isaac } 4286d3d1a6afSToby Isaac } 4287d3d1a6afSToby Isaac else { 4288d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4289d3d1a6afSToby Isaac PetscInt fDof; 4290d3d1a6afSToby Isaac 4291d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 4292d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 4293d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 4294d3d1a6afSToby Isaac } 4295d3d1a6afSToby Isaac } 4296d3d1a6afSToby Isaac } 42974b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 42984b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 42994b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 4300d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4301d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 4302d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 4303d3d1a6afSToby Isaac } 430419f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 430519f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 4306d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],PETSC_SCALAR,&pointMat[f]);CHKERRQ(ierr); 4307d3d1a6afSToby Isaac } 4308d3d1a6afSToby Isaac } 4309d3d1a6afSToby Isaac else { 4310d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4311d3d1a6afSToby Isaac PetscInt b = points[2*p]; 43124b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 4313d3d1a6afSToby Isaac 43144b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 43154b2f2278SToby Isaac if (!bSecDof) { 43164b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 43174b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 43184b2f2278SToby Isaac continue; 43194b2f2278SToby Isaac } 4320d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4321d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4322d3d1a6afSToby Isaac } 4323d3d1a6afSToby Isaac if (bDof) { 43244b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 4325d3d1a6afSToby Isaac 4326d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 4327d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4328d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 4329d3d1a6afSToby Isaac 4330d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 4331d3d1a6afSToby Isaac allDof += aDof; 4332d3d1a6afSToby Isaac } 4333d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 43344b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 4335d3d1a6afSToby Isaac } 4336d3d1a6afSToby Isaac else { 43374b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 4338d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 4339d3d1a6afSToby Isaac } 4340d3d1a6afSToby Isaac } 4341d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 4342d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 4343d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4344d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 4345d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 4346d3d1a6afSToby Isaac } 4347d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],PETSC_SCALAR,&pointMat[0]);CHKERRQ(ierr); 4348d3d1a6afSToby Isaac } 4349d3d1a6afSToby Isaac 43506ecaa68aSToby Isaac /* output arrays */ 43516ecaa68aSToby Isaac ierr = DMGetWorkArray(dm,2*newNumPoints,PETSC_INT,&newPoints);CHKERRQ(ierr); 43526ecaa68aSToby Isaac 4353d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 4354d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 4355d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 4356d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,maxDof,PETSC_INT,&indices);CHKERRQ(ierr); 4357d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,maxAnchor*maxDof,PETSC_INT,&newIndices);CHKERRQ(ierr); 4358d3d1a6afSToby Isaac if (numFields) { 4359d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 4360d3d1a6afSToby Isaac PetscInt b = points[2*p]; 4361d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 43624b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 4363d3d1a6afSToby Isaac 43644b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 43654b2f2278SToby Isaac if (!bSecDof) { 43664b2f2278SToby Isaac continue; 43674b2f2278SToby Isaac } 4368d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4369d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4370d3d1a6afSToby Isaac } 4371d3d1a6afSToby Isaac if (bDof) { 4372d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 4373d3d1a6afSToby Isaac 4374d3d1a6afSToby Isaac fStart[0] = 0; 4375d3d1a6afSToby Isaac fEnd[0] = 0; 4376d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4377d3d1a6afSToby Isaac PetscInt fDof; 4378d3d1a6afSToby Isaac 4379d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 4380d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 4381d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 4382d3d1a6afSToby Isaac } 4383d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 4384415ce65aSMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(cSec, b, bOff, fEnd, PETSC_TRUE, o, indices);CHKERRQ(ierr); 4385d3d1a6afSToby Isaac 4386d3d1a6afSToby Isaac fAnchorStart[0] = 0; 4387d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 4388d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4389d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 4390d3d1a6afSToby Isaac 4391d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 4392d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 4393d3d1a6afSToby Isaac } 4394d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 4395d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4396d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 4397d3d1a6afSToby Isaac 4398d3d1a6afSToby Isaac /* we take the orientation of ap into account in the order that we constructed the indices above: the newly added points have no orientation */ 4399d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 4400d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 4401302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 4402415ce65aSMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(section, a, aOff, fAnchorEnd, PETSC_TRUE, 0, newIndices);CHKERRQ(ierr); 4403d3d1a6afSToby Isaac } 4404d3d1a6afSToby Isaac newP += bDof; 4405d3d1a6afSToby Isaac 44066ecaa68aSToby Isaac if (outValues) { 4407d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 4408d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4409d3d1a6afSToby Isaac ierr = MatGetValues(cMat,fEnd[f]-fStart[f],indices + fStart[f],fAnchorEnd[f] - fAnchorStart[f],newIndices + fAnchorStart[f],pointMat[f] + pointMatOffsets[f][p]);CHKERRQ(ierr); 4410d3d1a6afSToby Isaac } 4411d3d1a6afSToby Isaac } 44126ecaa68aSToby Isaac } 4413d3d1a6afSToby Isaac else { 4414d3d1a6afSToby Isaac newPoints[2 * newP] = b; 4415d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 4416d3d1a6afSToby Isaac newP++; 4417d3d1a6afSToby Isaac } 4418d3d1a6afSToby Isaac } 4419d3d1a6afSToby Isaac } else { 4420d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4421d3d1a6afSToby Isaac PetscInt b = points[2*p]; 4422d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 44234b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 4424d3d1a6afSToby Isaac 44254b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 44264b2f2278SToby Isaac if (!bSecDof) { 44274b2f2278SToby Isaac continue; 44284b2f2278SToby Isaac } 4429d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4430d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4431d3d1a6afSToby Isaac } 4432d3d1a6afSToby Isaac if (bDof) { 4433d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 4434d3d1a6afSToby Isaac 4435d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 4436415ce65aSMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(cSec, b, bOff, &bEnd, PETSC_TRUE, o, indices);CHKERRQ(ierr); 4437d3d1a6afSToby Isaac 4438d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 4439d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4440d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 4441d3d1a6afSToby Isaac 4442d3d1a6afSToby Isaac /* we take the orientation of ap into account in the order that we constructed the indices above: the newly added points have no orientation */ 4443d3d1a6afSToby Isaac 4444d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 4445d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 4446302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 4447415ce65aSMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(section, a, aOff, &bAnchorEnd, PETSC_TRUE, 0, newIndices);CHKERRQ(ierr); 4448d3d1a6afSToby Isaac } 4449d3d1a6afSToby Isaac newP += bDof; 4450d3d1a6afSToby Isaac 4451d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 44526ecaa68aSToby Isaac if (outValues) { 4453d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 4454d3d1a6afSToby Isaac } 44556ecaa68aSToby Isaac } 4456d3d1a6afSToby Isaac else { 4457d3d1a6afSToby Isaac newPoints[2 * newP] = b; 4458d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 4459d3d1a6afSToby Isaac newP++; 4460d3d1a6afSToby Isaac } 4461d3d1a6afSToby Isaac } 4462d3d1a6afSToby Isaac } 4463d3d1a6afSToby Isaac 44646ecaa68aSToby Isaac if (outValues) { 44656ecaa68aSToby Isaac ierr = DMGetWorkArray(dm,newNumIndices*numIndices,PETSC_SCALAR,&tmpValues);CHKERRQ(ierr); 4466d3d1a6afSToby Isaac ierr = PetscMemzero(tmpValues,newNumIndices*numIndices*sizeof(*tmpValues));CHKERRQ(ierr); 4467d3d1a6afSToby Isaac /* multiply constraints on the right */ 4468d3d1a6afSToby Isaac if (numFields) { 4469d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4470d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 4471d3d1a6afSToby Isaac 4472d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4473d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 4474d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4475d3d1a6afSToby Isaac PetscInt c, r, k; 4476d3d1a6afSToby Isaac PetscInt dof; 4477d3d1a6afSToby Isaac 4478d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 44794b2f2278SToby Isaac if (!dof) { 44804b2f2278SToby Isaac continue; 44814b2f2278SToby Isaac } 4482d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 4483d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 4484d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 4485d3d1a6afSToby Isaac 4486d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4487d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 4488d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4489d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 4490d3d1a6afSToby Isaac } 4491d3d1a6afSToby Isaac } 4492d3d1a6afSToby Isaac } 4493d3d1a6afSToby Isaac } 4494d3d1a6afSToby Isaac else { 4495d3d1a6afSToby Isaac /* copy this column as is */ 4496d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4497d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 4498d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 4499d3d1a6afSToby Isaac } 4500d3d1a6afSToby Isaac } 4501d3d1a6afSToby Isaac } 4502d3d1a6afSToby Isaac oldOff += dof; 4503d3d1a6afSToby Isaac } 4504d3d1a6afSToby Isaac } 4505d3d1a6afSToby Isaac } 4506d3d1a6afSToby Isaac else { 4507d3d1a6afSToby Isaac PetscInt oldOff = 0; 4508d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4509d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 4510d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4511d3d1a6afSToby Isaac PetscInt c, r, k; 4512d3d1a6afSToby Isaac PetscInt dof; 4513d3d1a6afSToby Isaac 4514d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 45154b2f2278SToby Isaac if (!dof) { 45164b2f2278SToby Isaac continue; 45174b2f2278SToby Isaac } 4518d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 4519d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 4520d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 4521d3d1a6afSToby Isaac 4522d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4523d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 4524d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4525d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 4526d3d1a6afSToby Isaac } 4527d3d1a6afSToby Isaac } 4528d3d1a6afSToby Isaac } 4529d3d1a6afSToby Isaac } 4530d3d1a6afSToby Isaac else { 4531d3d1a6afSToby Isaac /* copy this column as is */ 4532d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4533d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 4534d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 4535d3d1a6afSToby Isaac } 4536d3d1a6afSToby Isaac } 4537d3d1a6afSToby Isaac } 4538d3d1a6afSToby Isaac oldOff += dof; 4539d3d1a6afSToby Isaac } 4540d3d1a6afSToby Isaac } 4541d3d1a6afSToby Isaac 45426ecaa68aSToby Isaac if (multiplyLeft) { 45436ecaa68aSToby Isaac ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,PETSC_SCALAR,&newValues);CHKERRQ(ierr); 4544d3d1a6afSToby Isaac ierr = PetscMemzero(newValues,newNumIndices*newNumIndices*sizeof(*newValues));CHKERRQ(ierr); 4545d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 4546d3d1a6afSToby Isaac if (numFields) { 4547d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4548d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 4549d3d1a6afSToby Isaac 4550d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4551d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 4552d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4553d3d1a6afSToby Isaac PetscInt c, r, k; 4554d3d1a6afSToby Isaac PetscInt dof; 4555d3d1a6afSToby Isaac 4556d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 4557d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 4558d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 4559d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 4560d3d1a6afSToby Isaac 4561d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 4562d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4563d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4564d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 4565d3d1a6afSToby Isaac } 4566d3d1a6afSToby Isaac } 4567d3d1a6afSToby Isaac } 4568d3d1a6afSToby Isaac } 4569d3d1a6afSToby Isaac else { 4570d3d1a6afSToby Isaac /* copy this row as is */ 4571d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 4572d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4573d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 4574d3d1a6afSToby Isaac } 4575d3d1a6afSToby Isaac } 4576d3d1a6afSToby Isaac } 4577d3d1a6afSToby Isaac oldOff += dof; 4578d3d1a6afSToby Isaac } 4579d3d1a6afSToby Isaac } 4580d3d1a6afSToby Isaac } 4581d3d1a6afSToby Isaac else { 4582d3d1a6afSToby Isaac PetscInt oldOff = 0; 4583d3d1a6afSToby Isaac 4584d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4585d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 4586d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4587d3d1a6afSToby Isaac PetscInt c, r, k; 4588d3d1a6afSToby Isaac PetscInt dof; 4589d3d1a6afSToby Isaac 4590d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 4591d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 4592d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 4593d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 4594d3d1a6afSToby Isaac 4595d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 4596d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4597d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4598d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 4599d3d1a6afSToby Isaac } 4600d3d1a6afSToby Isaac } 4601d3d1a6afSToby Isaac } 4602d3d1a6afSToby Isaac } 4603d3d1a6afSToby Isaac else { 4604d3d1a6afSToby Isaac /* copy this row as is */ 46059fc93327SToby Isaac for (r = 0; r < dof; r++) { 4606d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4607d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 4608d3d1a6afSToby Isaac } 4609d3d1a6afSToby Isaac } 4610d3d1a6afSToby Isaac } 4611d3d1a6afSToby Isaac oldOff += dof; 4612d3d1a6afSToby Isaac } 4613d3d1a6afSToby Isaac } 4614d3d1a6afSToby Isaac 46156ecaa68aSToby Isaac ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,PETSC_SCALAR,&tmpValues);CHKERRQ(ierr); 46166ecaa68aSToby Isaac } 46176ecaa68aSToby Isaac else { 46186ecaa68aSToby Isaac newValues = tmpValues; 46196ecaa68aSToby Isaac } 46206ecaa68aSToby Isaac } 46216ecaa68aSToby Isaac 4622d3d1a6afSToby Isaac /* clean up */ 4623d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,maxDof,PETSC_INT,&indices);CHKERRQ(ierr); 4624d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,PETSC_INT,&newIndices);CHKERRQ(ierr); 46256ecaa68aSToby Isaac 4626d3d1a6afSToby Isaac if (numFields) { 4627d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4628d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],PETSC_SCALAR,&pointMat[f]);CHKERRQ(ierr); 4629d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 4630d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&newPointOffsets[f]);CHKERRQ(ierr); 4631d3d1a6afSToby Isaac } 4632d3d1a6afSToby Isaac } 4633d3d1a6afSToby Isaac else { 4634d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],PETSC_SCALAR,&pointMat[0]);CHKERRQ(ierr); 4635d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 4636d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&newPointOffsets[0]);CHKERRQ(ierr); 4637d3d1a6afSToby Isaac } 4638d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 4639d3d1a6afSToby Isaac 4640d3d1a6afSToby Isaac /* output */ 46416ecaa68aSToby Isaac if (outPoints) { 4642d3d1a6afSToby Isaac *outPoints = newPoints; 46436ecaa68aSToby Isaac } 46446ecaa68aSToby Isaac else { 46456ecaa68aSToby Isaac ierr = DMRestoreWorkArray(dm,2*newNumPoints,PETSC_INT,&newPoints);CHKERRQ(ierr); 46466ecaa68aSToby Isaac } 464731620726SToby Isaac if (outValues) { 4648d3d1a6afSToby Isaac *outValues = newValues; 46496ecaa68aSToby Isaac } 465087a87d9fSToby Isaac else { 465187a87d9fSToby Isaac ierr = DMRestoreWorkArray(dm,newNumIndices*newNumIndices,PETSC_SCALAR,&newValues);CHKERRQ(ierr); 465287a87d9fSToby Isaac } 46536ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 4654d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 4655d3d1a6afSToby Isaac } 4656d3d1a6afSToby Isaac PetscFunctionReturn(0); 4657d3d1a6afSToby Isaac } 4658d3d1a6afSToby Isaac 4659d3d1a6afSToby Isaac #undef __FUNCT__ 46607773e69fSMatthew G. Knepley #define __FUNCT__ "DMPlexGetClosureIndices" 46616ecaa68aSToby Isaac PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices, PetscInt *outOffsets) 46627773e69fSMatthew G. Knepley { 46637773e69fSMatthew G. Knepley PetscSection clSection; 46647773e69fSMatthew G. Knepley IS clPoints; 46657773e69fSMatthew G. Knepley const PetscInt *clp; 46667773e69fSMatthew G. Knepley PetscInt *points = NULL, *pointsNew; 46677773e69fSMatthew G. Knepley PetscInt numPoints, numPointsNew; 46687773e69fSMatthew G. Knepley PetscInt offsets[32]; 46697773e69fSMatthew G. Knepley PetscInt Nf, Nind, NindNew, off, globalOff, f, p; 46707773e69fSMatthew G. Knepley PetscErrorCode ierr; 46717773e69fSMatthew G. Knepley 46727773e69fSMatthew G. Knepley PetscFunctionBegin; 46737773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46747773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 46757773e69fSMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 46767773e69fSMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 4); 46777773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 46787773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 46797773e69fSMatthew G. Knepley if (Nf > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 46807773e69fSMatthew G. Knepley ierr = PetscMemzero(offsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 46817773e69fSMatthew G. Knepley /* Get points in closure */ 46827773e69fSMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 46837773e69fSMatthew G. Knepley if (!clPoints) { 46847773e69fSMatthew G. Knepley PetscInt pStart, pEnd, q; 46857773e69fSMatthew G. Knepley 46867773e69fSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 46877773e69fSMatthew G. Knepley /* Compress out points not in the section */ 46887773e69fSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 46897773e69fSMatthew G. Knepley for (p = 0, q = 0; p < numPoints*2; p += 2) { 46907773e69fSMatthew G. Knepley if ((points[p] >= pStart) && (points[p] < pEnd)) { 46917773e69fSMatthew G. Knepley points[q*2] = points[p]; 46927773e69fSMatthew G. Knepley points[q*2+1] = points[p+1]; 46937773e69fSMatthew G. Knepley ++q; 46947773e69fSMatthew G. Knepley } 46957773e69fSMatthew G. Knepley } 46967773e69fSMatthew G. Knepley numPoints = q; 46977773e69fSMatthew G. Knepley } else { 46987773e69fSMatthew G. Knepley PetscInt dof, off; 46997773e69fSMatthew G. Knepley 47007773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 47017773e69fSMatthew G. Knepley numPoints = dof/2; 47027773e69fSMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 47037773e69fSMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 47047773e69fSMatthew G. Knepley points = (PetscInt *) &clp[off]; 47057773e69fSMatthew G. Knepley } 47067773e69fSMatthew G. Knepley /* Get number of indices and indices per field */ 47077773e69fSMatthew G. Knepley for (p = 0, Nind = 0; p < numPoints*2; p += 2) { 47087773e69fSMatthew G. Knepley PetscInt dof, fdof; 47097773e69fSMatthew G. Knepley 47107773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 47117773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 47127773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 47137773e69fSMatthew G. Knepley offsets[f+1] += fdof; 47147773e69fSMatthew G. Knepley } 47157773e69fSMatthew G. Knepley Nind += dof; 47167773e69fSMatthew G. Knepley } 47177773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 47187773e69fSMatthew G. Knepley if (Nf && offsets[Nf] != Nind) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", offsets[Nf], Nind); 47197773e69fSMatthew G. Knepley /* Correct for hanging node constraints */ 47207773e69fSMatthew G. Knepley { 47216ecaa68aSToby Isaac ierr = DMPlexAnchorsModifyMat(dm, section, numPoints, Nind, points, NULL, &numPointsNew, &NindNew, &pointsNew, NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 47227773e69fSMatthew G. Knepley if (numPointsNew) { 47237773e69fSMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 47247773e69fSMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 47257773e69fSMatthew G. Knepley numPoints = numPointsNew; 47267773e69fSMatthew G. Knepley Nind = NindNew; 47277773e69fSMatthew G. Knepley points = pointsNew; 47287773e69fSMatthew G. Knepley } 47297773e69fSMatthew G. Knepley } 47307773e69fSMatthew G. Knepley /* Calculate indices */ 47317773e69fSMatthew G. Knepley ierr = DMGetWorkArray(dm, Nind, PETSC_INT, indices);CHKERRQ(ierr); 47327773e69fSMatthew G. Knepley if (Nf) { 47336ecaa68aSToby Isaac if (outOffsets) { 47346ecaa68aSToby Isaac PetscInt f; 47356ecaa68aSToby Isaac 473646bdb399SToby Isaac for (f = 0; f <= Nf; f++) { 47376ecaa68aSToby Isaac outOffsets[f] = offsets[f]; 47386ecaa68aSToby Isaac } 47396ecaa68aSToby Isaac } 47407773e69fSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 47417773e69fSMatthew G. Knepley PetscInt o = points[p+1]; 47427773e69fSMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, points[p], &globalOff);CHKERRQ(ierr); 4743415ce65aSMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(section, points[p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, o, *indices); 47447773e69fSMatthew G. Knepley } 47457773e69fSMatthew G. Knepley } else { 47467773e69fSMatthew G. Knepley for (p = 0, off = 0; p < numPoints*2; p += 2) { 47477773e69fSMatthew G. Knepley PetscInt o = points[p+1]; 47487773e69fSMatthew G. Knepley ierr = PetscSectionGetOffset(globalSection, points[p], &globalOff);CHKERRQ(ierr); 4749415ce65aSMatthew G. Knepley DMPlexGetIndicesPoint_Internal(section, points[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, *indices); 47507773e69fSMatthew G. Knepley } 47517773e69fSMatthew G. Knepley } 47527773e69fSMatthew G. Knepley /* Cleanup points */ 47537773e69fSMatthew G. Knepley if (numPointsNew) { 47547773e69fSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 2*numPointsNew, PETSC_INT, &pointsNew);CHKERRQ(ierr); 47557773e69fSMatthew G. Knepley } else { 47567773e69fSMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 47577773e69fSMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 47587773e69fSMatthew G. Knepley } 47597773e69fSMatthew G. Knepley if (numIndices) *numIndices = Nind; 47607773e69fSMatthew G. Knepley PetscFunctionReturn(0); 47617773e69fSMatthew G. Knepley } 47627773e69fSMatthew G. Knepley 47637773e69fSMatthew G. Knepley #undef __FUNCT__ 47647773e69fSMatthew G. Knepley #define __FUNCT__ "DMPlexRestoreClosureIndices" 476546bdb399SToby Isaac PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices,PetscInt *outOffsets) 47667773e69fSMatthew G. Knepley { 47677773e69fSMatthew G. Knepley PetscErrorCode ierr; 47687773e69fSMatthew G. Knepley 47697773e69fSMatthew G. Knepley PetscFunctionBegin; 47707773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47717773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 47727773e69fSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 0, PETSC_INT, indices);CHKERRQ(ierr); 47737773e69fSMatthew G. Knepley PetscFunctionReturn(0); 47747773e69fSMatthew G. Knepley } 47757773e69fSMatthew G. Knepley 47767773e69fSMatthew G. Knepley #undef __FUNCT__ 4777552f7358SJed Brown #define __FUNCT__ "DMPlexMatSetClosure" 47787f5d1fdeSMatthew G. Knepley /*@C 47797f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 47807f5d1fdeSMatthew G. Knepley 47817f5d1fdeSMatthew G. Knepley Not collective 47827f5d1fdeSMatthew G. Knepley 47837f5d1fdeSMatthew G. Knepley Input Parameters: 47847f5d1fdeSMatthew G. Knepley + dm - The DM 4785ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 4786ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 47877f5d1fdeSMatthew G. Knepley . A - The matrix 47887f5d1fdeSMatthew G. Knepley . point - The sieve point in the DM 47897f5d1fdeSMatthew G. Knepley . values - The array of values 47907f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 47917f5d1fdeSMatthew G. Knepley 47927f5d1fdeSMatthew G. Knepley Fortran Notes: 47937f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 47947f5d1fdeSMatthew G. Knepley 47957f5d1fdeSMatthew G. Knepley Level: intermediate 47967f5d1fdeSMatthew G. Knepley 47977f5d1fdeSMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure() 47987f5d1fdeSMatthew G. Knepley @*/ 47997c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 4800552f7358SJed Brown { 4801552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 48021b406b76SMatthew G. Knepley PetscSection clSection; 48031b406b76SMatthew G. Knepley IS clPoints; 4804d3d1a6afSToby Isaac PetscInt *points = NULL, *newPoints; 48051b406b76SMatthew G. Knepley const PetscInt *clp; 4806552f7358SJed Brown PetscInt *indices; 4807552f7358SJed Brown PetscInt offsets[32]; 4808d3d1a6afSToby Isaac PetscInt numFields, numPoints, newNumPoints, numIndices, newNumIndices, dof, off, globalOff, pStart, pEnd, p, q, f; 4809d3d1a6afSToby Isaac PetscScalar *newValues; 4810552f7358SJed Brown PetscErrorCode ierr; 4811552f7358SJed Brown 4812552f7358SJed Brown PetscFunctionBegin; 4813552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4814ebd6d717SJed Brown if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 48153dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 4816ebd6d717SJed Brown if (!globalSection) {ierr = DMGetDefaultGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 48173dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 48183dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 4819552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 482082f516ccSBarry Smith if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 4821552f7358SJed Brown ierr = PetscMemzero(offsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 48221b406b76SMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 48231b406b76SMatthew G. Knepley if (!clPoints) { 4824552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 4825552f7358SJed Brown /* Compress out points not in the section */ 4826552f7358SJed Brown ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 4827552f7358SJed Brown for (p = 0, q = 0; p < numPoints*2; p += 2) { 4828552f7358SJed Brown if ((points[p] >= pStart) && (points[p] < pEnd)) { 4829552f7358SJed Brown points[q*2] = points[p]; 4830552f7358SJed Brown points[q*2+1] = points[p+1]; 4831552f7358SJed Brown ++q; 4832552f7358SJed Brown } 4833552f7358SJed Brown } 4834552f7358SJed Brown numPoints = q; 48351b406b76SMatthew G. Knepley } else { 48361b406b76SMatthew G. Knepley PetscInt dof, off; 48371b406b76SMatthew G. Knepley 48381b406b76SMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 48391b406b76SMatthew G. Knepley numPoints = dof/2; 48401b406b76SMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 48411b406b76SMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 48421b406b76SMatthew G. Knepley points = (PetscInt *) &clp[off]; 48431b406b76SMatthew G. Knepley } 4844552f7358SJed Brown for (p = 0, numIndices = 0; p < numPoints*2; p += 2) { 4845552f7358SJed Brown PetscInt fdof; 4846552f7358SJed Brown 4847552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 4848552f7358SJed Brown for (f = 0; f < numFields; ++f) { 4849552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 4850552f7358SJed Brown offsets[f+1] += fdof; 4851552f7358SJed Brown } 4852552f7358SJed Brown numIndices += dof; 4853552f7358SJed Brown } 48540d644c17SKarl Rupp for (f = 1; f < numFields; ++f) offsets[f+1] += offsets[f]; 48550d644c17SKarl Rupp 485682f516ccSBarry Smith if (numFields && offsets[numFields] != numIndices) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", offsets[numFields], numIndices); 48576ecaa68aSToby Isaac ierr = DMPlexAnchorsModifyMat(dm,section,numPoints,numIndices,points,values,&newNumPoints,&newNumIndices,&newPoints,&newValues,offsets,PETSC_TRUE);CHKERRQ(ierr); 4858d3d1a6afSToby Isaac if (newNumPoints) { 4859d3d1a6afSToby Isaac if (!clPoints) { 4860d3d1a6afSToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 4861d3d1a6afSToby Isaac } else { 4862d3d1a6afSToby Isaac ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr); 4863d3d1a6afSToby Isaac } 4864d3d1a6afSToby Isaac numPoints = newNumPoints; 4865d3d1a6afSToby Isaac numIndices = newNumIndices; 4866d3d1a6afSToby Isaac points = newPoints; 4867d3d1a6afSToby Isaac values = newValues; 4868d3d1a6afSToby Isaac } 4869552f7358SJed Brown ierr = DMGetWorkArray(dm, numIndices, PETSC_INT, &indices);CHKERRQ(ierr); 4870552f7358SJed Brown if (numFields) { 4871552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 4872552f7358SJed Brown PetscInt o = points[p+1]; 4873552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, points[p], &globalOff);CHKERRQ(ierr); 4874415ce65aSMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(section, points[p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, o, indices); 4875552f7358SJed Brown } 4876552f7358SJed Brown } else { 4877e6ccafaeSMatthew G Knepley for (p = 0, off = 0; p < numPoints*2; p += 2) { 4878552f7358SJed Brown PetscInt o = points[p+1]; 4879552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, points[p], &globalOff);CHKERRQ(ierr); 4880415ce65aSMatthew G. Knepley DMPlexGetIndicesPoint_Internal(section, points[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, indices); 4881552f7358SJed Brown } 4882552f7358SJed Brown } 4883b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 4884552f7358SJed Brown ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 4885ab1d0545SMatthew G. Knepley if (mesh->printFEM > 1) { 4886ab1d0545SMatthew G. Knepley PetscInt i; 4887ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 4888ab1d0545SMatthew G. Knepley for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %d", indices[i]);CHKERRQ(ierr);} 4889ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 4890ab1d0545SMatthew G. Knepley } 4891552f7358SJed Brown if (ierr) { 4892552f7358SJed Brown PetscMPIInt rank; 4893552f7358SJed Brown PetscErrorCode ierr2; 4894552f7358SJed Brown 489582f516ccSBarry Smith ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 4896e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 4897b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 48986a415b8fSMatthew G Knepley ierr2 = DMRestoreWorkArray(dm, numIndices, PETSC_INT, &indices);CHKERRQ(ierr2); 4899552f7358SJed Brown CHKERRQ(ierr); 4900552f7358SJed Brown } 4901d3d1a6afSToby Isaac if (newNumPoints) { 4902d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,newNumIndices*newNumIndices,PETSC_SCALAR,&newValues);CHKERRQ(ierr); 4903d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,2*newNumPoints,PETSC_INT,&newPoints);CHKERRQ(ierr); 4904d3d1a6afSToby Isaac } 4905d3d1a6afSToby Isaac else { 49061b406b76SMatthew G. Knepley if (!clPoints) { 4907552f7358SJed Brown ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 49081b406b76SMatthew G. Knepley } else { 49091b406b76SMatthew G. Knepley ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr); 49101b406b76SMatthew G. Knepley } 4911d3d1a6afSToby Isaac } 4912552f7358SJed Brown ierr = DMRestoreWorkArray(dm, numIndices, PETSC_INT, &indices);CHKERRQ(ierr); 4913552f7358SJed Brown PetscFunctionReturn(0); 4914552f7358SJed Brown } 4915552f7358SJed Brown 4916552f7358SJed Brown #undef __FUNCT__ 4917de41b84cSMatthew G. Knepley #define __FUNCT__ "DMPlexMatSetClosureRefined" 4918de41b84cSMatthew G. Knepley PetscErrorCode DMPlexMatSetClosureRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 4919de41b84cSMatthew G. Knepley { 4920de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 4921de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 4922de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 4923de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 4924de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 4925de41b84cSMatthew G. Knepley CellRefiner cellRefiner; 49264ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 4927de41b84cSMatthew G. Knepley PetscErrorCode ierr; 4928de41b84cSMatthew G. Knepley 4929de41b84cSMatthew G. Knepley PetscFunctionBegin; 4930de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 4931de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 4932de41b84cSMatthew G. Knepley if (!fsection) {ierr = DMGetDefaultSection(dmf, &fsection);CHKERRQ(ierr);} 4933de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 4934de41b84cSMatthew G. Knepley if (!csection) {ierr = DMGetDefaultSection(dmc, &csection);CHKERRQ(ierr);} 4935de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 4936de41b84cSMatthew G. Knepley if (!globalFSection) {ierr = DMGetDefaultGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 4937de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 4938de41b84cSMatthew G. Knepley if (!globalCSection) {ierr = DMGetDefaultGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 4939de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 4940de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 4941de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 4942de41b84cSMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 4943de41b84cSMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 4944de41b84cSMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 4945de41b84cSMatthew G. Knepley /* Column indices */ 4946de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 49474ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 4948de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 4949de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 4950de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 4951de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 4952de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 4953de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 4954de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 4955de41b84cSMatthew G. Knepley ++q; 4956de41b84cSMatthew G. Knepley } 4957de41b84cSMatthew G. Knepley } 4958de41b84cSMatthew G. Knepley numCPoints = q; 4959de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 4960de41b84cSMatthew G. Knepley PetscInt fdof; 4961de41b84cSMatthew G. Knepley 4962de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 49634ca5e9f5SMatthew G. Knepley if (!dof) continue; 4964de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 4965de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 4966de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 4967de41b84cSMatthew G. Knepley } 4968de41b84cSMatthew G. Knepley numCIndices += dof; 4969de41b84cSMatthew G. Knepley } 4970de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 4971de41b84cSMatthew G. Knepley /* Row indices */ 4972de41b84cSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 4973de41b84cSMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 49741ba5f902SMatthew G. Knepley ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 4975de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 4976de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 4977de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 4978de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 4979de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 4980de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 4981de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 49824ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 49834ca5e9f5SMatthew G. Knepley if (!dof) continue; 49844ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 49854ca5e9f5SMatthew G. Knepley if (s < q) continue; 4986de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 4987de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 4988de41b84cSMatthew G. Knepley ++q; 4989de41b84cSMatthew G. Knepley } 4990de41b84cSMatthew G. Knepley } 4991de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 4992de41b84cSMatthew G. Knepley } 4993de41b84cSMatthew G. Knepley numFPoints = q; 4994de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 4995de41b84cSMatthew G. Knepley PetscInt fdof; 4996de41b84cSMatthew G. Knepley 4997de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 49984ca5e9f5SMatthew G. Knepley if (!dof) continue; 4999de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5000de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 5001de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 5002de41b84cSMatthew G. Knepley } 5003de41b84cSMatthew G. Knepley numFIndices += dof; 5004de41b84cSMatthew G. Knepley } 5005de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 5006de41b84cSMatthew G. Knepley 5007de41b84cSMatthew G. Knepley if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", foffsets[numFields], numFIndices); 5008de41b84cSMatthew G. Knepley if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", coffsets[numFields], numCIndices); 5009de41b84cSMatthew G. Knepley ierr = DMGetWorkArray(dmf, numFIndices, PETSC_INT, &findices);CHKERRQ(ierr); 5010de41b84cSMatthew G. Knepley ierr = DMGetWorkArray(dmc, numCIndices, PETSC_INT, &cindices);CHKERRQ(ierr); 5011de41b84cSMatthew G. Knepley if (numFields) { 5012de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 5013de41b84cSMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 5014de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 5015415ce65aSMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, o, findices); 5016de41b84cSMatthew G. Knepley } 5017de41b84cSMatthew G. Knepley for (p = 0; p < numCPoints*2; p += 2) { 5018de41b84cSMatthew G. Knepley PetscInt o = cpoints[p+1]; 5019de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 5020415ce65aSMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, o, cindices); 5021de41b84cSMatthew G. Knepley } 5022de41b84cSMatthew G. Knepley } else { 5023de41b84cSMatthew G. Knepley for (p = 0, off = 0; p < numFPoints*2; p += 2) { 5024de41b84cSMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 5025de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 5026415ce65aSMatthew G. Knepley DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, findices); 5027de41b84cSMatthew G. Knepley } 5028de41b84cSMatthew G. Knepley for (p = 0, off = 0; p < numCPoints*2; p += 2) { 5029de41b84cSMatthew G. Knepley PetscInt o = cpoints[p+1]; 5030de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 5031415ce65aSMatthew G. Knepley DMPlexGetIndicesPoint_Internal(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, cindices); 5032de41b84cSMatthew G. Knepley } 5033de41b84cSMatthew G. Knepley } 5034de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 5035de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 5036de41b84cSMatthew G. Knepley if (ierr) { 5037de41b84cSMatthew G. Knepley PetscMPIInt rank; 5038de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 5039de41b84cSMatthew G. Knepley 5040de41b84cSMatthew G. Knepley ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 5041e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 5042de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 5043de41b84cSMatthew G. Knepley ierr2 = DMRestoreWorkArray(dmf, numFIndices, PETSC_INT, &findices);CHKERRQ(ierr2); 5044de41b84cSMatthew G. Knepley ierr2 = DMRestoreWorkArray(dmc, numCIndices, PETSC_INT, &cindices);CHKERRQ(ierr2); 5045de41b84cSMatthew G. Knepley CHKERRQ(ierr); 5046de41b84cSMatthew G. Knepley } 5047549a8adaSMatthew G. Knepley ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 5048de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 5049de41b84cSMatthew G. Knepley ierr = DMRestoreWorkArray(dmf, numFIndices, PETSC_INT, &findices);CHKERRQ(ierr); 5050de41b84cSMatthew G. Knepley ierr = DMRestoreWorkArray(dmc, numCIndices, PETSC_INT, &cindices);CHKERRQ(ierr); 5051de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 5052de41b84cSMatthew G. Knepley } 5053de41b84cSMatthew G. Knepley 5054de41b84cSMatthew G. Knepley #undef __FUNCT__ 50557c927364SMatthew G. Knepley #define __FUNCT__ "DMPlexMatGetClosureIndicesRefined" 50567c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 50577c927364SMatthew G. Knepley { 50587c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 50597c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 50607c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 50617c927364SMatthew G. Knepley CellRefiner cellRefiner; 50627c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 50637c927364SMatthew G. Knepley PetscErrorCode ierr; 50647c927364SMatthew G. Knepley 50657c927364SMatthew G. Knepley PetscFunctionBegin; 50667c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 50677c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 50687c927364SMatthew G. Knepley if (!fsection) {ierr = DMGetDefaultSection(dmf, &fsection);CHKERRQ(ierr);} 50697c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 50707c927364SMatthew G. Knepley if (!csection) {ierr = DMGetDefaultSection(dmc, &csection);CHKERRQ(ierr);} 50717c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 50727c927364SMatthew G. Knepley if (!globalFSection) {ierr = DMGetDefaultGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 50737c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 50747c927364SMatthew G. Knepley if (!globalCSection) {ierr = DMGetDefaultGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 50757c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 50767c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 50777c927364SMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 50787c927364SMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 50797c927364SMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 50807c927364SMatthew G. Knepley /* Column indices */ 50817c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 50827c927364SMatthew G. Knepley maxFPoints = numCPoints; 50837c927364SMatthew G. Knepley /* Compress out points not in the section */ 50847c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 50857c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 50867c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 50877c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 50887c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 50897c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 50907c927364SMatthew G. Knepley ++q; 50917c927364SMatthew G. Knepley } 50927c927364SMatthew G. Knepley } 50937c927364SMatthew G. Knepley numCPoints = q; 50947c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 50957c927364SMatthew G. Knepley PetscInt fdof; 50967c927364SMatthew G. Knepley 50977c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 50987c927364SMatthew G. Knepley if (!dof) continue; 50997c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 51007c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 51017c927364SMatthew G. Knepley coffsets[f+1] += fdof; 51027c927364SMatthew G. Knepley } 51037c927364SMatthew G. Knepley numCIndices += dof; 51047c927364SMatthew G. Knepley } 51057c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 51067c927364SMatthew G. Knepley /* Row indices */ 51077c927364SMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 51087c927364SMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 51097c927364SMatthew G. Knepley ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 51107c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 51117c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 51127c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 51137c927364SMatthew G. Knepley /* Compress out points not in the section */ 51147c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 51157c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 51167c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 51177c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 51187c927364SMatthew G. Knepley if (!dof) continue; 51197c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 51207c927364SMatthew G. Knepley if (s < q) continue; 51217c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 51227c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 51237c927364SMatthew G. Knepley ++q; 51247c927364SMatthew G. Knepley } 51257c927364SMatthew G. Knepley } 51267c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 51277c927364SMatthew G. Knepley } 51287c927364SMatthew G. Knepley numFPoints = q; 51297c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 51307c927364SMatthew G. Knepley PetscInt fdof; 51317c927364SMatthew G. Knepley 51327c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 51337c927364SMatthew G. Knepley if (!dof) continue; 51347c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 51357c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 51367c927364SMatthew G. Knepley foffsets[f+1] += fdof; 51377c927364SMatthew G. Knepley } 51387c927364SMatthew G. Knepley numFIndices += dof; 51397c927364SMatthew G. Knepley } 51407c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 51417c927364SMatthew G. Knepley 51427c927364SMatthew G. Knepley if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", foffsets[numFields], numFIndices); 51437c927364SMatthew G. Knepley if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", coffsets[numFields], numCIndices); 51447c927364SMatthew G. Knepley if (numFields) { 51457c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 51467c927364SMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 51477c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 5148415ce65aSMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, o, findices); 51497c927364SMatthew G. Knepley } 51507c927364SMatthew G. Knepley for (p = 0; p < numCPoints*2; p += 2) { 51517c927364SMatthew G. Knepley PetscInt o = cpoints[p+1]; 51527c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 5153415ce65aSMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, o, cindices); 51547c927364SMatthew G. Knepley } 51557c927364SMatthew G. Knepley } else { 51567c927364SMatthew G. Knepley for (p = 0, off = 0; p < numFPoints*2; p += 2) { 51577c927364SMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 51587c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 5159415ce65aSMatthew G. Knepley DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, findices); 51607c927364SMatthew G. Knepley } 51617c927364SMatthew G. Knepley for (p = 0, off = 0; p < numCPoints*2; p += 2) { 51627c927364SMatthew G. Knepley PetscInt o = cpoints[p+1]; 51637c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 5164415ce65aSMatthew G. Knepley DMPlexGetIndicesPoint_Internal(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, cindices); 51657c927364SMatthew G. Knepley } 51667c927364SMatthew G. Knepley } 51677c927364SMatthew G. Knepley ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 51687c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 51697c927364SMatthew G. Knepley PetscFunctionReturn(0); 51707c927364SMatthew G. Knepley } 51717c927364SMatthew G. Knepley 51727c927364SMatthew G. Knepley #undef __FUNCT__ 5173770b213bSMatthew G Knepley #define __FUNCT__ "DMPlexGetHybridBounds" 5174f96281f8SMatthew G. Knepley /*@ 5175f96281f8SMatthew G. Knepley DMPlexGetHybridBounds - Get the first mesh point of each dimension which is a hybrid 5176f96281f8SMatthew G. Knepley 5177f96281f8SMatthew G. Knepley Input Parameter: 5178f96281f8SMatthew G. Knepley . dm - The DMPlex object 5179f96281f8SMatthew G. Knepley 5180f96281f8SMatthew G. Knepley Output Parameters: 5181f96281f8SMatthew G. Knepley + cMax - The first hybrid cell 5182dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 5183dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 5184dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 5185f96281f8SMatthew G. Knepley 5186f96281f8SMatthew G. Knepley Level: developer 5187f96281f8SMatthew G. Knepley 5188dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexSetHybridBounds() 5189f96281f8SMatthew G. Knepley @*/ 5190770b213bSMatthew G Knepley PetscErrorCode DMPlexGetHybridBounds(DM dm, PetscInt *cMax, PetscInt *fMax, PetscInt *eMax, PetscInt *vMax) 5191552f7358SJed Brown { 5192552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5193770b213bSMatthew G Knepley PetscInt dim; 5194770b213bSMatthew G Knepley PetscErrorCode ierr; 5195552f7358SJed Brown 5196552f7358SJed Brown PetscFunctionBegin; 5197552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5198c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5199770b213bSMatthew G Knepley if (cMax) *cMax = mesh->hybridPointMax[dim]; 5200770b213bSMatthew G Knepley if (fMax) *fMax = mesh->hybridPointMax[dim-1]; 5201770b213bSMatthew G Knepley if (eMax) *eMax = mesh->hybridPointMax[1]; 5202770b213bSMatthew G Knepley if (vMax) *vMax = mesh->hybridPointMax[0]; 5203552f7358SJed Brown PetscFunctionReturn(0); 5204552f7358SJed Brown } 5205552f7358SJed Brown 5206552f7358SJed Brown #undef __FUNCT__ 5207770b213bSMatthew G Knepley #define __FUNCT__ "DMPlexSetHybridBounds" 5208dc5a3409SMatthew G. Knepley /*@ 5209dc5a3409SMatthew G. Knepley DMPlexSetHybridBounds - Set the first mesh point of each dimension which is a hybrid 5210dc5a3409SMatthew G. Knepley 5211dc5a3409SMatthew G. Knepley Input Parameters: 5212dc5a3409SMatthew G. Knepley . dm - The DMPlex object 5213dc5a3409SMatthew G. Knepley . cMax - The first hybrid cell 5214dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 5215dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 5216dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 5217dc5a3409SMatthew G. Knepley 5218dc5a3409SMatthew G. Knepley Level: developer 5219dc5a3409SMatthew G. Knepley 5220dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexGetHybridBounds() 5221dc5a3409SMatthew G. Knepley @*/ 5222770b213bSMatthew G Knepley PetscErrorCode DMPlexSetHybridBounds(DM dm, PetscInt cMax, PetscInt fMax, PetscInt eMax, PetscInt vMax) 5223552f7358SJed Brown { 5224552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5225770b213bSMatthew G Knepley PetscInt dim; 5226770b213bSMatthew G Knepley PetscErrorCode ierr; 5227552f7358SJed Brown 5228552f7358SJed Brown PetscFunctionBegin; 5229552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5230c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5231770b213bSMatthew G Knepley if (cMax >= 0) mesh->hybridPointMax[dim] = cMax; 5232770b213bSMatthew G Knepley if (fMax >= 0) mesh->hybridPointMax[dim-1] = fMax; 5233770b213bSMatthew G Knepley if (eMax >= 0) mesh->hybridPointMax[1] = eMax; 5234770b213bSMatthew G Knepley if (vMax >= 0) mesh->hybridPointMax[0] = vMax; 5235552f7358SJed Brown PetscFunctionReturn(0); 5236552f7358SJed Brown } 5237552f7358SJed Brown 5238552f7358SJed Brown #undef __FUNCT__ 5239552f7358SJed Brown #define __FUNCT__ "DMPlexGetVTKCellHeight" 5240552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 5241552f7358SJed Brown { 5242552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5243552f7358SJed Brown 5244552f7358SJed Brown PetscFunctionBegin; 5245552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5246552f7358SJed Brown PetscValidPointer(cellHeight, 2); 5247552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 5248552f7358SJed Brown PetscFunctionReturn(0); 5249552f7358SJed Brown } 5250552f7358SJed Brown 5251552f7358SJed Brown #undef __FUNCT__ 5252552f7358SJed Brown #define __FUNCT__ "DMPlexSetVTKCellHeight" 5253552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 5254552f7358SJed Brown { 5255552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5256552f7358SJed Brown 5257552f7358SJed Brown PetscFunctionBegin; 5258552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5259552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 5260552f7358SJed Brown PetscFunctionReturn(0); 5261552f7358SJed Brown } 5262552f7358SJed Brown 5263552f7358SJed Brown #undef __FUNCT__ 5264552f7358SJed Brown #define __FUNCT__ "DMPlexCreateNumbering_Private" 5265552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 5266ef48cebcSMatthew G. Knepley static PetscErrorCode DMPlexCreateNumbering_Private(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 5267552f7358SJed Brown { 5268552f7358SJed Brown PetscSection section, globalSection; 5269552f7358SJed Brown PetscInt *numbers, p; 5270552f7358SJed Brown PetscErrorCode ierr; 5271552f7358SJed Brown 5272552f7358SJed Brown PetscFunctionBegin; 527382f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 5274552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 5275552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 5276552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 5277552f7358SJed Brown } 5278552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 527915b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 5280854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 5281552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 5282552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 5283ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 5284ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 5285552f7358SJed Brown } 528682f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 5287ef48cebcSMatthew G. Knepley if (globalSize) { 5288ef48cebcSMatthew G. Knepley PetscLayout layout; 5289ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 5290ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 5291ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 5292ef48cebcSMatthew G. Knepley } 5293552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 5294552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 5295552f7358SJed Brown PetscFunctionReturn(0); 5296552f7358SJed Brown } 5297552f7358SJed Brown 5298552f7358SJed Brown #undef __FUNCT__ 529981ed3555SMatthew G. Knepley #define __FUNCT__ "DMPlexCreateCellNumbering_Internal" 530081ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 5301552f7358SJed Brown { 5302552f7358SJed Brown PetscInt cellHeight, cStart, cEnd, cMax; 5303552f7358SJed Brown PetscErrorCode ierr; 5304552f7358SJed Brown 5305552f7358SJed Brown PetscFunctionBegin; 5306552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 5307552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 53080298fd71SBarry Smith ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 530981ed3555SMatthew G. Knepley if (cMax >= 0 && !includeHybrid) cEnd = PetscMin(cEnd, cMax); 531081ed3555SMatthew G. Knepley ierr = DMPlexCreateNumbering_Private(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 531181ed3555SMatthew G. Knepley PetscFunctionReturn(0); 5312552f7358SJed Brown } 531381ed3555SMatthew G. Knepley 531481ed3555SMatthew G. Knepley #undef __FUNCT__ 531581ed3555SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellNumbering" 531681ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 531781ed3555SMatthew G. Knepley { 531881ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 531981ed3555SMatthew G. Knepley PetscErrorCode ierr; 532081ed3555SMatthew G. Knepley 532181ed3555SMatthew G. Knepley PetscFunctionBegin; 532281ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 532381ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 5324552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 5325552f7358SJed Brown PetscFunctionReturn(0); 5326552f7358SJed Brown } 5327552f7358SJed Brown 5328552f7358SJed Brown #undef __FUNCT__ 532981ed3555SMatthew G. Knepley #define __FUNCT__ "DMPlexCreateVertexNumbering_Internal" 533081ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 533181ed3555SMatthew G. Knepley { 533281ed3555SMatthew G. Knepley PetscInt vStart, vEnd, vMax; 533381ed3555SMatthew G. Knepley PetscErrorCode ierr; 533481ed3555SMatthew G. Knepley 533581ed3555SMatthew G. Knepley PetscFunctionBegin; 533681ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 533781ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 533881ed3555SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); 533981ed3555SMatthew G. Knepley if (vMax >= 0 && !includeHybrid) vEnd = PetscMin(vEnd, vMax); 534081ed3555SMatthew G. Knepley ierr = DMPlexCreateNumbering_Private(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 534181ed3555SMatthew G. Knepley PetscFunctionReturn(0); 534281ed3555SMatthew G. Knepley } 534381ed3555SMatthew G. Knepley 534481ed3555SMatthew G. Knepley #undef __FUNCT__ 5345552f7358SJed Brown #define __FUNCT__ "DMPlexGetVertexNumbering" 5346552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 5347552f7358SJed Brown { 5348552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5349552f7358SJed Brown PetscErrorCode ierr; 5350552f7358SJed Brown 5351552f7358SJed Brown PetscFunctionBegin; 5352552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 535381ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 5354552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 5355552f7358SJed Brown PetscFunctionReturn(0); 5356552f7358SJed Brown } 5357552f7358SJed Brown 5358ef48cebcSMatthew G. Knepley #undef __FUNCT__ 5359ef48cebcSMatthew G. Knepley #define __FUNCT__ "DMPlexCreatePointNumbering" 5360ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 5361ef48cebcSMatthew G. Knepley { 5362ef48cebcSMatthew G. Knepley IS nums[4]; 5363ef48cebcSMatthew G. Knepley PetscInt depths[4]; 5364ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 5365ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 5366ef48cebcSMatthew G. Knepley 5367ef48cebcSMatthew G. Knepley PetscFunctionBegin; 5368ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5369ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 53708abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 53718abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 5372ef48cebcSMatthew G. Knepley depths[0] = depth; depths[1] = 0; 5373ef48cebcSMatthew G. Knepley for (d = 2; d <= depth; ++d) depths[d] = depth-d+1; 5374ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 5375ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 5376ef48cebcSMatthew G. Knepley 5377ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, depths[d], &pStart, &pEnd);CHKERRQ(ierr); 5378ef48cebcSMatthew G. Knepley ierr = DMPlexCreateNumbering_Private(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 5379ef48cebcSMatthew G. Knepley shift += gsize; 5380ef48cebcSMatthew G. Knepley } 5381302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 5382ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 5383ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 5384ef48cebcSMatthew G. Knepley } 5385ef48cebcSMatthew G. Knepley 5386ca8062c8SMatthew G. Knepley #undef __FUNCT__ 5387ca8062c8SMatthew G. Knepley #define __FUNCT__ "DMPlexCheckSymmetry" 5388ca8062c8SMatthew G. Knepley /*@ 5389ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 5390ca8062c8SMatthew G. Knepley 5391ca8062c8SMatthew G. Knepley Input Parameters: 5392ca8062c8SMatthew G. Knepley + dm - The DMPlex object 5393ca8062c8SMatthew G. Knepley 5394ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 5395ca8062c8SMatthew G. Knepley 5396ca8062c8SMatthew G. Knepley Level: developer 5397ca8062c8SMatthew G. Knepley 53989bf0dad6SMatthew G. Knepley .seealso: DMCreate(), DMCheckSkeleton(), DMCheckFaces() 5399ca8062c8SMatthew G. Knepley @*/ 5400ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 5401ca8062c8SMatthew G. Knepley { 5402ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 5403ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 5404ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 5405ca8062c8SMatthew G. Knepley PetscInt pStart, pEnd, p, csize, ssize; 5406ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 5407ca8062c8SMatthew G. Knepley 5408ca8062c8SMatthew G. Knepley PetscFunctionBegin; 5409ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5410ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 5411ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 5412ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 5413ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 5414ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 5415ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 5416ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 5417ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 541842e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 541942e66dfaSMatthew G. Knepley PetscInt d; 542042e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 542142e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 542242e66dfaSMatthew G. Knepley } 5423ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 5424ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 5425ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 5426ca8062c8SMatthew G. Knepley if (support[s] == p) break; 5427ca8062c8SMatthew G. Knepley } 542842e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 5429302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d cone: ", p);CHKERRQ(ierr); 5430ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 5431302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", cone[s]);CHKERRQ(ierr); 5432ca8062c8SMatthew G. Knepley } 5433302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 5434302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d support: ", cone[c]);CHKERRQ(ierr); 5435ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 5436302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", support[s]);CHKERRQ(ierr); 5437ca8062c8SMatthew G. Knepley } 5438302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 5439302440fdSBarry Smith if (dup) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d not repeatedly found in support of repeated cone point %d", p, cone[c]); 5440302440fdSBarry Smith else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d not found in support of cone point %d", p, cone[c]); 5441ca8062c8SMatthew G. Knepley } 544242e66dfaSMatthew G. Knepley } 5443ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 5444ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 5445ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 5446ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5447ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5448ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 5449ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 5450ca8062c8SMatthew G. Knepley } 5451ca8062c8SMatthew G. Knepley if (c >= coneSize) { 5452302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d support: ", p);CHKERRQ(ierr); 5453ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 5454302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", support[c]);CHKERRQ(ierr); 5455ca8062c8SMatthew G. Knepley } 5456302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 5457302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d cone: ", support[s]);CHKERRQ(ierr); 5458ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 5459302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", cone[c]);CHKERRQ(ierr); 5460ca8062c8SMatthew G. Knepley } 5461302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 5462ca8062c8SMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d not found in cone of support point %d", p, support[s]); 5463ca8062c8SMatthew G. Knepley } 5464ca8062c8SMatthew G. Knepley } 5465ca8062c8SMatthew G. Knepley } 5466ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 5467ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 5468ca8062c8SMatthew G. Knepley if (csize != ssize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %d != Total support size %d", csize, ssize); 5469ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 5470ca8062c8SMatthew G. Knepley } 5471ca8062c8SMatthew G. Knepley 5472ca8062c8SMatthew G. Knepley #undef __FUNCT__ 5473ca8062c8SMatthew G. Knepley #define __FUNCT__ "DMPlexCheckSkeleton" 5474ca8062c8SMatthew G. Knepley /*@ 5475ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 5476ca8062c8SMatthew G. Knepley 5477ca8062c8SMatthew G. Knepley Input Parameters: 5478ca8062c8SMatthew G. Knepley + dm - The DMPlex object 547958723a97SMatthew G. Knepley . isSimplex - Are the cells simplices or tensor products 548058723a97SMatthew G. Knepley - cellHeight - Normally 0 5481ca8062c8SMatthew G. Knepley 5482ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 5483ca8062c8SMatthew G. Knepley 5484ca8062c8SMatthew G. Knepley Level: developer 5485ca8062c8SMatthew G. Knepley 54869bf0dad6SMatthew G. Knepley .seealso: DMCreate(), DMCheckSymmetry(), DMCheckFaces() 5487ca8062c8SMatthew G. Knepley @*/ 548858723a97SMatthew G. Knepley PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscBool isSimplex, PetscInt cellHeight) 5489ca8062c8SMatthew G. Knepley { 549042363296SMatthew G. Knepley PetscInt dim, numCorners, numHybridCorners, vStart, vEnd, cStart, cEnd, cMax, c; 5491ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 5492ca8062c8SMatthew G. Knepley 5493ca8062c8SMatthew G. Knepley PetscFunctionBegin; 5494ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5495c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5496ca8062c8SMatthew G. Knepley switch (dim) { 549742363296SMatthew G. Knepley case 1: numCorners = isSimplex ? 2 : 2; numHybridCorners = isSimplex ? 2 : 2; break; 549842363296SMatthew G. Knepley case 2: numCorners = isSimplex ? 3 : 4; numHybridCorners = isSimplex ? 4 : 4; break; 549942363296SMatthew G. Knepley case 3: numCorners = isSimplex ? 4 : 8; numHybridCorners = isSimplex ? 6 : 8; break; 5500ca8062c8SMatthew G. Knepley default: 5501ca8062c8SMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle meshes of dimension %d", dim); 5502ca8062c8SMatthew G. Knepley } 550358723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 550458723a97SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 5505ca8062c8SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 5506ca8062c8SMatthew G. Knepley cMax = cMax >= 0 ? cMax : cEnd; 5507ca8062c8SMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 550858723a97SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 550958723a97SMatthew G. Knepley 551058723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 551158723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 551258723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 551358723a97SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 551458723a97SMatthew G. Knepley } 551558723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 5516ca8062c8SMatthew G. Knepley if (coneSize != numCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %d has %d vertices != %d", c, coneSize, numCorners); 5517ca8062c8SMatthew G. Knepley } 551842363296SMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 551942363296SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 552042363296SMatthew G. Knepley 552142363296SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 552242363296SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 552342363296SMatthew G. Knepley const PetscInt p = closure[cl]; 552442363296SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 552542363296SMatthew G. Knepley } 552642363296SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 552742363296SMatthew G. Knepley if (coneSize > numHybridCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Hybrid cell %d has %d vertices > %d", c, coneSize, numHybridCorners); 552842363296SMatthew G. Knepley } 5529ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 5530ca8062c8SMatthew G. Knepley } 55319bf0dad6SMatthew G. Knepley 55329bf0dad6SMatthew G. Knepley #undef __FUNCT__ 55339bf0dad6SMatthew G. Knepley #define __FUNCT__ "DMPlexCheckFaces" 55349bf0dad6SMatthew G. Knepley /*@ 55359bf0dad6SMatthew G. Knepley DMPlexCheckFaces - Check that the faces of each cell give a vertex order this is consistent with what we expect from the cell type 55369bf0dad6SMatthew G. Knepley 55379bf0dad6SMatthew G. Knepley Input Parameters: 55389bf0dad6SMatthew G. Knepley + dm - The DMPlex object 55399bf0dad6SMatthew G. Knepley . isSimplex - Are the cells simplices or tensor products 55409bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 55419bf0dad6SMatthew G. Knepley 55429bf0dad6SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 55439bf0dad6SMatthew G. Knepley 55449bf0dad6SMatthew G. Knepley Level: developer 55459bf0dad6SMatthew G. Knepley 55469bf0dad6SMatthew G. Knepley .seealso: DMCreate(), DMCheckSymmetry(), DMCheckSkeleton() 55479bf0dad6SMatthew G. Knepley @*/ 55489bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexCheckFaces(DM dm, PetscBool isSimplex, PetscInt cellHeight) 55499bf0dad6SMatthew G. Knepley { 55503554e41dSMatthew G. Knepley PetscInt pMax[4]; 55513554e41dSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, h; 55529bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 55539bf0dad6SMatthew G. Knepley 55549bf0dad6SMatthew G. Knepley PetscFunctionBegin; 55559bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5556c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 55579bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 555825abba81SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &pMax[dim], &pMax[dim-1], &pMax[1], &pMax[0]);CHKERRQ(ierr); 55593554e41dSMatthew G. Knepley for (h = cellHeight; h < dim; ++h) { 55603554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 55613554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 55629bf0dad6SMatthew G. Knepley const PetscInt *cone, *ornt, *faces; 55639bf0dad6SMatthew G. Knepley PetscInt numFaces, faceSize, coneSize,f; 55649bf0dad6SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0; 55659bf0dad6SMatthew G. Knepley 556625abba81SMatthew G. Knepley if (pMax[dim-h] >= 0 && c >= pMax[dim-h]) continue; 55679bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 55689bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 55699bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 55709bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 55719bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 55729bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 55739bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 55749bf0dad6SMatthew G. Knepley } 55753554e41dSMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, dim-h, numCorners, closure, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 55769bf0dad6SMatthew G. Knepley if (coneSize != numFaces) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %d has %d faces but should have %d", c, coneSize, numFaces); 55779bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 55789bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 55799bf0dad6SMatthew G. Knepley 55809bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 55819bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 55829bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 55839bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 55849bf0dad6SMatthew G. Knepley } 5585e003ed69SMatthew G. Knepley if (fnumCorners != faceSize) SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Face %d (%d) of cell %d has %d vertices but should have %d", cone[f], f, c, fnumCorners, faceSize); 55869bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 5587e003ed69SMatthew G. Knepley if (fclosure[v] != faces[f*faceSize+v]) SETERRQ6(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Face %d (%d) of cell %d vertex %d, %d != %d", cone[f], f, c, v, fclosure[v], faces[f*faceSize+v]); 55889bf0dad6SMatthew G. Knepley } 55899bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 55909bf0dad6SMatthew G. Knepley } 55919bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreFaces_Internal(dm, dim, c, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 55929bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 55939bf0dad6SMatthew G. Knepley } 55943554e41dSMatthew G. Knepley } 5595552f7358SJed Brown PetscFunctionReturn(0); 5596552f7358SJed Brown } 55973913d7c8SMatthew G. Knepley 55983913d7c8SMatthew G. Knepley #undef __FUNCT__ 5599bceba477SMatthew G. Knepley #define __FUNCT__ "DMCreateInterpolation_Plex" 5600bceba477SMatthew G. Knepley /* Pointwise interpolation 5601bceba477SMatthew G. Knepley Just code FEM for now 5602bceba477SMatthew G. Knepley u^f = I u^c 56034ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 56044ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 56054ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 5606bceba477SMatthew G. Knepley */ 5607bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 5608bceba477SMatthew G. Knepley { 5609bceba477SMatthew G. Knepley PetscSection gsc, gsf; 5610bceba477SMatthew G. Knepley PetscInt m, n; 5611a063dac3SMatthew G. Knepley void *ctx; 561268132eb9SMatthew G. Knepley DM cdm; 561368132eb9SMatthew G. Knepley PetscBool regular; 5614bceba477SMatthew G. Knepley PetscErrorCode ierr; 5615bceba477SMatthew G. Knepley 5616bceba477SMatthew G. Knepley PetscFunctionBegin; 5617bceba477SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 5618bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 5619bceba477SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 5620bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 562168132eb9SMatthew G. Knepley 5622bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 5623bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 5624bceba477SMatthew G. Knepley ierr = MatSetType(*interpolation, dmCoarse->mattype);CHKERRQ(ierr); 5625a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 562668132eb9SMatthew G. Knepley 5627a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 562868132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 562968132eb9SMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 563068132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 563168132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 56325d1c2e58SMatthew G. Knepley /* Use naive scaling */ 56335d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 5634a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 5635a063dac3SMatthew G. Knepley } 5636bceba477SMatthew G. Knepley 5637a063dac3SMatthew G. Knepley #undef __FUNCT__ 5638a063dac3SMatthew G. Knepley #define __FUNCT__ "DMCreateInjection_Plex" 56396dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 5640a063dac3SMatthew G. Knepley { 564190748bafSMatthew G. Knepley PetscErrorCode ierr; 56426dbf9973SLawrence Mitchell VecScatter ctx; 564390748bafSMatthew G. Knepley 5644a063dac3SMatthew G. Knepley PetscFunctionBegin; 56456dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 56466dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 56476dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 5648bceba477SMatthew G. Knepley PetscFunctionReturn(0); 5649bceba477SMatthew G. Knepley } 5650bceba477SMatthew G. Knepley 5651bceba477SMatthew G. Knepley #undef __FUNCT__ 5652fd59a867SMatthew G. Knepley #define __FUNCT__ "DMCreateDefaultSection_Plex" 5653fd59a867SMatthew G. Knepley PetscErrorCode DMCreateDefaultSection_Plex(DM dm) 5654fd59a867SMatthew G. Knepley { 5655fd59a867SMatthew G. Knepley PetscSection section; 5656ab1d0545SMatthew G. Knepley IS *bcPoints, *bcComps; 5657ebb3236fSMatthew G. Knepley PetscBool *isFE; 5658286d8613SMatthew G. Knepley PetscInt *bcFields, *numComp, *numDof; 5659ebb3236fSMatthew G. Knepley PetscInt depth, dim, numBd, numBC = 0, numFields, bd, bc = 0, f; 5660ebb3236fSMatthew G. Knepley PetscInt cStart, cEnd, cEndInterior; 5661fd59a867SMatthew G. Knepley PetscErrorCode ierr; 5662fd59a867SMatthew G. Knepley 5663fd59a867SMatthew G. Knepley PetscFunctionBegin; 5664ebb3236fSMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 5665ae71db08SMatthew G. Knepley if (!numFields) PetscFunctionReturn(0); 5666ebb3236fSMatthew G. Knepley /* FE and FV boundary conditions are handled slightly differently */ 5667ebb3236fSMatthew G. Knepley ierr = PetscMalloc1(numFields, &isFE);CHKERRQ(ierr); 5668ebb3236fSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5669ebb3236fSMatthew G. Knepley PetscObject obj; 5670ebb3236fSMatthew G. Knepley PetscClassId id; 5671ebb3236fSMatthew G. Knepley 5672ebb3236fSMatthew G. Knepley ierr = DMGetField(dm, f, &obj);CHKERRQ(ierr); 5673ebb3236fSMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 5674ebb3236fSMatthew G. Knepley if (id == PETSCFE_CLASSID) {isFE[f] = PETSC_TRUE;} 5675ebb3236fSMatthew G. Knepley else if (id == PETSCFV_CLASSID) {isFE[f] = PETSC_FALSE;} 5676ebb3236fSMatthew G. Knepley else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f); 5677ebb3236fSMatthew G. Knepley } 56782f900235SMatthew G. Knepley /* Allocate boundary point storage for FEM boundaries */ 5679286d8613SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5680c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5681ebb3236fSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5682ebb3236fSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cEndInterior, NULL, NULL, NULL);CHKERRQ(ierr); 5683a6ba4734SToby Isaac ierr = DMGetNumBoundary(dm, &numBd);CHKERRQ(ierr); 5684fd59a867SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 56852f900235SMatthew G. Knepley PetscInt field; 5686fd59a867SMatthew G. Knepley PetscBool isEssential; 56872f900235SMatthew G. Knepley 5688a6ba4734SToby Isaac ierr = DMGetBoundary(dm, bd, &isEssential, NULL, NULL, &field, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 56892f900235SMatthew G. Knepley if (isFE[field] && isEssential) ++numBC; 5690fd59a867SMatthew G. Knepley } 56912f900235SMatthew G. Knepley /* Add ghost cell boundaries for FVM */ 5692ebb3236fSMatthew G. Knepley for (f = 0; f < numFields; ++f) if (!isFE[f] && cEndInterior >= 0) ++numBC; 56936c8d74c4SMatthew G. Knepley ierr = PetscCalloc3(numBC,&bcFields,numBC,&bcPoints,numBC,&bcComps);CHKERRQ(ierr); 5694ebb3236fSMatthew G. Knepley /* Constrain ghost cells for FV */ 5695ebb3236fSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5696ebb3236fSMatthew G. Knepley PetscInt *newidx, c; 5697ebb3236fSMatthew G. Knepley 5698ebb3236fSMatthew G. Knepley if (isFE[f] || cEndInterior < 0) continue; 5699ebb3236fSMatthew G. Knepley ierr = PetscMalloc1(cEnd-cEndInterior,&newidx);CHKERRQ(ierr); 5700ebb3236fSMatthew G. Knepley for (c = cEndInterior; c < cEnd; ++c) newidx[c-cEndInterior] = c; 5701ebb3236fSMatthew G. Knepley bcFields[bc] = f; 5702ebb3236fSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), cEnd-cEndInterior, newidx, PETSC_OWN_POINTER, &bcPoints[bc++]);CHKERRQ(ierr); 5703ebb3236fSMatthew G. Knepley } 5704ebb3236fSMatthew G. Knepley /* Handle FEM Dirichlet boundaries */ 5705ebb3236fSMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5706fd59a867SMatthew G. Knepley const char *bdLabel; 5707fd59a867SMatthew G. Knepley DMLabel label; 57080e0f25f2SMatthew G. Knepley const PetscInt *comps; 5709fd59a867SMatthew G. Knepley const PetscInt *values; 57100e0f25f2SMatthew G. Knepley PetscInt bd2, field, numComps, numValues; 5711c945be8dSMatthew G. Knepley PetscBool isEssential, duplicate = PETSC_FALSE; 5712fd59a867SMatthew G. Knepley 5713a6ba4734SToby Isaac ierr = DMGetBoundary(dm, bd, &isEssential, NULL, &bdLabel, &field, &numComps, &comps, NULL, &numValues, &values, NULL);CHKERRQ(ierr); 57142f900235SMatthew G. Knepley if (!isFE[field]) continue; 5715c58f1c22SToby Isaac ierr = DMGetLabel(dm, bdLabel, &label);CHKERRQ(ierr); 5716ebb3236fSMatthew G. Knepley /* Only want to modify label once */ 57177391c1cbSMatthew G. Knepley for (bd2 = 0; bd2 < bd; ++bd2) { 57187391c1cbSMatthew G. Knepley const char *bdname; 5719a6ba4734SToby Isaac ierr = DMGetBoundary(dm, bd2, NULL, NULL, &bdname, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 57207391c1cbSMatthew G. Knepley ierr = PetscStrcmp(bdname, bdLabel, &duplicate);CHKERRQ(ierr); 57217391c1cbSMatthew G. Knepley if (duplicate) break; 57227391c1cbSMatthew G. Knepley } 5723ebb3236fSMatthew G. Knepley if (!duplicate && (isFE[field])) { 5724b0bf5782SToby Isaac /* don't complete cells, which are just present to give orientation to the boundary */ 5725092e5057SToby Isaac ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); 57267391c1cbSMatthew G. Knepley } 5727ebb3236fSMatthew G. Knepley /* Filter out cells, if you actually want to constrain cells you need to do things by hand right now */ 5728fd59a867SMatthew G. Knepley if (isEssential) { 572993a5981aSMatthew G. Knepley PetscInt *newidx; 5730ebb3236fSMatthew G. Knepley PetscInt n, newn = 0, p, v; 573193a5981aSMatthew G. Knepley 5732fd59a867SMatthew G. Knepley bcFields[bc] = field; 57330e0f25f2SMatthew G. Knepley if (numComps) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), numComps, comps, PETSC_COPY_VALUES, &bcComps[bc]);CHKERRQ(ierr);} 5734ebb3236fSMatthew G. Knepley for (v = 0; v < numValues; ++v) { 5735ebb3236fSMatthew G. Knepley IS tmp; 5736ebb3236fSMatthew G. Knepley const PetscInt *idx; 5737ebb3236fSMatthew G. Knepley 5738c58f1c22SToby Isaac ierr = DMGetStratumIS(dm, bdLabel, values[v], &tmp);CHKERRQ(ierr); 5739ebb3236fSMatthew G. Knepley if (!tmp) continue; 574093a5981aSMatthew G. Knepley ierr = ISGetLocalSize(tmp, &n);CHKERRQ(ierr); 574193a5981aSMatthew G. Knepley ierr = ISGetIndices(tmp, &idx);CHKERRQ(ierr); 5742ebb3236fSMatthew G. Knepley if (isFE[field]) { 574393a5981aSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] < cStart) || (idx[p] >= cEnd)) ++newn; 5744ebb3236fSMatthew G. Knepley } else { 5745ebb3236fSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] >= cStart) || (idx[p] < cEnd)) ++newn; 5746ebb3236fSMatthew G. Knepley } 574793a5981aSMatthew G. Knepley ierr = ISRestoreIndices(tmp, &idx);CHKERRQ(ierr); 574893a5981aSMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 5749fd59a867SMatthew G. Knepley } 5750ebb3236fSMatthew G. Knepley ierr = PetscMalloc1(newn,&newidx);CHKERRQ(ierr); 5751ebb3236fSMatthew G. Knepley newn = 0; 5752ebb3236fSMatthew G. Knepley for (v = 0; v < numValues; ++v) { 5753ebb3236fSMatthew G. Knepley IS tmp; 5754ebb3236fSMatthew G. Knepley const PetscInt *idx; 5755ebb3236fSMatthew G. Knepley 5756c58f1c22SToby Isaac ierr = DMGetStratumIS(dm, bdLabel, values[v], &tmp);CHKERRQ(ierr); 5757ebb3236fSMatthew G. Knepley if (!tmp) continue; 5758ebb3236fSMatthew G. Knepley ierr = ISGetLocalSize(tmp, &n);CHKERRQ(ierr); 5759ebb3236fSMatthew G. Knepley ierr = ISGetIndices(tmp, &idx);CHKERRQ(ierr); 5760ebb3236fSMatthew G. Knepley if (isFE[field]) { 5761ebb3236fSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] < cStart) || (idx[p] >= cEnd)) newidx[newn++] = idx[p]; 5762ebb3236fSMatthew G. Knepley } else { 5763ebb3236fSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] >= cStart) || (idx[p] < cEnd)) newidx[newn++] = idx[p]; 5764ebb3236fSMatthew G. Knepley } 5765ebb3236fSMatthew G. Knepley ierr = ISRestoreIndices(tmp, &idx);CHKERRQ(ierr); 5766ebb3236fSMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 5767ebb3236fSMatthew G. Knepley } 5768ebb3236fSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), newn, newidx, PETSC_OWN_POINTER, &bcPoints[bc++]);CHKERRQ(ierr); 5769ebb3236fSMatthew G. Knepley } 5770fd59a867SMatthew G. Knepley } 5771fd59a867SMatthew G. Knepley /* Handle discretization */ 5772ebb3236fSMatthew G. Knepley ierr = PetscCalloc2(numFields,&numComp,numFields*(dim+1),&numDof);CHKERRQ(ierr); 5773fd59a867SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 57740bacfa0aSMatthew G. Knepley PetscObject obj; 57750bacfa0aSMatthew G. Knepley 57760bacfa0aSMatthew G. Knepley ierr = DMGetField(dm, f, &obj);CHKERRQ(ierr); 5777ebb3236fSMatthew G. Knepley if (isFE[f]) { 57780bacfa0aSMatthew G. Knepley PetscFE fe = (PetscFE) obj; 5779286d8613SMatthew G. Knepley const PetscInt *numFieldDof; 5780fd59a867SMatthew G. Knepley PetscInt d; 5781fd59a867SMatthew G. Knepley 5782fd59a867SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &numComp[f]);CHKERRQ(ierr); 5783286d8613SMatthew G. Knepley ierr = PetscFEGetNumDof(fe, &numFieldDof);CHKERRQ(ierr); 5784286d8613SMatthew G. Knepley for (d = 0; d < dim+1; ++d) numDof[f*(dim+1)+d] = numFieldDof[d]; 5785ebb3236fSMatthew G. Knepley } else { 57860bacfa0aSMatthew G. Knepley PetscFV fv = (PetscFV) obj; 57870bacfa0aSMatthew G. Knepley 57880bacfa0aSMatthew G. Knepley ierr = PetscFVGetNumComponents(fv, &numComp[f]);CHKERRQ(ierr); 57890bacfa0aSMatthew G. Knepley numDof[f*(dim+1)+dim] = numComp[f]; 5790ebb3236fSMatthew G. Knepley } 5791fd59a867SMatthew G. Knepley } 5792286d8613SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5793286d8613SMatthew G. Knepley PetscInt d; 5794286d8613SMatthew G. Knepley for (d = 1; d < dim; ++d) { 5795286d8613SMatthew G. Knepley if ((numDof[f*(dim+1)+d] > 0) && (depth < dim)) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated when unknowns are specified on edges or faces."); 5796286d8613SMatthew G. Knepley } 5797286d8613SMatthew G. Knepley } 5798ab1d0545SMatthew G. Knepley ierr = DMPlexCreateSection(dm, dim, numFields, numComp, numDof, numBC, bcFields, bcComps, bcPoints, NULL, §ion);CHKERRQ(ierr); 5799fd59a867SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5800fd59a867SMatthew G. Knepley PetscFE fe; 5801fd59a867SMatthew G. Knepley const char *name; 580218abd763SMatthew G. Knepley 580318abd763SMatthew G. Knepley ierr = DMGetField(dm, f, (PetscObject *) &fe);CHKERRQ(ierr); 5804fd59a867SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) fe, &name);CHKERRQ(ierr); 5805fd59a867SMatthew G. Knepley ierr = PetscSectionSetFieldName(section, f, name);CHKERRQ(ierr); 5806fd59a867SMatthew G. Knepley } 5807fd59a867SMatthew G. Knepley ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); 5808fd59a867SMatthew G. Knepley ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 58090e0f25f2SMatthew G. Knepley for (bc = 0; bc < numBC; ++bc) {ierr = ISDestroy(&bcPoints[bc]);CHKERRQ(ierr);ierr = ISDestroy(&bcComps[bc]);CHKERRQ(ierr);} 58100e0f25f2SMatthew G. Knepley ierr = PetscFree3(bcFields,bcPoints,bcComps);CHKERRQ(ierr); 5811286d8613SMatthew G. Knepley ierr = PetscFree2(numComp,numDof);CHKERRQ(ierr); 5812ebb3236fSMatthew G. Knepley ierr = PetscFree(isFE);CHKERRQ(ierr); 5813bceba477SMatthew G. Knepley PetscFunctionReturn(0); 5814bceba477SMatthew G. Knepley } 5815bceba477SMatthew G. Knepley 5816bceba477SMatthew G. Knepley #undef __FUNCT__ 58170aef6b92SMatthew G. Knepley #define __FUNCT__ "DMPlexGetRegularRefinement" 58180aef6b92SMatthew G. Knepley /*@ 58190aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 58200aef6b92SMatthew G. Knepley 58210aef6b92SMatthew G. Knepley Input Parameter: 58220aef6b92SMatthew G. Knepley . dm - The DMPlex object 58230aef6b92SMatthew G. Knepley 58240aef6b92SMatthew G. Knepley Output Parameter: 58250aef6b92SMatthew G. Knepley . regular - The flag 58260aef6b92SMatthew G. Knepley 58270aef6b92SMatthew G. Knepley Level: intermediate 58280aef6b92SMatthew G. Knepley 58290aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 58300aef6b92SMatthew G. Knepley @*/ 58310aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 58320aef6b92SMatthew G. Knepley { 58330aef6b92SMatthew G. Knepley PetscFunctionBegin; 58340aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58350aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 58360aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 58370aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 58380aef6b92SMatthew G. Knepley } 58390aef6b92SMatthew G. Knepley 58400aef6b92SMatthew G. Knepley #undef __FUNCT__ 58410aef6b92SMatthew G. Knepley #define __FUNCT__ "DMPlexSetRegularRefinement" 58420aef6b92SMatthew G. Knepley /*@ 58430aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 58440aef6b92SMatthew G. Knepley 58450aef6b92SMatthew G. Knepley Input Parameters: 58460aef6b92SMatthew G. Knepley + dm - The DMPlex object 58470aef6b92SMatthew G. Knepley - regular - The flag 58480aef6b92SMatthew G. Knepley 58490aef6b92SMatthew G. Knepley Level: intermediate 58500aef6b92SMatthew G. Knepley 58510aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 58520aef6b92SMatthew G. Knepley @*/ 58530aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 58540aef6b92SMatthew G. Knepley { 58550aef6b92SMatthew G. Knepley PetscFunctionBegin; 58560aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58570aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 58580aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 58590aef6b92SMatthew G. Knepley } 58600aef6b92SMatthew G. Knepley 5861f7c74593SToby Isaac /* anchors */ 5862a68b90caSToby Isaac #undef __FUNCT__ 5863a17985deSToby Isaac #define __FUNCT__ "DMPlexGetAnchors" 5864a68b90caSToby Isaac /*@ 5865f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 5866f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 5867a68b90caSToby Isaac 5868e228b242SToby Isaac not collective 5869a68b90caSToby Isaac 5870a68b90caSToby Isaac Input Parameters: 5871a68b90caSToby Isaac . dm - The DMPlex object 5872a68b90caSToby Isaac 5873a68b90caSToby Isaac Output Parameters: 5874a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 5875a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 5876a68b90caSToby Isaac 5877a68b90caSToby Isaac 5878a68b90caSToby Isaac Level: intermediate 5879a68b90caSToby Isaac 5880f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 5881a68b90caSToby Isaac @*/ 5882a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 5883a68b90caSToby Isaac { 5884a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 588541e6d900SToby Isaac PetscErrorCode ierr; 5886a68b90caSToby Isaac 5887a68b90caSToby Isaac PetscFunctionBegin; 5888a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 588941e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 5890a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 5891a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 5892a68b90caSToby Isaac PetscFunctionReturn(0); 5893a68b90caSToby Isaac } 5894a68b90caSToby Isaac 5895a68b90caSToby Isaac #undef __FUNCT__ 5896a17985deSToby Isaac #define __FUNCT__ "DMPlexSetAnchors" 5897a68b90caSToby Isaac /*@ 5898f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 5899f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 5900a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 5901a68b90caSToby Isaac 5902a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 5903f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 5904a68b90caSToby Isaac 5905e228b242SToby Isaac collective on dm 5906a68b90caSToby Isaac 5907a68b90caSToby Isaac Input Parameters: 5908a68b90caSToby Isaac + dm - The DMPlex object 5909e228b242SToby Isaac . anchorSection - The section that describes the mapping from constrained points to the anchor points listed in anchorIS. Must have a local communicator (PETSC_COMM_SELF or derivative). 5910e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 5911a68b90caSToby Isaac 5912a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 5913a68b90caSToby Isaac 5914a68b90caSToby Isaac Level: intermediate 5915a68b90caSToby Isaac 5916f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 5917a68b90caSToby Isaac @*/ 5918a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 5919a68b90caSToby Isaac { 5920a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 5921e228b242SToby Isaac PetscMPIInt result; 5922a68b90caSToby Isaac PetscErrorCode ierr; 5923a68b90caSToby Isaac 5924a68b90caSToby Isaac PetscFunctionBegin; 5925a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5926e228b242SToby Isaac if (anchorSection) { 5927e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 5928e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRQ(ierr); 5929e228b242SToby Isaac if (result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 5930e228b242SToby Isaac } 5931e228b242SToby Isaac if (anchorIS) { 5932e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 5933e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRQ(ierr); 5934e228b242SToby Isaac if (result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 5935e228b242SToby Isaac } 5936a68b90caSToby Isaac 5937a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 5938a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 5939a68b90caSToby Isaac plex->anchorSection = anchorSection; 5940a68b90caSToby Isaac 5941a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 5942a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 5943a68b90caSToby Isaac plex->anchorIS = anchorIS; 5944a68b90caSToby Isaac 5945a68b90caSToby Isaac #if defined(PETSC_USE_DEBUG) 5946a68b90caSToby Isaac if (anchorIS && anchorSection) { 5947a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 5948a68b90caSToby Isaac const PetscInt *anchors; 5949a68b90caSToby Isaac 5950a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 5951a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 5952a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 5953a68b90caSToby Isaac for (a = 0; a < size; a++) { 5954a68b90caSToby Isaac PetscInt p; 5955a68b90caSToby Isaac 5956a68b90caSToby Isaac p = anchors[a]; 5957a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 5958a68b90caSToby Isaac PetscInt dof; 5959a68b90caSToby Isaac 5960a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 5961a68b90caSToby Isaac if (dof) { 5962a68b90caSToby Isaac PetscErrorCode ierr2; 5963a68b90caSToby Isaac 5964a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 5965a68b90caSToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %d cannot be constrained and an anchor",p); 5966a68b90caSToby Isaac } 5967a68b90caSToby Isaac } 5968a68b90caSToby Isaac } 5969a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 5970a68b90caSToby Isaac } 5971a68b90caSToby Isaac #endif 5972f7c74593SToby Isaac /* reset the generic constraints */ 5973f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 5974a68b90caSToby Isaac PetscFunctionReturn(0); 5975a68b90caSToby Isaac } 5976a68b90caSToby Isaac 5977a68b90caSToby Isaac #undef __FUNCT__ 5978f7c74593SToby Isaac #define __FUNCT__ "DMPlexCreateConstraintSection_Anchors" 5979f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 5980a68b90caSToby Isaac { 5981f7c74593SToby Isaac PetscSection anchorSection; 59826995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 5983a68b90caSToby Isaac PetscErrorCode ierr; 5984a68b90caSToby Isaac 5985a68b90caSToby Isaac PetscFunctionBegin; 5986a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5987a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 5988e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 5989a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 59906995de1eSToby Isaac if (numFields) { 5991719ab38cSToby Isaac PetscInt f; 5992a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 5993719ab38cSToby Isaac 5994719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 5995719ab38cSToby Isaac PetscInt numComp; 5996719ab38cSToby Isaac 5997719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 5998719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 5999719ab38cSToby Isaac } 60006995de1eSToby Isaac } 6001a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 60026995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 60036995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 60046995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 60056995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 6006a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 6007a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 6008a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 6009a68b90caSToby Isaac if (dof) { 6010a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 6011a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 6012a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 6013a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 6014a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 6015a68b90caSToby Isaac } 6016a68b90caSToby Isaac } 6017a68b90caSToby Isaac } 6018a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 6019a68b90caSToby Isaac PetscFunctionReturn(0); 6020a68b90caSToby Isaac } 6021a68b90caSToby Isaac 6022a68b90caSToby Isaac #undef __FUNCT__ 6023f7c74593SToby Isaac #define __FUNCT__ "DMPlexCreateConstraintMatrix_Anchors" 6024f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 6025a68b90caSToby Isaac { 6026f7c74593SToby Isaac PetscSection aSec; 60270ac89760SToby Isaac PetscInt pStart, pEnd, p, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 60280ac89760SToby Isaac const PetscInt *anchors; 60290ac89760SToby Isaac PetscInt numFields, f; 603066ad2231SToby Isaac IS aIS; 60310ac89760SToby Isaac PetscErrorCode ierr; 60320ac89760SToby Isaac 60330ac89760SToby Isaac PetscFunctionBegin; 60340ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 60350ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 60360ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 60370ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 60380ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 6039302440fdSBarry Smith ierr = MatSetType(*cMat,MATSEQAIJ);CHKERRQ(ierr); 6040a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 604166ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 60426995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 60436995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 60440ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 60450ac89760SToby Isaac i[0] = 0; 60460ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 60470ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 6048f19733c5SToby Isaac PetscInt rDof, rOff, r; 6049f19733c5SToby Isaac 6050f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 6051f19733c5SToby Isaac if (!rDof) continue; 6052f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 60530ac89760SToby Isaac if (numFields) { 60540ac89760SToby Isaac for (f = 0; f < numFields; f++) { 60550ac89760SToby Isaac annz = 0; 6056f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 6057f19733c5SToby Isaac a = anchors[rOff + r]; 60580ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 60590ac89760SToby Isaac annz += aDof; 60600ac89760SToby Isaac } 60610ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 60620ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 60630ac89760SToby Isaac for (q = 0; q < dof; q++) { 60640ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 60650ac89760SToby Isaac } 60660ac89760SToby Isaac } 60670ac89760SToby Isaac } 60680ac89760SToby Isaac else { 60690ac89760SToby Isaac annz = 0; 60700ac89760SToby Isaac for (q = 0; q < dof; q++) { 60710ac89760SToby Isaac a = anchors[off + q]; 60720ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 60730ac89760SToby Isaac annz += aDof; 60740ac89760SToby Isaac } 60750ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 60760ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 60770ac89760SToby Isaac for (q = 0; q < dof; q++) { 60780ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 60790ac89760SToby Isaac } 60800ac89760SToby Isaac } 60810ac89760SToby Isaac } 60820ac89760SToby Isaac nnz = i[m]; 60830ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 60840ac89760SToby Isaac offset = 0; 60850ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 60860ac89760SToby Isaac if (numFields) { 60870ac89760SToby Isaac for (f = 0; f < numFields; f++) { 60880ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 60890ac89760SToby Isaac for (q = 0; q < dof; q++) { 60900ac89760SToby Isaac PetscInt rDof, rOff, r; 60910ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 60920ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 60930ac89760SToby Isaac for (r = 0; r < rDof; r++) { 60940ac89760SToby Isaac PetscInt s; 60950ac89760SToby Isaac 60960ac89760SToby Isaac a = anchors[rOff + r]; 60970ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 60980ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 60990ac89760SToby Isaac for (s = 0; s < aDof; s++) { 61000ac89760SToby Isaac j[offset++] = aOff + s; 61010ac89760SToby Isaac } 61020ac89760SToby Isaac } 61030ac89760SToby Isaac } 61040ac89760SToby Isaac } 61050ac89760SToby Isaac } 61060ac89760SToby Isaac else { 61070ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 61080ac89760SToby Isaac for (q = 0; q < dof; q++) { 61090ac89760SToby Isaac PetscInt rDof, rOff, r; 61100ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 61110ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 61120ac89760SToby Isaac for (r = 0; r < rDof; r++) { 61130ac89760SToby Isaac PetscInt s; 61140ac89760SToby Isaac 61150ac89760SToby Isaac a = anchors[rOff + r]; 61160ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 61170ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 61180ac89760SToby Isaac for (s = 0; s < aDof; s++) { 61190ac89760SToby Isaac j[offset++] = aOff + s; 61200ac89760SToby Isaac } 61210ac89760SToby Isaac } 61220ac89760SToby Isaac } 61230ac89760SToby Isaac } 61240ac89760SToby Isaac } 61250ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 612625570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 612725570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 612866ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 61290ac89760SToby Isaac PetscFunctionReturn(0); 61300ac89760SToby Isaac } 61310ac89760SToby Isaac 61320ac89760SToby Isaac #undef __FUNCT__ 613366ad2231SToby Isaac #define __FUNCT__ "DMCreateDefaultConstraints_Plex" 613466ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 613566ad2231SToby Isaac { 6136f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 6137f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 613866ad2231SToby Isaac Mat cMat; 613966ad2231SToby Isaac PetscErrorCode ierr; 614066ad2231SToby Isaac 614166ad2231SToby Isaac PetscFunctionBegin; 614266ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6143a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 614466ad2231SToby Isaac if (anchorSection) { 6145e228b242SToby Isaac PetscDS ds; 6146e228b242SToby Isaac PetscInt nf; 6147e228b242SToby Isaac 6148f7c74593SToby Isaac ierr = DMGetDefaultSection(dm,§ion);CHKERRQ(ierr); 6149f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 6150f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 6151e228b242SToby Isaac ierr = DMGetDS(dm,&ds);CHKERRQ(ierr); 6152302440fdSBarry Smith ierr = PetscDSGetNumFields(ds,&nf);CHKERRQ(ierr); 6153e228b242SToby Isaac if (nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 615466ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 615566ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 615666ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 615766ad2231SToby Isaac } 615866ad2231SToby Isaac PetscFunctionReturn(0); 615966ad2231SToby Isaac } 6160