134541f0dSBarry Smith #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2d53a3d6fSBarry Smith #include <petsc-private/isimpl.h> 30c312b8eSJed Brown #include <petscsf.h> 4e228b242SToby Isaac #include <petscds.h> 5552f7358SJed Brown 6552f7358SJed Brown /* Logging support */ 73d822a50SMichael Lange PetscLogEvent DMPLEX_Interpolate, PETSCPARTITIONER_Partition, DMPLEX_Distribute, DMPLEX_DistributeCones, DMPLEX_DistributeLabels, DMPLEX_DistributeSF, DMPLEX_DistributeOverlap, DMPLEX_DistributeField, DMPLEX_DistributeData, DMPLEX_Stratify, DMPLEX_Preallocate, DMPLEX_ResidualFEM, DMPLEX_JacobianFEM, DMPLEX_InterpolatorFEM, DMPLEX_InjectorFEM; 8552f7358SJed Brown 95a576424SJed Brown PETSC_EXTERN PetscErrorCode VecView_Seq(Vec, PetscViewer); 105a576424SJed Brown PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 112c40f234SMatthew G. Knepley PETSC_EXTERN PetscErrorCode VecLoad_Default(Vec, PetscViewer); 12552f7358SJed Brown 137e42fee7SMatthew G. Knepley #undef __FUNCT__ 147afe7537SMatthew G. Knepley #define __FUNCT__ "DMPlexGetFieldType_Internal" 157afe7537SMatthew G. Knepley PetscErrorCode DMPlexGetFieldType_Internal(DM dm, PetscSection section, PetscInt field, PetscInt *sStart, PetscInt *sEnd, PetscViewerVTKFieldType *ft) 167e42fee7SMatthew G. Knepley { 177e42fee7SMatthew G. Knepley PetscInt dim, pStart, pEnd, vStart, vEnd, cStart, cEnd, vdof = 0, cdof = 0; 187e42fee7SMatthew G. Knepley PetscErrorCode ierr; 197e42fee7SMatthew G. Knepley 207e42fee7SMatthew G. Knepley PetscFunctionBegin; 217e42fee7SMatthew G. Knepley *ft = PETSC_VTK_POINT_FIELD; 22c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 237e42fee7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 247e42fee7SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 257e42fee7SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 267e42fee7SMatthew G. Knepley if (field >= 0) { 277e42fee7SMatthew G. Knepley if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, vStart, field, &vdof);CHKERRQ(ierr);} 287e42fee7SMatthew G. Knepley if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, cStart, field, &cdof);CHKERRQ(ierr);} 297e42fee7SMatthew G. Knepley } else { 307e42fee7SMatthew G. Knepley if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetDof(section, vStart, &vdof);CHKERRQ(ierr);} 317e42fee7SMatthew G. Knepley if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetDof(section, cStart, &cdof);CHKERRQ(ierr);} 327e42fee7SMatthew G. Knepley } 337e42fee7SMatthew G. Knepley if (vdof) { 347e42fee7SMatthew G. Knepley *sStart = vStart; 357e42fee7SMatthew G. Knepley *sEnd = vEnd; 367e42fee7SMatthew G. Knepley if (vdof == dim) *ft = PETSC_VTK_POINT_VECTOR_FIELD; 377e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_POINT_FIELD; 387e42fee7SMatthew G. Knepley } else if (cdof) { 397e42fee7SMatthew G. Knepley *sStart = cStart; 407e42fee7SMatthew G. Knepley *sEnd = cEnd; 417e42fee7SMatthew G. Knepley if (cdof == dim) *ft = PETSC_VTK_CELL_VECTOR_FIELD; 427e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_CELL_FIELD; 437e42fee7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Could not classify input Vec for VTK"); 447e42fee7SMatthew G. Knepley PetscFunctionReturn(0); 457e42fee7SMatthew G. Knepley } 467e42fee7SMatthew G. Knepley 47552f7358SJed Brown #undef __FUNCT__ 48552f7358SJed Brown #define __FUNCT__ "VecView_Plex_Local" 49552f7358SJed Brown PetscErrorCode VecView_Plex_Local(Vec v, PetscViewer viewer) 50552f7358SJed Brown { 51552f7358SJed Brown DM dm; 52b136c2c9SMatthew G. Knepley PetscBool isvtk, ishdf5, isseq; 53552f7358SJed Brown PetscErrorCode ierr; 54552f7358SJed Brown 55552f7358SJed Brown PetscFunctionBegin; 56552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 5782f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 58552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 59b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 60b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 61ef31f671SMatthew G. Knepley if (isvtk || ishdf5) { 62ef31f671SMatthew G. Knepley PetscInt numFields; 63ef31f671SMatthew G. Knepley PetscBool fem = PETSC_FALSE; 64ef31f671SMatthew G. Knepley 65ef31f671SMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 66ef31f671SMatthew G. Knepley if (numFields) { 67ef31f671SMatthew G. Knepley PetscObject fe; 68ef31f671SMatthew G. Knepley 69ef31f671SMatthew G. Knepley ierr = DMGetField(dm, 0, &fe);CHKERRQ(ierr); 70ef31f671SMatthew G. Knepley if (fe->classid == PETSCFE_CLASSID) fem = PETSC_TRUE; 71ef31f671SMatthew G. Knepley } 72d7ddef95SMatthew G. Knepley if (fem) {ierr = DMPlexInsertBoundaryValues(dm, v, 0.0, NULL, NULL, NULL);CHKERRQ(ierr);} 73ef31f671SMatthew G. Knepley } 74552f7358SJed Brown if (isvtk) { 75552f7358SJed Brown PetscSection section; 76b136c2c9SMatthew G. Knepley PetscViewerVTKFieldType ft; 77b136c2c9SMatthew G. Knepley PetscInt pStart, pEnd; 78552f7358SJed Brown 79552f7358SJed Brown ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 807afe7537SMatthew G. Knepley ierr = DMPlexGetFieldType_Internal(dm, section, PETSC_DETERMINE, &pStart, &pEnd, &ft);CHKERRQ(ierr); 81552f7358SJed Brown ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); /* viewer drops reference */ 82552f7358SJed Brown ierr = PetscObjectReference((PetscObject) v);CHKERRQ(ierr); /* viewer drops reference */ 83552f7358SJed Brown ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, ft, (PetscObject) v);CHKERRQ(ierr); 84b136c2c9SMatthew G. Knepley } else if (ishdf5) { 85b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 86b136c2c9SMatthew G. Knepley ierr = VecView_Plex_Local_HDF5(v, viewer);CHKERRQ(ierr); 87b136c2c9SMatthew G. Knepley #else 88b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 89b136c2c9SMatthew G. Knepley #endif 90552f7358SJed Brown } else { 9155f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 9255f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 93552f7358SJed Brown } 94552f7358SJed Brown PetscFunctionReturn(0); 95552f7358SJed Brown } 96552f7358SJed Brown 97552f7358SJed Brown #undef __FUNCT__ 98552f7358SJed Brown #define __FUNCT__ "VecView_Plex" 99552f7358SJed Brown PetscErrorCode VecView_Plex(Vec v, PetscViewer viewer) 100552f7358SJed Brown { 101552f7358SJed Brown DM dm; 10255f2e967SMatthew G. Knepley PetscBool isvtk, ishdf5, isseq; 103552f7358SJed Brown PetscErrorCode ierr; 104552f7358SJed Brown 105552f7358SJed Brown PetscFunctionBegin; 106552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 10782f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 108552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 10933c3e6b4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 11055f2e967SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 111552f7358SJed Brown if (isvtk) { 112552f7358SJed Brown Vec locv; 113552f7358SJed Brown const char *name; 114552f7358SJed Brown 115552f7358SJed Brown ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 116552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 117552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 118552f7358SJed Brown ierr = DMGlobalToLocalBegin(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 119552f7358SJed Brown ierr = DMGlobalToLocalEnd(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 120552f7358SJed Brown ierr = VecView_Plex_Local(locv, viewer);CHKERRQ(ierr); 121552f7358SJed Brown ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 122b136c2c9SMatthew G. Knepley } else if (ishdf5) { 123b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 124b136c2c9SMatthew G. Knepley ierr = VecView_Plex_HDF5(v, viewer);CHKERRQ(ierr); 125b136c2c9SMatthew G. Knepley #else 126b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 127b136c2c9SMatthew G. Knepley #endif 128552f7358SJed Brown } else { 12955f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 13055f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 131552f7358SJed Brown } 132552f7358SJed Brown PetscFunctionReturn(0); 133552f7358SJed Brown } 134552f7358SJed Brown 135552f7358SJed Brown #undef __FUNCT__ 1362c40f234SMatthew G. Knepley #define __FUNCT__ "VecLoad_Plex_Local" 1372c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Local(Vec v, PetscViewer viewer) 1382c40f234SMatthew G. Knepley { 1392c40f234SMatthew G. Knepley DM dm; 1402c40f234SMatthew G. Knepley PetscBool ishdf5; 1412c40f234SMatthew G. Knepley PetscErrorCode ierr; 1422c40f234SMatthew G. Knepley 1432c40f234SMatthew G. Knepley PetscFunctionBegin; 1442c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 1452c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 1462c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1472c40f234SMatthew G. Knepley if (ishdf5) { 1482c40f234SMatthew G. Knepley DM dmBC; 1492c40f234SMatthew G. Knepley Vec gv; 1502c40f234SMatthew G. Knepley const char *name; 1512c40f234SMatthew G. Knepley 1522c40f234SMatthew G. Knepley ierr = DMGetOutputDM(dm, &dmBC);CHKERRQ(ierr); 1532c40f234SMatthew G. Knepley ierr = DMGetGlobalVector(dmBC, &gv);CHKERRQ(ierr); 1542c40f234SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 1552c40f234SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) gv, name);CHKERRQ(ierr); 1562c40f234SMatthew G. Knepley ierr = VecLoad_Default(gv, viewer);CHKERRQ(ierr); 1572c40f234SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 1582c40f234SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 1592c40f234SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmBC, &gv);CHKERRQ(ierr); 1602c40f234SMatthew G. Knepley } else { 1612c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 1622c40f234SMatthew G. Knepley } 1632c40f234SMatthew G. Knepley PetscFunctionReturn(0); 1642c40f234SMatthew G. Knepley } 1652c40f234SMatthew G. Knepley 1662c40f234SMatthew G. Knepley #undef __FUNCT__ 1672c40f234SMatthew G. Knepley #define __FUNCT__ "VecLoad_Plex" 1682c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex(Vec v, PetscViewer viewer) 1692c40f234SMatthew G. Knepley { 1702c40f234SMatthew G. Knepley DM dm; 1712c40f234SMatthew G. Knepley PetscBool ishdf5; 1722c40f234SMatthew G. Knepley PetscErrorCode ierr; 1732c40f234SMatthew G. Knepley 1742c40f234SMatthew G. Knepley PetscFunctionBegin; 1752c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 1762c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 1772c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1782c40f234SMatthew G. Knepley if (ishdf5) { 179878b459fSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 180b136c2c9SMatthew G. Knepley ierr = VecLoad_Plex_HDF5(v, viewer);CHKERRQ(ierr); 181b136c2c9SMatthew G. Knepley #else 182b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 183878b459fSMatthew G. Knepley #endif 1842c40f234SMatthew G. Knepley } else { 1852c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 186552f7358SJed Brown } 187552f7358SJed Brown PetscFunctionReturn(0); 188552f7358SJed Brown } 189552f7358SJed Brown 190552f7358SJed Brown #undef __FUNCT__ 191552f7358SJed Brown #define __FUNCT__ "DMPlexView_Ascii" 192552f7358SJed Brown PetscErrorCode DMPlexView_Ascii(DM dm, PetscViewer viewer) 193552f7358SJed Brown { 194552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 195552f7358SJed Brown DM cdm; 196552f7358SJed Brown DMLabel markers; 197552f7358SJed Brown PetscSection coordSection; 198552f7358SJed Brown Vec coordinates; 199552f7358SJed Brown PetscViewerFormat format; 200552f7358SJed Brown PetscErrorCode ierr; 201552f7358SJed Brown 202552f7358SJed Brown PetscFunctionBegin; 203552f7358SJed Brown ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 204552f7358SJed Brown ierr = DMGetDefaultSection(cdm, &coordSection);CHKERRQ(ierr); 205552f7358SJed Brown ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 206552f7358SJed Brown ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 207552f7358SJed Brown if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 208552f7358SJed Brown const char *name; 209552f7358SJed Brown PetscInt maxConeSize, maxSupportSize; 210552f7358SJed Brown PetscInt pStart, pEnd, p; 211552f7358SJed Brown PetscMPIInt rank, size; 212552f7358SJed Brown 21382f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 21482f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 215552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 216552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 217552f7358SJed Brown ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 218552f7358SJed Brown ierr = PetscViewerASCIISynchronizedAllow(viewer, PETSC_TRUE);CHKERRQ(ierr); 219552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "Mesh '%s':\n", name);CHKERRQ(ierr); 220552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "Max sizes cone: %D support: %D\n", maxConeSize, maxSupportSize);CHKERRQ(ierr); 221552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "orientation is missing\n", name);CHKERRQ(ierr); 222552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "cap --> base:\n", name);CHKERRQ(ierr); 223552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 224552f7358SJed Brown PetscInt dof, off, s; 225552f7358SJed Brown 226552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 227552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 228552f7358SJed Brown for (s = off; s < off+dof; ++s) { 229552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%D]: %D ----> %D\n", rank, p, mesh->supports[s]);CHKERRQ(ierr); 230552f7358SJed Brown } 231552f7358SJed Brown } 232552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 233552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "base <-- cap:\n", name);CHKERRQ(ierr); 234552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 235552f7358SJed Brown PetscInt dof, off, c; 236552f7358SJed Brown 237552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 238552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 239552f7358SJed Brown for (c = off; c < off+dof; ++c) { 240552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%D]: %D <---- %D (%D)\n", rank, p, mesh->cones[c], mesh->coneOrientations[c]);CHKERRQ(ierr); 241552f7358SJed Brown } 242552f7358SJed Brown } 243552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 2440298fd71SBarry Smith ierr = PetscSectionGetChart(coordSection, &pStart, NULL);CHKERRQ(ierr); 245552f7358SJed Brown if (pStart >= 0) {ierr = PetscSectionVecView(coordSection, coordinates, viewer);CHKERRQ(ierr);} 246552f7358SJed Brown ierr = DMPlexGetLabel(dm, "marker", &markers);CHKERRQ(ierr); 247552f7358SJed Brown ierr = DMLabelView(markers,viewer);CHKERRQ(ierr); 248552f7358SJed Brown if (size > 1) { 249552f7358SJed Brown PetscSF sf; 250552f7358SJed Brown 251552f7358SJed Brown ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 252552f7358SJed Brown ierr = PetscSFView(sf, viewer);CHKERRQ(ierr); 253552f7358SJed Brown } 254552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 255552f7358SJed Brown } else if (format == PETSC_VIEWER_ASCII_LATEX) { 256*0588280cSMatthew G. Knepley const char *name, *color; 257*0588280cSMatthew G. Knepley const char *defcolors[3] = {"gray", "orange", "green"}; 258*0588280cSMatthew G. Knepley const char *deflcolors[4] = {"blue", "cyan", "red", "magenta"}; 259552f7358SJed Brown PetscReal scale = 2.0; 260*0588280cSMatthew G. Knepley PetscBool useNumbers = PETSC_TRUE, useLabels, useColors; 261*0588280cSMatthew G. Knepley double tcoords[3]; 262552f7358SJed Brown PetscScalar *coords; 263*0588280cSMatthew G. Knepley PetscInt numLabels, l, numColors, numLColors, dim, depth, cStart, cEnd, c, vStart, vEnd, v, eStart = 0, eEnd = 0, e, p; 264552f7358SJed Brown PetscMPIInt rank, size; 265*0588280cSMatthew G. Knepley char **names, **colors, **lcolors; 266552f7358SJed Brown 267*0588280cSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 268552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 269*0588280cSMatthew G. Knepley ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 270*0588280cSMatthew G. Knepley numLabels = PetscMax(numLabels, 10); 271*0588280cSMatthew G. Knepley numColors = 10; 272*0588280cSMatthew G. Knepley numLColors = 10; 273*0588280cSMatthew G. Knepley ierr = PetscCalloc3(numLabels, &names, numColors, &colors, numLColors, &lcolors);CHKERRQ(ierr); 274*0588280cSMatthew G. Knepley ierr = PetscOptionsGetReal(((PetscObject) viewer)->prefix, "-dm_plex_view_scale", &scale, NULL);CHKERRQ(ierr); 275*0588280cSMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) viewer)->prefix, "-dm_plex_view_numbers", &useNumbers, NULL);CHKERRQ(ierr); 276*0588280cSMatthew G. Knepley ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->prefix, "-dm_plex_view_labels", names, &numLabels, &useLabels);CHKERRQ(ierr); 277*0588280cSMatthew G. Knepley if (!useLabels) numLabels = 0; 278*0588280cSMatthew G. Knepley ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->prefix, "-dm_plex_view_colors", colors, &numColors, &useColors);CHKERRQ(ierr); 279*0588280cSMatthew G. Knepley if (!useColors) { 280*0588280cSMatthew G. Knepley numColors = 3; 281*0588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscStrallocpy(defcolors[c], &colors[c]);CHKERRQ(ierr);} 282*0588280cSMatthew G. Knepley } 283*0588280cSMatthew G. Knepley ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->prefix, "-dm_plex_view_lcolors", lcolors, &numLColors, &useColors);CHKERRQ(ierr); 284*0588280cSMatthew G. Knepley if (!useColors) { 285*0588280cSMatthew G. Knepley numLColors = 4; 286*0588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscStrallocpy(deflcolors[c], &lcolors[c]);CHKERRQ(ierr);} 287*0588280cSMatthew G. Knepley } 28882f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 28982f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 290552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 291552f7358SJed Brown ierr = PetscViewerASCIISynchronizedAllow(viewer, PETSC_TRUE);CHKERRQ(ierr); 292770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\ 293*0588280cSMatthew G. Knepley \\documentclass[tikz]{standalone}\n\n\ 294552f7358SJed Brown \\usepackage{pgflibraryshapes}\n\ 295552f7358SJed Brown \\usetikzlibrary{backgrounds}\n\ 296552f7358SJed Brown \\usetikzlibrary{arrows}\n\ 297*0588280cSMatthew G. Knepley \\begin{document}\n");CHKERRQ(ierr); 298*0588280cSMatthew G. Knepley if (size > 1) { 299f738dd31SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s for process ", name);CHKERRQ(ierr); 300770b213bSMatthew G Knepley for (p = 0; p < size; ++p) { 301770b213bSMatthew G Knepley if (p > 0 && p == size-1) { 302770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", and ", colors[p%numColors], p);CHKERRQ(ierr); 303770b213bSMatthew G Knepley } else if (p > 0) { 304770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", ", colors[p%numColors], p);CHKERRQ(ierr); 305770b213bSMatthew G Knepley } 306770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\\textcolor{%s}%D}", colors[p%numColors], p);CHKERRQ(ierr); 307770b213bSMatthew G Knepley } 308*0588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ".\n\n\n");CHKERRQ(ierr); 309*0588280cSMatthew G. Knepley } 310*0588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\begin{tikzpicture}[scale = %g,font=\\fontsize{8}{8}\\selectfont]\n", 1.0);CHKERRQ(ierr); 311552f7358SJed Brown /* Plot vertices */ 312552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 313552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 314552f7358SJed Brown for (v = vStart; v < vEnd; ++v) { 315552f7358SJed Brown PetscInt off, dof, d; 316*0588280cSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 317552f7358SJed Brown 318552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 319552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 320*0588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 321*0588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 322*0588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 323*0588280cSMatthew G. Knepley tcoords[d] = PetscAbsReal(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 324*0588280cSMatthew G. Knepley } 325*0588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 326*0588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 327552f7358SJed Brown for (d = 0; d < dof; ++d) { 328552f7358SJed Brown if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 329*0588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", tcoords[d]);CHKERRQ(ierr); 330552f7358SJed Brown } 331*0588280cSMatthew G. Knepley color = colors[rank%numColors]; 332*0588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 333*0588280cSMatthew G. Knepley PetscInt val; 334*0588280cSMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 335*0588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 336*0588280cSMatthew G. Knepley } 337*0588280cSMatthew G. Knepley if (useNumbers) { 338*0588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%D) [draw,shape=circle,color=%s] {%D};\n", v, rank, color, v);CHKERRQ(ierr); 339*0588280cSMatthew G. Knepley } else { 340*0588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%D) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", v, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 341*0588280cSMatthew G. Knepley } 342552f7358SJed Brown } 343552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 344552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 345552f7358SJed Brown /* Plot edges */ 346*0588280cSMatthew G. Knepley if (depth > 1) {ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);} 347*0588280cSMatthew G. Knepley if (dim < 3 && useNumbers) { 348552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 349552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\\path\n");CHKERRQ(ierr); 350552f7358SJed Brown for (e = eStart; e < eEnd; ++e) { 351552f7358SJed Brown const PetscInt *cone; 352552f7358SJed Brown PetscInt coneSize, offA, offB, dof, d; 353*0588280cSMatthew G. Knepley PetscBool useLabel = PETSC_FALSE; 354552f7358SJed Brown 355552f7358SJed Brown ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 35682f516ccSBarry Smith if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 357552f7358SJed Brown ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 358552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, cone[0], &dof);CHKERRQ(ierr); 359552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 360552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 361552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(");CHKERRQ(ierr); 362552f7358SJed Brown for (d = 0; d < dof; ++d) { 363*0588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[offA+d]+coords[offB+d])); 364*0588280cSMatthew G. Knepley tcoords[d] = PetscAbsReal(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 365552f7358SJed Brown } 366*0588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 367*0588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 368*0588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 369*0588280cSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 370*0588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", tcoords[d]);CHKERRQ(ierr); 371*0588280cSMatthew G. Knepley } 372*0588280cSMatthew G. Knepley color = colors[rank%numColors]; 373*0588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 374*0588280cSMatthew G. Knepley PetscInt val; 375*0588280cSMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 376*0588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; useLabel = PETSC_TRUE; break;} 377*0588280cSMatthew G. Knepley } 378*0588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%D) [draw,shape=circle,color=%s] {%D} --\n", e, rank, color, e);CHKERRQ(ierr); 379552f7358SJed Brown } 380552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 381552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 382552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "(0,0);\n");CHKERRQ(ierr); 383*0588280cSMatthew G. Knepley } 384552f7358SJed Brown /* Plot cells */ 385*0588280cSMatthew G. Knepley if (dim == 3 || !useNumbers) { 386*0588280cSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 387*0588280cSMatthew G. Knepley const PetscInt *cone; 388*0588280cSMatthew G. Knepley 389*0588280cSMatthew G. Knepley color = colors[rank%numColors]; 390*0588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 391*0588280cSMatthew G. Knepley PetscInt val; 392*0588280cSMatthew G. Knepley ierr = DMPlexGetLabelValue(dm, names[l], e, &val);CHKERRQ(ierr); 393*0588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 394*0588280cSMatthew G. Knepley } 395*0588280cSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 396*0588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%D) -- (%D_%D);\n", color, cone[0], rank, cone[1], rank);CHKERRQ(ierr); 397*0588280cSMatthew G. Knepley } 398*0588280cSMatthew G. Knepley } else { 399552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 400552f7358SJed Brown for (c = cStart; c < cEnd; ++c) { 4010298fd71SBarry Smith PetscInt *closure = NULL; 402552f7358SJed Brown PetscInt closureSize, firstPoint = -1; 403552f7358SJed Brown 404552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 405552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] ", colors[rank%numColors]);CHKERRQ(ierr); 406552f7358SJed Brown for (p = 0; p < closureSize*2; p += 2) { 407552f7358SJed Brown const PetscInt point = closure[p]; 408552f7358SJed Brown 409552f7358SJed Brown if ((point < vStart) || (point >= vEnd)) continue; 410552f7358SJed Brown if (firstPoint >= 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- ");CHKERRQ(ierr);} 411552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(%D_%D)", point, rank);CHKERRQ(ierr); 412552f7358SJed Brown if (firstPoint < 0) firstPoint = point; 413552f7358SJed Brown } 414552f7358SJed Brown /* Why doesn't this work? ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- cycle;\n");CHKERRQ(ierr); */ 415552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- (%D_%D);\n", firstPoint, rank);CHKERRQ(ierr); 416552f7358SJed Brown ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 417552f7358SJed Brown } 418*0588280cSMatthew G. Knepley } 419552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 420*0588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{tikzpicture}\n");CHKERRQ(ierr); 421770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{document}\n", name);CHKERRQ(ierr); 422*0588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) {ierr = PetscFree(names[l]);CHKERRQ(ierr);} 423*0588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscFree(colors[c]);CHKERRQ(ierr);} 424*0588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscFree(lcolors[c]);CHKERRQ(ierr);} 425*0588280cSMatthew G. Knepley ierr = PetscFree3(names, colors, lcolors);CHKERRQ(ierr); 426552f7358SJed Brown } else { 42782f516ccSBarry Smith MPI_Comm comm; 428834065abSMatthew G. Knepley PetscInt *sizes, *hybsizes; 429834065abSMatthew G. Knepley PetscInt locDepth, depth, dim, d, pMax[4]; 430552f7358SJed Brown PetscInt pStart, pEnd, p; 431a57dd577SMatthew G Knepley PetscInt numLabels, l; 4321143a3c0SMatthew G. Knepley const char *name; 433552f7358SJed Brown PetscMPIInt size; 434552f7358SJed Brown 43582f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 436552f7358SJed Brown ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 437c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4385f64d76eSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 4391143a3c0SMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimensions:\n", name, dim);CHKERRQ(ierr);} 4401143a3c0SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimensions:\n", dim);CHKERRQ(ierr);} 441552f7358SJed Brown ierr = DMPlexGetDepth(dm, &locDepth);CHKERRQ(ierr); 442552f7358SJed Brown ierr = MPI_Allreduce(&locDepth, &depth, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 443bb81ee50SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &pMax[depth], depth > 0 ? &pMax[depth-1] : NULL, &pMax[1], &pMax[0]);CHKERRQ(ierr); 444dcca6d9dSJed Brown ierr = PetscMalloc2(size,&sizes,size,&hybsizes);CHKERRQ(ierr); 445552f7358SJed Brown if (depth == 1) { 446552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 447552f7358SJed Brown pEnd = pEnd - pStart; 448552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 449552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", 0);CHKERRQ(ierr); 450552f7358SJed Brown for (p = 0; p < size; ++p) {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 451552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 452552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 453552f7358SJed Brown pEnd = pEnd - pStart; 454552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 455552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", dim);CHKERRQ(ierr); 456552f7358SJed Brown for (p = 0; p < size; ++p) {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 457552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 458552f7358SJed Brown } else { 459552f7358SJed Brown for (d = 0; d <= dim; d++) { 460552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 461834065abSMatthew G. Knepley pEnd -= pStart; 462834065abSMatthew G. Knepley pMax[d] -= pStart; 463552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 464834065abSMatthew G. Knepley ierr = MPI_Gather(&pMax[d], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 465552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", d);CHKERRQ(ierr); 466834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 467834065abSMatthew G. Knepley if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 468834065abSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 469834065abSMatthew G. Knepley } 470552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 471552f7358SJed Brown } 472552f7358SJed Brown } 473834065abSMatthew G. Knepley ierr = PetscFree2(sizes,hybsizes);CHKERRQ(ierr); 474a57dd577SMatthew G Knepley ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 475a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 476a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 477a57dd577SMatthew G Knepley DMLabel label; 478a57dd577SMatthew G Knepley const char *name; 479a57dd577SMatthew G Knepley IS valueIS; 480a57dd577SMatthew G Knepley const PetscInt *values; 481a57dd577SMatthew G Knepley PetscInt numValues, v; 482a57dd577SMatthew G Knepley 483a57dd577SMatthew G Knepley ierr = DMPlexGetLabelName(dm, l, &name);CHKERRQ(ierr); 484a57dd577SMatthew G Knepley ierr = DMPlexGetLabel(dm, name, &label);CHKERRQ(ierr); 485a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 486a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, " %s: %d strata of sizes (", name, numValues);CHKERRQ(ierr); 487a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 488a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 489a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 490a57dd577SMatthew G Knepley PetscInt size; 491a57dd577SMatthew G Knepley 492a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 493a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 494a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "%d", size);CHKERRQ(ierr); 495a57dd577SMatthew G Knepley } 496a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 497a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 4984d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 499a57dd577SMatthew G Knepley } 500552f7358SJed Brown } 501552f7358SJed Brown PetscFunctionReturn(0); 502552f7358SJed Brown } 503552f7358SJed Brown 504552f7358SJed Brown #undef __FUNCT__ 505552f7358SJed Brown #define __FUNCT__ "DMView_Plex" 506552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 507552f7358SJed Brown { 508fcf6c8fdSToby Isaac PetscBool iascii, ishdf5, isvtk; 509552f7358SJed Brown PetscErrorCode ierr; 510552f7358SJed Brown 511552f7358SJed Brown PetscFunctionBegin; 512552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 513552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 514552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 515fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 516c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 517552f7358SJed Brown if (iascii) { 518552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 519c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 520c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 5217afe7537SMatthew G. Knepley ierr = PetscViewerPushFormat(viewer, PETSC_VIEWER_HDF5_VIZ);CHKERRQ(ierr); 522c6ccd67eSMatthew G. Knepley ierr = DMPlexView_HDF5(dm, viewer);CHKERRQ(ierr); 5237afe7537SMatthew G. Knepley ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 524c6ccd67eSMatthew G. Knepley #else 525c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 526552f7358SJed Brown #endif 52711aeaf0aSBarry Smith } 528fcf6c8fdSToby Isaac else if (isvtk) { 529fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 530fcf6c8fdSToby Isaac } 531552f7358SJed Brown PetscFunctionReturn(0); 532552f7358SJed Brown } 533552f7358SJed Brown 5342c40f234SMatthew G. Knepley #undef __FUNCT__ 5352c40f234SMatthew G. Knepley #define __FUNCT__ "DMLoad_Plex" 5362c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 5372c40f234SMatthew G. Knepley { 5382c40f234SMatthew G. Knepley PetscBool isbinary, ishdf5; 5392c40f234SMatthew G. Knepley PetscErrorCode ierr; 5402c40f234SMatthew G. Knepley 5412c40f234SMatthew G. Knepley PetscFunctionBegin; 5422c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5432c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 5442c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERBINARY, &isbinary);CHKERRQ(ierr); 5452c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 5462c40f234SMatthew G. Knepley if (isbinary) {SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Do not yet support binary viewers");} 5472c40f234SMatthew G. Knepley else if (ishdf5) { 5482c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 54910b7db4eSMatthew G. Knepley ierr = DMPlexLoad_HDF5(dm, viewer);CHKERRQ(ierr); 5502c40f234SMatthew G. Knepley #else 5512c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 552552f7358SJed Brown #endif 553552f7358SJed Brown } 554552f7358SJed Brown PetscFunctionReturn(0); 555552f7358SJed Brown } 556552f7358SJed Brown 557552f7358SJed Brown #undef __FUNCT__ 5586c73c22cSMatthew G. Knepley #define __FUNCT__ "BoundaryDestroy" 5596c73c22cSMatthew G. Knepley static PetscErrorCode BoundaryDestroy(DMBoundary *boundary) 5606c73c22cSMatthew G. Knepley { 5616c73c22cSMatthew G. Knepley DMBoundary b, next; 5626c73c22cSMatthew G. Knepley PetscErrorCode ierr; 5636c73c22cSMatthew G. Knepley 5648e136ac0SMatthew G. Knepley PetscFunctionBegin; 5656c73c22cSMatthew G. Knepley if (!boundary) PetscFunctionReturn(0); 5666c73c22cSMatthew G. Knepley b = *boundary; 5676c73c22cSMatthew G. Knepley *boundary = NULL; 5686c73c22cSMatthew G. Knepley for (; b; b = next) { 5696c73c22cSMatthew G. Knepley next = b->next; 5706c73c22cSMatthew G. Knepley ierr = PetscFree(b->ids);CHKERRQ(ierr); 5716c73c22cSMatthew G. Knepley ierr = PetscFree(b->name);CHKERRQ(ierr); 57263d5297fSMatthew G. Knepley ierr = PetscFree(b->labelname);CHKERRQ(ierr); 5736c73c22cSMatthew G. Knepley ierr = PetscFree(b);CHKERRQ(ierr); 5746c73c22cSMatthew G. Knepley } 5756c73c22cSMatthew G. Knepley PetscFunctionReturn(0); 5766c73c22cSMatthew G. Knepley } 5776c73c22cSMatthew G. Knepley 5786c73c22cSMatthew G. Knepley #undef __FUNCT__ 579552f7358SJed Brown #define __FUNCT__ "DMDestroy_Plex" 580552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 581552f7358SJed Brown { 582552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 583a85475f2SMatthew G. Knepley PlexLabel next = mesh->labels; 584552f7358SJed Brown PetscErrorCode ierr; 585552f7358SJed Brown 586552f7358SJed Brown PetscFunctionBegin; 5870d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 588552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 589552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 590552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 591552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 592552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 593552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 594d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 595d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 59677623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 597552f7358SJed Brown while (next) { 598a85475f2SMatthew G. Knepley PlexLabel tmp = next->next; 599552f7358SJed Brown 600a85475f2SMatthew G. Knepley ierr = DMLabelDestroy(&next->label);CHKERRQ(ierr); 601a85475f2SMatthew G. Knepley ierr = PetscFree(next);CHKERRQ(ierr); 602552f7358SJed Brown next = tmp; 603552f7358SJed Brown } 6043913d7c8SMatthew G. Knepley ierr = DMDestroy(&mesh->coarseMesh);CHKERRQ(ierr); 605a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 606552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 607552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 6086c73c22cSMatthew G. Knepley ierr = BoundaryDestroy(&mesh->boundary);CHKERRQ(ierr); 609a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 610a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 611d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 612d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 613d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 614d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 615d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 616d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 617552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 618552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 619552f7358SJed Brown PetscFunctionReturn(0); 620552f7358SJed Brown } 621552f7358SJed Brown 622552f7358SJed Brown #undef __FUNCT__ 623552f7358SJed Brown #define __FUNCT__ "DMCreateMatrix_Plex" 624b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 625552f7358SJed Brown { 626552f7358SJed Brown PetscSection section, sectionGlobal; 627552f7358SJed Brown PetscInt bs = -1; 628552f7358SJed Brown PetscInt localSize; 62989545effSMatthew G. Knepley PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock; 630552f7358SJed Brown PetscErrorCode ierr; 631b412c318SBarry Smith MatType mtype; 632552f7358SJed Brown 633552f7358SJed Brown PetscFunctionBegin; 634607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 635b412c318SBarry Smith mtype = dm->mattype; 636552f7358SJed Brown ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 637552f7358SJed Brown ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 638552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 639552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 64082f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 641552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 642552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 643552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 644552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 645552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 646552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 647552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 648552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 649552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 650552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 651552f7358SJed Brown if (!isShell) { 652552f7358SJed Brown PetscBool fillMatrix = (PetscBool) !dm->prealloc_only; 6532a28c762SMatthew G Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal, bsMax, bsMin; 654552f7358SJed Brown 655552f7358SJed Brown if (bs < 0) { 656552f7358SJed Brown if (isBlock || isSeqBlock || isMPIBlock || isSymBlock || isSymSeqBlock || isSymMPIBlock) { 657fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 658552f7358SJed Brown 659552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 660552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 661552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 662fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 663fad22124SMatthew G Knepley if (dof-cdof) { 6642a28c762SMatthew G Knepley if (bs < 0) { 665fad22124SMatthew G Knepley bs = dof-cdof; 666fad22124SMatthew G Knepley } else if (bs != dof-cdof) { 6672a28c762SMatthew G Knepley /* Layout does not admit a pointwise block size */ 6682a28c762SMatthew G Knepley bs = 1; 669552f7358SJed Brown break; 670552f7358SJed Brown } 671552f7358SJed Brown } 6722a28c762SMatthew G Knepley } 6732a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 6742a28c762SMatthew G Knepley bsLocal = bs; 67582f516ccSBarry Smith ierr = MPI_Allreduce(&bsLocal, &bsMax, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 6762a28c762SMatthew G Knepley bsLocal = bs < 0 ? bsMax : bs; 67782f516ccSBarry Smith ierr = MPI_Allreduce(&bsLocal, &bsMin, 1, MPIU_INT, MPI_MIN, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 6782a28c762SMatthew G Knepley if (bsMin != bsMax) { 6792a28c762SMatthew G Knepley bs = 1; 6802a28c762SMatthew G Knepley } else { 6812a28c762SMatthew G Knepley bs = bsMax; 6822a28c762SMatthew G Knepley } 683552f7358SJed Brown } else { 684552f7358SJed Brown bs = 1; 685552f7358SJed Brown } 686552f7358SJed Brown } 6871795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 688552f7358SJed Brown ierr = DMPlexPreallocateOperator(dm, bs, section, sectionGlobal, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 689552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 690552f7358SJed Brown } 691552f7358SJed Brown PetscFunctionReturn(0); 692552f7358SJed Brown } 693552f7358SJed Brown 694552f7358SJed Brown #undef __FUNCT__ 695552f7358SJed Brown #define __FUNCT__ "DMPlexGetChart" 696552f7358SJed Brown /*@ 697552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 698552f7358SJed Brown 699552f7358SJed Brown Not collective 700552f7358SJed Brown 701552f7358SJed Brown Input Parameter: 702552f7358SJed Brown . mesh - The DMPlex 703552f7358SJed Brown 704552f7358SJed Brown Output Parameters: 705552f7358SJed Brown + pStart - The first mesh point 706552f7358SJed Brown - pEnd - The upper bound for mesh points 707552f7358SJed Brown 708552f7358SJed Brown Level: beginner 709552f7358SJed Brown 710552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 711552f7358SJed Brown @*/ 712552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 713552f7358SJed Brown { 714552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 715552f7358SJed Brown PetscErrorCode ierr; 716552f7358SJed Brown 717552f7358SJed Brown PetscFunctionBegin; 718552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 719552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 720552f7358SJed Brown PetscFunctionReturn(0); 721552f7358SJed Brown } 722552f7358SJed Brown 723552f7358SJed Brown #undef __FUNCT__ 724552f7358SJed Brown #define __FUNCT__ "DMPlexSetChart" 725552f7358SJed Brown /*@ 726552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 727552f7358SJed Brown 728552f7358SJed Brown Not collective 729552f7358SJed Brown 730552f7358SJed Brown Input Parameters: 731552f7358SJed Brown + mesh - The DMPlex 732552f7358SJed Brown . pStart - The first mesh point 733552f7358SJed Brown - pEnd - The upper bound for mesh points 734552f7358SJed Brown 735552f7358SJed Brown Output Parameters: 736552f7358SJed Brown 737552f7358SJed Brown Level: beginner 738552f7358SJed Brown 739552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 740552f7358SJed Brown @*/ 741552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 742552f7358SJed Brown { 743552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 744552f7358SJed Brown PetscErrorCode ierr; 745552f7358SJed Brown 746552f7358SJed Brown PetscFunctionBegin; 747552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 748552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 749552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 750552f7358SJed Brown PetscFunctionReturn(0); 751552f7358SJed Brown } 752552f7358SJed Brown 753552f7358SJed Brown #undef __FUNCT__ 754552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeSize" 755552f7358SJed Brown /*@ 756552f7358SJed Brown DMPlexGetConeSize - Return the number of in-edges for this point in the Sieve DAG 757552f7358SJed Brown 758552f7358SJed Brown Not collective 759552f7358SJed Brown 760552f7358SJed Brown Input Parameters: 761552f7358SJed Brown + mesh - The DMPlex 762552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 763552f7358SJed Brown 764552f7358SJed Brown Output Parameter: 765552f7358SJed Brown . size - The cone size for point p 766552f7358SJed Brown 767552f7358SJed Brown Level: beginner 768552f7358SJed Brown 769552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 770552f7358SJed Brown @*/ 771552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 772552f7358SJed Brown { 773552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 774552f7358SJed Brown PetscErrorCode ierr; 775552f7358SJed Brown 776552f7358SJed Brown PetscFunctionBegin; 777552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 778552f7358SJed Brown PetscValidPointer(size, 3); 779552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 780552f7358SJed Brown PetscFunctionReturn(0); 781552f7358SJed Brown } 782552f7358SJed Brown 783552f7358SJed Brown #undef __FUNCT__ 784552f7358SJed Brown #define __FUNCT__ "DMPlexSetConeSize" 785552f7358SJed Brown /*@ 786552f7358SJed Brown DMPlexSetConeSize - Set the number of in-edges for this point in the Sieve DAG 787552f7358SJed Brown 788552f7358SJed Brown Not collective 789552f7358SJed Brown 790552f7358SJed Brown Input Parameters: 791552f7358SJed Brown + mesh - The DMPlex 792552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 793552f7358SJed Brown - size - The cone size for point p 794552f7358SJed Brown 795552f7358SJed Brown Output Parameter: 796552f7358SJed Brown 797552f7358SJed Brown Note: 798552f7358SJed Brown This should be called after DMPlexSetChart(). 799552f7358SJed Brown 800552f7358SJed Brown Level: beginner 801552f7358SJed Brown 802552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 803552f7358SJed Brown @*/ 804552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 805552f7358SJed Brown { 806552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 807552f7358SJed Brown PetscErrorCode ierr; 808552f7358SJed Brown 809552f7358SJed Brown PetscFunctionBegin; 810552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 811552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 8120d644c17SKarl Rupp 813552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 814552f7358SJed Brown PetscFunctionReturn(0); 815552f7358SJed Brown } 816552f7358SJed Brown 817552f7358SJed Brown #undef __FUNCT__ 818f5a469b9SMatthew G. Knepley #define __FUNCT__ "DMPlexAddConeSize" 819f5a469b9SMatthew G. Knepley /*@ 820f5a469b9SMatthew G. Knepley DMPlexAddConeSize - Add the given number of in-edges to this point in the Sieve DAG 821f5a469b9SMatthew G. Knepley 822f5a469b9SMatthew G. Knepley Not collective 823f5a469b9SMatthew G. Knepley 824f5a469b9SMatthew G. Knepley Input Parameters: 825f5a469b9SMatthew G. Knepley + mesh - The DMPlex 826f5a469b9SMatthew G. Knepley . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 827f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 828f5a469b9SMatthew G. Knepley 829f5a469b9SMatthew G. Knepley Output Parameter: 830f5a469b9SMatthew G. Knepley 831f5a469b9SMatthew G. Knepley Note: 832f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 833f5a469b9SMatthew G. Knepley 834f5a469b9SMatthew G. Knepley Level: beginner 835f5a469b9SMatthew G. Knepley 836f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 837f5a469b9SMatthew G. Knepley @*/ 838f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 839f5a469b9SMatthew G. Knepley { 840f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 841f5a469b9SMatthew G. Knepley PetscInt csize; 842f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 843f5a469b9SMatthew G. Knepley 844f5a469b9SMatthew G. Knepley PetscFunctionBegin; 845f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 846f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 847f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 848f5a469b9SMatthew G. Knepley 849f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 850f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 851f5a469b9SMatthew G. Knepley } 852f5a469b9SMatthew G. Knepley 853f5a469b9SMatthew G. Knepley #undef __FUNCT__ 854552f7358SJed Brown #define __FUNCT__ "DMPlexGetCone" 855552f7358SJed Brown /*@C 856552f7358SJed Brown DMPlexGetCone - Return the points on the in-edges for this point in the Sieve DAG 857552f7358SJed Brown 858552f7358SJed Brown Not collective 859552f7358SJed Brown 860552f7358SJed Brown Input Parameters: 861552f7358SJed Brown + mesh - The DMPlex 862552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 863552f7358SJed Brown 864552f7358SJed Brown Output Parameter: 865552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 866552f7358SJed Brown 867552f7358SJed Brown Level: beginner 868552f7358SJed Brown 8693813dfbdSMatthew G Knepley Fortran Notes: 8703813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 8713813dfbdSMatthew G Knepley include petsc.h90 in your code. 8723813dfbdSMatthew G Knepley 8733813dfbdSMatthew G Knepley You must also call DMPlexRestoreCone() after you finish using the returned array. 874552f7358SJed Brown 875552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart() 876552f7358SJed Brown @*/ 877552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 878552f7358SJed Brown { 879552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 880552f7358SJed Brown PetscInt off; 881552f7358SJed Brown PetscErrorCode ierr; 882552f7358SJed Brown 883552f7358SJed Brown PetscFunctionBegin; 884552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 885552f7358SJed Brown PetscValidPointer(cone, 3); 886552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 887552f7358SJed Brown *cone = &mesh->cones[off]; 888552f7358SJed Brown PetscFunctionReturn(0); 889552f7358SJed Brown } 890552f7358SJed Brown 891552f7358SJed Brown #undef __FUNCT__ 892552f7358SJed Brown #define __FUNCT__ "DMPlexSetCone" 893552f7358SJed Brown /*@ 894552f7358SJed Brown DMPlexSetCone - Set the points on the in-edges for this point in the Sieve DAG 895552f7358SJed Brown 896552f7358SJed Brown Not collective 897552f7358SJed Brown 898552f7358SJed Brown Input Parameters: 899552f7358SJed Brown + mesh - The DMPlex 900552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 901552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 902552f7358SJed Brown 903552f7358SJed Brown Output Parameter: 904552f7358SJed Brown 905552f7358SJed Brown Note: 906552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 907552f7358SJed Brown 908552f7358SJed Brown Level: beginner 909552f7358SJed Brown 910552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 911552f7358SJed Brown @*/ 912552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 913552f7358SJed Brown { 914552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 915552f7358SJed Brown PetscInt pStart, pEnd; 916552f7358SJed Brown PetscInt dof, off, c; 917552f7358SJed Brown PetscErrorCode ierr; 918552f7358SJed Brown 919552f7358SJed Brown PetscFunctionBegin; 920552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 921552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 922552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 923552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 924552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 92582f516ccSBarry 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); 926552f7358SJed Brown for (c = 0; c < dof; ++c) { 92782f516ccSBarry 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); 928552f7358SJed Brown mesh->cones[off+c] = cone[c]; 929552f7358SJed Brown } 930552f7358SJed Brown PetscFunctionReturn(0); 931552f7358SJed Brown } 932552f7358SJed Brown 933552f7358SJed Brown #undef __FUNCT__ 934552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeOrientation" 935552f7358SJed Brown /*@C 936552f7358SJed Brown DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the Sieve DAG 937552f7358SJed Brown 938552f7358SJed Brown Not collective 939552f7358SJed Brown 940552f7358SJed Brown Input Parameters: 941552f7358SJed Brown + mesh - The DMPlex 942552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 943552f7358SJed Brown 944552f7358SJed Brown Output Parameter: 945552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 946552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 947552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 948552f7358SJed Brown the index of the cone point on which to start. 949552f7358SJed Brown 950552f7358SJed Brown Level: beginner 951552f7358SJed Brown 9523813dfbdSMatthew G Knepley Fortran Notes: 9533813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 9543813dfbdSMatthew G Knepley include petsc.h90 in your code. 9553813dfbdSMatthew G Knepley 9563813dfbdSMatthew G Knepley You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 957552f7358SJed Brown 958552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 959552f7358SJed Brown @*/ 960552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 961552f7358SJed Brown { 962552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 963552f7358SJed Brown PetscInt off; 964552f7358SJed Brown PetscErrorCode ierr; 965552f7358SJed Brown 966552f7358SJed Brown PetscFunctionBegin; 967552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 968552f7358SJed Brown #if defined(PETSC_USE_DEBUG) 969552f7358SJed Brown { 970552f7358SJed Brown PetscInt dof; 971552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 972552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 973552f7358SJed Brown } 974552f7358SJed Brown #endif 975552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 9760d644c17SKarl Rupp 977552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 978552f7358SJed Brown PetscFunctionReturn(0); 979552f7358SJed Brown } 980552f7358SJed Brown 981552f7358SJed Brown #undef __FUNCT__ 982552f7358SJed Brown #define __FUNCT__ "DMPlexSetConeOrientation" 983552f7358SJed Brown /*@ 984552f7358SJed Brown DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the Sieve DAG 985552f7358SJed Brown 986552f7358SJed Brown Not collective 987552f7358SJed Brown 988552f7358SJed Brown Input Parameters: 989552f7358SJed Brown + mesh - The DMPlex 990552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 991552f7358SJed Brown - coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 992552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 993552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 994552f7358SJed Brown the index of the cone point on which to start. 995552f7358SJed Brown 996552f7358SJed Brown Output Parameter: 997552f7358SJed Brown 998552f7358SJed Brown Note: 999552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1000552f7358SJed Brown 1001552f7358SJed Brown Level: beginner 1002552f7358SJed Brown 1003552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 1004552f7358SJed Brown @*/ 1005552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 1006552f7358SJed Brown { 1007552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1008552f7358SJed Brown PetscInt pStart, pEnd; 1009552f7358SJed Brown PetscInt dof, off, c; 1010552f7358SJed Brown PetscErrorCode ierr; 1011552f7358SJed Brown 1012552f7358SJed Brown PetscFunctionBegin; 1013552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1014552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1015552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1016552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 1017552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 101882f516ccSBarry 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); 1019552f7358SJed Brown for (c = 0; c < dof; ++c) { 1020552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 1021552f7358SJed Brown 1022552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 102382f516ccSBarry 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); 1024552f7358SJed Brown mesh->coneOrientations[off+c] = o; 1025552f7358SJed Brown } 1026552f7358SJed Brown PetscFunctionReturn(0); 1027552f7358SJed Brown } 1028552f7358SJed Brown 1029552f7358SJed Brown #undef __FUNCT__ 1030552f7358SJed Brown #define __FUNCT__ "DMPlexInsertCone" 1031552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 1032552f7358SJed Brown { 1033552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1034552f7358SJed Brown PetscInt pStart, pEnd; 1035552f7358SJed Brown PetscInt dof, off; 1036552f7358SJed Brown PetscErrorCode ierr; 1037552f7358SJed Brown 1038552f7358SJed Brown PetscFunctionBegin; 1039552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1040552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 104182f516ccSBarry 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); 104282f516ccSBarry 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); 104377c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 104477c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 104577c88f5bSMatthew 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); 1046552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 1047552f7358SJed Brown PetscFunctionReturn(0); 1048552f7358SJed Brown } 1049552f7358SJed Brown 1050552f7358SJed Brown #undef __FUNCT__ 105177c88f5bSMatthew G Knepley #define __FUNCT__ "DMPlexInsertConeOrientation" 105277c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 105377c88f5bSMatthew G Knepley { 105477c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 105577c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 105677c88f5bSMatthew G Knepley PetscInt dof, off; 105777c88f5bSMatthew G Knepley PetscErrorCode ierr; 105877c88f5bSMatthew G Knepley 105977c88f5bSMatthew G Knepley PetscFunctionBegin; 106077c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 106177c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 106277c88f5bSMatthew 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); 106377c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 106477c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 106577c88f5bSMatthew 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); 106677c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 106777c88f5bSMatthew G Knepley PetscFunctionReturn(0); 106877c88f5bSMatthew G Knepley } 106977c88f5bSMatthew G Knepley 107077c88f5bSMatthew G Knepley #undef __FUNCT__ 1071552f7358SJed Brown #define __FUNCT__ "DMPlexGetSupportSize" 1072552f7358SJed Brown /*@ 1073552f7358SJed Brown DMPlexGetSupportSize - Return the number of out-edges for this point in the Sieve DAG 1074552f7358SJed Brown 1075552f7358SJed Brown Not collective 1076552f7358SJed Brown 1077552f7358SJed Brown Input Parameters: 1078552f7358SJed Brown + mesh - The DMPlex 1079552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1080552f7358SJed Brown 1081552f7358SJed Brown Output Parameter: 1082552f7358SJed Brown . size - The support size for point p 1083552f7358SJed Brown 1084552f7358SJed Brown Level: beginner 1085552f7358SJed Brown 1086552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 1087552f7358SJed Brown @*/ 1088552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 1089552f7358SJed Brown { 1090552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1091552f7358SJed Brown PetscErrorCode ierr; 1092552f7358SJed Brown 1093552f7358SJed Brown PetscFunctionBegin; 1094552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1095552f7358SJed Brown PetscValidPointer(size, 3); 1096552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 1097552f7358SJed Brown PetscFunctionReturn(0); 1098552f7358SJed Brown } 1099552f7358SJed Brown 1100552f7358SJed Brown #undef __FUNCT__ 1101552f7358SJed Brown #define __FUNCT__ "DMPlexSetSupportSize" 1102552f7358SJed Brown /*@ 1103552f7358SJed Brown DMPlexSetSupportSize - Set the number of out-edges for this point in the Sieve DAG 1104552f7358SJed Brown 1105552f7358SJed Brown Not collective 1106552f7358SJed Brown 1107552f7358SJed Brown Input Parameters: 1108552f7358SJed Brown + mesh - The DMPlex 1109552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1110552f7358SJed Brown - size - The support size for point p 1111552f7358SJed Brown 1112552f7358SJed Brown Output Parameter: 1113552f7358SJed Brown 1114552f7358SJed Brown Note: 1115552f7358SJed Brown This should be called after DMPlexSetChart(). 1116552f7358SJed Brown 1117552f7358SJed Brown Level: beginner 1118552f7358SJed Brown 1119552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 1120552f7358SJed Brown @*/ 1121552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 1122552f7358SJed Brown { 1123552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1124552f7358SJed Brown PetscErrorCode ierr; 1125552f7358SJed Brown 1126552f7358SJed Brown PetscFunctionBegin; 1127552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1128552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 11290d644c17SKarl Rupp 1130552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 1131552f7358SJed Brown PetscFunctionReturn(0); 1132552f7358SJed Brown } 1133552f7358SJed Brown 1134552f7358SJed Brown #undef __FUNCT__ 1135552f7358SJed Brown #define __FUNCT__ "DMPlexGetSupport" 1136552f7358SJed Brown /*@C 1137552f7358SJed Brown DMPlexGetSupport - Return the points on the out-edges for this point in the Sieve DAG 1138552f7358SJed Brown 1139552f7358SJed Brown Not collective 1140552f7358SJed Brown 1141552f7358SJed Brown Input Parameters: 1142552f7358SJed Brown + mesh - The DMPlex 1143552f7358SJed Brown - p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1144552f7358SJed Brown 1145552f7358SJed Brown Output Parameter: 1146552f7358SJed Brown . support - An array of points which are on the out-edges for point p 1147552f7358SJed Brown 1148552f7358SJed Brown Level: beginner 1149552f7358SJed Brown 11503813dfbdSMatthew G Knepley Fortran Notes: 11513813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 11523813dfbdSMatthew G Knepley include petsc.h90 in your code. 11533813dfbdSMatthew G Knepley 11543813dfbdSMatthew G Knepley You must also call DMPlexRestoreSupport() after you finish using the returned array. 11553813dfbdSMatthew G Knepley 1156552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1157552f7358SJed Brown @*/ 1158552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 1159552f7358SJed Brown { 1160552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1161552f7358SJed Brown PetscInt off; 1162552f7358SJed Brown PetscErrorCode ierr; 1163552f7358SJed Brown 1164552f7358SJed Brown PetscFunctionBegin; 1165552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1166552f7358SJed Brown PetscValidPointer(support, 3); 1167552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 1168552f7358SJed Brown *support = &mesh->supports[off]; 1169552f7358SJed Brown PetscFunctionReturn(0); 1170552f7358SJed Brown } 1171552f7358SJed Brown 1172552f7358SJed Brown #undef __FUNCT__ 1173552f7358SJed Brown #define __FUNCT__ "DMPlexSetSupport" 1174552f7358SJed Brown /*@ 1175552f7358SJed Brown DMPlexSetSupport - Set the points on the out-edges for this point in the Sieve DAG 1176552f7358SJed Brown 1177552f7358SJed Brown Not collective 1178552f7358SJed Brown 1179552f7358SJed Brown Input Parameters: 1180552f7358SJed Brown + mesh - The DMPlex 1181552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1182552f7358SJed Brown - support - An array of points which are on the in-edges for point p 1183552f7358SJed Brown 1184552f7358SJed Brown Output Parameter: 1185552f7358SJed Brown 1186552f7358SJed Brown Note: 1187552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 1188552f7358SJed Brown 1189552f7358SJed Brown Level: beginner 1190552f7358SJed Brown 1191552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 1192552f7358SJed Brown @*/ 1193552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 1194552f7358SJed Brown { 1195552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1196552f7358SJed Brown PetscInt pStart, pEnd; 1197552f7358SJed Brown PetscInt dof, off, c; 1198552f7358SJed Brown PetscErrorCode ierr; 1199552f7358SJed Brown 1200552f7358SJed Brown PetscFunctionBegin; 1201552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1202552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 1203552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 1204552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 1205552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 120682f516ccSBarry 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); 1207552f7358SJed Brown for (c = 0; c < dof; ++c) { 120882f516ccSBarry 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); 1209552f7358SJed Brown mesh->supports[off+c] = support[c]; 1210552f7358SJed Brown } 1211552f7358SJed Brown PetscFunctionReturn(0); 1212552f7358SJed Brown } 1213552f7358SJed Brown 1214552f7358SJed Brown #undef __FUNCT__ 1215552f7358SJed Brown #define __FUNCT__ "DMPlexInsertSupport" 1216552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 1217552f7358SJed Brown { 1218552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1219552f7358SJed Brown PetscInt pStart, pEnd; 1220552f7358SJed Brown PetscInt dof, off; 1221552f7358SJed Brown PetscErrorCode ierr; 1222552f7358SJed Brown 1223552f7358SJed Brown PetscFunctionBegin; 1224552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1225552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 1226552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 1227552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 122882f516ccSBarry 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); 122982f516ccSBarry 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); 123082f516ccSBarry 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); 1231552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 1232552f7358SJed Brown PetscFunctionReturn(0); 1233552f7358SJed Brown } 1234552f7358SJed Brown 1235552f7358SJed Brown #undef __FUNCT__ 1236552f7358SJed Brown #define __FUNCT__ "DMPlexGetTransitiveClosure" 1237552f7358SJed Brown /*@C 1238552f7358SJed Brown DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the Sieve DAG 1239552f7358SJed Brown 1240552f7358SJed Brown Not collective 1241552f7358SJed Brown 1242552f7358SJed Brown Input Parameters: 1243552f7358SJed Brown + mesh - The DMPlex 1244552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1245552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 12460298fd71SBarry Smith - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 1247552f7358SJed Brown 1248552f7358SJed Brown Output Parameters: 1249552f7358SJed Brown + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 1250552f7358SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 1251552f7358SJed Brown 1252552f7358SJed Brown Note: 12530298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 1254552f7358SJed Brown 12553813dfbdSMatthew G Knepley Fortran Notes: 12563813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 12573813dfbdSMatthew G Knepley include petsc.h90 in your code. 12583813dfbdSMatthew G Knepley 12593813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 12603813dfbdSMatthew G Knepley 1261552f7358SJed Brown Level: beginner 1262552f7358SJed Brown 1263552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1264552f7358SJed Brown @*/ 1265552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 1266552f7358SJed Brown { 1267552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1268552f7358SJed Brown PetscInt *closure, *fifo; 12690298fd71SBarry Smith const PetscInt *tmp = NULL, *tmpO = NULL; 1270552f7358SJed Brown PetscInt tmpSize, t; 1271552f7358SJed Brown PetscInt depth = 0, maxSize; 1272552f7358SJed Brown PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 1273552f7358SJed Brown PetscErrorCode ierr; 1274552f7358SJed Brown 1275552f7358SJed Brown PetscFunctionBegin; 1276552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1277552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1278552f7358SJed Brown /* This is only 1-level */ 1279552f7358SJed Brown if (useCone) { 1280552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 1281552f7358SJed Brown ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 1282552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 1283552f7358SJed Brown } else { 1284552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 1285552f7358SJed Brown ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 1286552f7358SJed Brown } 1287bfbcdd7aSMatthew G. Knepley if (depth == 1) { 1288bfbcdd7aSMatthew G. Knepley if (*points) { 1289bfbcdd7aSMatthew G. Knepley closure = *points; 1290bfbcdd7aSMatthew G. Knepley } else { 1291bfbcdd7aSMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 1292bfbcdd7aSMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 1293bfbcdd7aSMatthew G. Knepley } 1294bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 1295bfbcdd7aSMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 1296bfbcdd7aSMatthew G. Knepley closure[closureSize] = tmp[t]; 1297bfbcdd7aSMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[t] : 0; 1298bfbcdd7aSMatthew G. Knepley } 1299bfbcdd7aSMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 1300bfbcdd7aSMatthew G. Knepley if (points) *points = closure; 1301bfbcdd7aSMatthew G. Knepley PetscFunctionReturn(0); 1302bfbcdd7aSMatthew G. Knepley } 130324c766afSToby Isaac { 130424c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 130524c766afSToby Isaac 130624c766afSToby Isaac c = mesh->maxConeSize; 130724c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 130824c766afSToby Isaac s = mesh->maxSupportSize; 130924c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 131024c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 131124c766afSToby Isaac } 1312bfbcdd7aSMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 1313bfbcdd7aSMatthew G. Knepley if (*points) { 1314bfbcdd7aSMatthew G. Knepley closure = *points; 1315bfbcdd7aSMatthew G. Knepley } else { 1316bfbcdd7aSMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 1317bfbcdd7aSMatthew G. Knepley } 1318bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 1319552f7358SJed Brown for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 1320552f7358SJed Brown const PetscInt cp = tmp[t]; 1321552f7358SJed Brown const PetscInt co = tmpO ? tmpO[t] : 0; 1322552f7358SJed Brown 1323552f7358SJed Brown closure[closureSize] = cp; 1324552f7358SJed Brown closure[closureSize+1] = co; 1325552f7358SJed Brown fifo[fifoSize] = cp; 1326552f7358SJed Brown fifo[fifoSize+1] = co; 1327552f7358SJed Brown } 1328bfbcdd7aSMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 1329552f7358SJed Brown while (fifoSize - fifoStart) { 1330552f7358SJed Brown const PetscInt q = fifo[fifoStart]; 1331552f7358SJed Brown const PetscInt o = fifo[fifoStart+1]; 1332552f7358SJed Brown const PetscInt rev = o >= 0 ? 0 : 1; 1333552f7358SJed Brown const PetscInt off = rev ? -(o+1) : o; 1334552f7358SJed Brown 1335552f7358SJed Brown if (useCone) { 1336552f7358SJed Brown ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 1337552f7358SJed Brown ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 1338552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 1339552f7358SJed Brown } else { 1340552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 1341552f7358SJed Brown ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 13420298fd71SBarry Smith tmpO = NULL; 1343552f7358SJed Brown } 1344552f7358SJed Brown for (t = 0; t < tmpSize; ++t) { 1345552f7358SJed Brown const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 1346552f7358SJed Brown const PetscInt cp = tmp[i]; 13472e1b13c2SMatthew 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. */ 13482e1b13c2SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 13492e1b13c2SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 13502e1b13c2SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 1351552f7358SJed Brown PetscInt c; 1352552f7358SJed Brown 13532e1b13c2SMatthew G. Knepley if (rev) { 13542e1b13c2SMatthew G. Knepley PetscInt childSize, coff; 13552e1b13c2SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 13562e1b13c2SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 13572e1b13c2SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 13582e1b13c2SMatthew G. Knepley } 1359552f7358SJed Brown /* Check for duplicate */ 1360552f7358SJed Brown for (c = 0; c < closureSize; c += 2) { 1361552f7358SJed Brown if (closure[c] == cp) break; 1362552f7358SJed Brown } 1363552f7358SJed Brown if (c == closureSize) { 1364552f7358SJed Brown closure[closureSize] = cp; 1365552f7358SJed Brown closure[closureSize+1] = co; 1366552f7358SJed Brown fifo[fifoSize] = cp; 1367552f7358SJed Brown fifo[fifoSize+1] = co; 1368552f7358SJed Brown closureSize += 2; 1369552f7358SJed Brown fifoSize += 2; 1370552f7358SJed Brown } 1371552f7358SJed Brown } 1372552f7358SJed Brown fifoStart += 2; 1373552f7358SJed Brown } 1374552f7358SJed Brown if (numPoints) *numPoints = closureSize/2; 1375552f7358SJed Brown if (points) *points = closure; 1376552f7358SJed Brown ierr = DMRestoreWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 1377552f7358SJed Brown PetscFunctionReturn(0); 1378552f7358SJed Brown } 1379552f7358SJed Brown 1380552f7358SJed Brown #undef __FUNCT__ 13819bf0dad6SMatthew G. Knepley #define __FUNCT__ "DMPlexGetTransitiveClosure_Internal" 13829bf0dad6SMatthew G. Knepley /*@C 13839bf0dad6SMatthew 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 13849bf0dad6SMatthew G. Knepley 13859bf0dad6SMatthew G. Knepley Not collective 13869bf0dad6SMatthew G. Knepley 13879bf0dad6SMatthew G. Knepley Input Parameters: 13889bf0dad6SMatthew G. Knepley + mesh - The DMPlex 13899bf0dad6SMatthew G. Knepley . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 13909bf0dad6SMatthew G. Knepley . orientation - The orientation of the point 13919bf0dad6SMatthew G. Knepley . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 13929bf0dad6SMatthew G. Knepley - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 13939bf0dad6SMatthew G. Knepley 13949bf0dad6SMatthew G. Knepley Output Parameters: 13959bf0dad6SMatthew G. Knepley + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 13969bf0dad6SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 13979bf0dad6SMatthew G. Knepley 13989bf0dad6SMatthew G. Knepley Note: 13999bf0dad6SMatthew G. Knepley If using internal storage (points is NULL on input), each call overwrites the last output. 14009bf0dad6SMatthew G. Knepley 14019bf0dad6SMatthew G. Knepley Fortran Notes: 14029bf0dad6SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 14039bf0dad6SMatthew G. Knepley include petsc.h90 in your code. 14049bf0dad6SMatthew G. Knepley 14059bf0dad6SMatthew G. Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 14069bf0dad6SMatthew G. Knepley 14079bf0dad6SMatthew G. Knepley Level: beginner 14089bf0dad6SMatthew G. Knepley 14099bf0dad6SMatthew G. Knepley .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 14109bf0dad6SMatthew G. Knepley @*/ 14119bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 14129bf0dad6SMatthew G. Knepley { 14139bf0dad6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 14149bf0dad6SMatthew G. Knepley PetscInt *closure, *fifo; 14159bf0dad6SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 14169bf0dad6SMatthew G. Knepley PetscInt tmpSize, t; 14179bf0dad6SMatthew G. Knepley PetscInt depth = 0, maxSize; 14189bf0dad6SMatthew G. Knepley PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 14199bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 14209bf0dad6SMatthew G. Knepley 14219bf0dad6SMatthew G. Knepley PetscFunctionBegin; 14229bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14239bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 14249bf0dad6SMatthew G. Knepley /* This is only 1-level */ 14259bf0dad6SMatthew G. Knepley if (useCone) { 14269bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 14279bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 14289bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 14299bf0dad6SMatthew G. Knepley } else { 14309bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 14319bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 14329bf0dad6SMatthew G. Knepley } 14339bf0dad6SMatthew G. Knepley if (depth == 1) { 14349bf0dad6SMatthew G. Knepley if (*points) { 14359bf0dad6SMatthew G. Knepley closure = *points; 14369bf0dad6SMatthew G. Knepley } else { 14379bf0dad6SMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 14389bf0dad6SMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 14399bf0dad6SMatthew G. Knepley } 14409bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 14419bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 14429bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 14439bf0dad6SMatthew G. Knepley closure[closureSize] = tmp[i]; 14449bf0dad6SMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[i] : 0; 14459bf0dad6SMatthew G. Knepley } 14469bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 14479bf0dad6SMatthew G. Knepley if (points) *points = closure; 14489bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 14499bf0dad6SMatthew G. Knepley } 145024c766afSToby Isaac { 145124c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 145224c766afSToby Isaac 145324c766afSToby Isaac c = mesh->maxConeSize; 145424c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 145524c766afSToby Isaac s = mesh->maxSupportSize; 145624c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 145724c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 145824c766afSToby Isaac } 14599bf0dad6SMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 14609bf0dad6SMatthew G. Knepley if (*points) { 14619bf0dad6SMatthew G. Knepley closure = *points; 14629bf0dad6SMatthew G. Knepley } else { 14639bf0dad6SMatthew G. Knepley ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &closure);CHKERRQ(ierr); 14649bf0dad6SMatthew G. Knepley } 14659bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 14669bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 14679bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 14689bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 14699bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 14709bf0dad6SMatthew G. Knepley 14719bf0dad6SMatthew G. Knepley if (ornt < 0) { 14729bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 14739bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 14749bf0dad6SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 14759bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 14769bf0dad6SMatthew G. Knepley } 14779bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 14789bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 14799bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 14809bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 14819bf0dad6SMatthew G. Knepley } 14829bf0dad6SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 14839bf0dad6SMatthew G. Knepley while (fifoSize - fifoStart) { 14849bf0dad6SMatthew G. Knepley const PetscInt q = fifo[fifoStart]; 14859bf0dad6SMatthew G. Knepley const PetscInt o = fifo[fifoStart+1]; 14869bf0dad6SMatthew G. Knepley const PetscInt rev = o >= 0 ? 0 : 1; 14879bf0dad6SMatthew G. Knepley const PetscInt off = rev ? -(o+1) : o; 14889bf0dad6SMatthew G. Knepley 14899bf0dad6SMatthew G. Knepley if (useCone) { 14909bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 14919bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 14929bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 14939bf0dad6SMatthew G. Knepley } else { 14949bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 14959bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 14969bf0dad6SMatthew G. Knepley tmpO = NULL; 14979bf0dad6SMatthew G. Knepley } 14989bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 14999bf0dad6SMatthew G. Knepley const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 15009bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 15019bf0dad6SMatthew 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. */ 15029bf0dad6SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 15039bf0dad6SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 15049bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 15059bf0dad6SMatthew G. Knepley PetscInt c; 15069bf0dad6SMatthew G. Knepley 15079bf0dad6SMatthew G. Knepley if (rev) { 15089bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 15099bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 15109bf0dad6SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 15119bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 15129bf0dad6SMatthew G. Knepley } 15139bf0dad6SMatthew G. Knepley /* Check for duplicate */ 15149bf0dad6SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 15159bf0dad6SMatthew G. Knepley if (closure[c] == cp) break; 15169bf0dad6SMatthew G. Knepley } 15179bf0dad6SMatthew G. Knepley if (c == closureSize) { 15189bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 15199bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 15209bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 15219bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 15229bf0dad6SMatthew G. Knepley closureSize += 2; 15239bf0dad6SMatthew G. Knepley fifoSize += 2; 15249bf0dad6SMatthew G. Knepley } 15259bf0dad6SMatthew G. Knepley } 15269bf0dad6SMatthew G. Knepley fifoStart += 2; 15279bf0dad6SMatthew G. Knepley } 15289bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 15299bf0dad6SMatthew G. Knepley if (points) *points = closure; 15309bf0dad6SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, maxSize, PETSC_INT, &fifo);CHKERRQ(ierr); 15319bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 15329bf0dad6SMatthew G. Knepley } 15339bf0dad6SMatthew G. Knepley 15349bf0dad6SMatthew G. Knepley #undef __FUNCT__ 1535552f7358SJed Brown #define __FUNCT__ "DMPlexRestoreTransitiveClosure" 1536552f7358SJed Brown /*@C 1537552f7358SJed 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 1538552f7358SJed Brown 1539552f7358SJed Brown Not collective 1540552f7358SJed Brown 1541552f7358SJed Brown Input Parameters: 1542552f7358SJed Brown + mesh - The DMPlex 1543552f7358SJed Brown . p - The Sieve point, which must lie in the chart set with DMPlexSetChart() 1544552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 1545e5c84f05SJed Brown . numPoints - The number of points in the closure, so points[] is of size 2*numPoints, zeroed on exit 1546e5c84f05SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...], zeroed on exit 1547552f7358SJed Brown 1548552f7358SJed Brown Note: 15490298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 1550552f7358SJed Brown 15513813dfbdSMatthew G Knepley Fortran Notes: 15523813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 15533813dfbdSMatthew G Knepley include petsc.h90 in your code. 15543813dfbdSMatthew G Knepley 15553813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 15563813dfbdSMatthew G Knepley 1557552f7358SJed Brown Level: beginner 1558552f7358SJed Brown 1559552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1560552f7358SJed Brown @*/ 1561552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 1562552f7358SJed Brown { 1563552f7358SJed Brown PetscErrorCode ierr; 1564552f7358SJed Brown 1565552f7358SJed Brown PetscFunctionBegin; 1566552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1567e5c84f05SJed Brown if (numPoints) PetscValidIntPointer(numPoints,4); 1568e5c84f05SJed Brown if (points) PetscValidPointer(points,5); 1569552f7358SJed Brown ierr = DMRestoreWorkArray(dm, 0, PETSC_INT, points);CHKERRQ(ierr); 15704ff43b2cSJed Brown if (numPoints) *numPoints = 0; 1571552f7358SJed Brown PetscFunctionReturn(0); 1572552f7358SJed Brown } 1573552f7358SJed Brown 1574552f7358SJed Brown #undef __FUNCT__ 1575552f7358SJed Brown #define __FUNCT__ "DMPlexGetMaxSizes" 1576552f7358SJed Brown /*@ 1577552f7358SJed Brown DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the Sieve DAG 1578552f7358SJed Brown 1579552f7358SJed Brown Not collective 1580552f7358SJed Brown 1581552f7358SJed Brown Input Parameter: 1582552f7358SJed Brown . mesh - The DMPlex 1583552f7358SJed Brown 1584552f7358SJed Brown Output Parameters: 1585552f7358SJed Brown + maxConeSize - The maximum number of in-edges 1586552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 1587552f7358SJed Brown 1588552f7358SJed Brown Level: beginner 1589552f7358SJed Brown 1590552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 1591552f7358SJed Brown @*/ 1592552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 1593552f7358SJed Brown { 1594552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1595552f7358SJed Brown 1596552f7358SJed Brown PetscFunctionBegin; 1597552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1598552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 1599552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 1600552f7358SJed Brown PetscFunctionReturn(0); 1601552f7358SJed Brown } 1602552f7358SJed Brown 1603552f7358SJed Brown #undef __FUNCT__ 1604552f7358SJed Brown #define __FUNCT__ "DMSetUp_Plex" 1605552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 1606552f7358SJed Brown { 1607552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1608552f7358SJed Brown PetscInt size; 1609552f7358SJed Brown PetscErrorCode ierr; 1610552f7358SJed Brown 1611552f7358SJed Brown PetscFunctionBegin; 1612552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1613552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 1614552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 16151795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 16161795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 1617552f7358SJed Brown if (mesh->maxSupportSize) { 1618552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 1619552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 16201795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 1621552f7358SJed Brown } 1622552f7358SJed Brown PetscFunctionReturn(0); 1623552f7358SJed Brown } 1624552f7358SJed Brown 1625552f7358SJed Brown #undef __FUNCT__ 1626552f7358SJed Brown #define __FUNCT__ "DMCreateSubDM_Plex" 1627552f7358SJed Brown PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) 1628552f7358SJed Brown { 1629552f7358SJed Brown PetscErrorCode ierr; 1630552f7358SJed Brown 1631552f7358SJed Brown PetscFunctionBegin; 16324d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 16334d9407bcSMatthew G. Knepley ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 1634552f7358SJed Brown PetscFunctionReturn(0); 1635552f7358SJed Brown } 1636552f7358SJed Brown 1637552f7358SJed Brown #undef __FUNCT__ 1638552f7358SJed Brown #define __FUNCT__ "DMPlexSymmetrize" 1639552f7358SJed Brown /*@ 1640552f7358SJed Brown DMPlexSymmetrize - Creates support (out-edge) information from cone (in-edge) inoformation 1641552f7358SJed Brown 1642552f7358SJed Brown Not collective 1643552f7358SJed Brown 1644552f7358SJed Brown Input Parameter: 1645552f7358SJed Brown . mesh - The DMPlex 1646552f7358SJed Brown 1647552f7358SJed Brown Output Parameter: 1648552f7358SJed Brown 1649552f7358SJed Brown Note: 1650552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 1651552f7358SJed Brown 1652552f7358SJed Brown Level: beginner 1653552f7358SJed Brown 1654552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 1655552f7358SJed Brown @*/ 1656552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 1657552f7358SJed Brown { 1658552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1659552f7358SJed Brown PetscInt *offsets; 1660552f7358SJed Brown PetscInt supportSize; 1661552f7358SJed Brown PetscInt pStart, pEnd, p; 1662552f7358SJed Brown PetscErrorCode ierr; 1663552f7358SJed Brown 1664552f7358SJed Brown PetscFunctionBegin; 1665552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 166682f516ccSBarry Smith if (mesh->supports) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 1667552f7358SJed Brown /* Calculate support sizes */ 1668552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1669552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1670552f7358SJed Brown PetscInt dof, off, c; 1671552f7358SJed Brown 1672552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1673552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1674552f7358SJed Brown for (c = off; c < off+dof; ++c) { 1675552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 1676552f7358SJed Brown } 1677552f7358SJed Brown } 1678552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1679552f7358SJed Brown PetscInt dof; 1680552f7358SJed Brown 1681552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 16820d644c17SKarl Rupp 1683552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 1684552f7358SJed Brown } 1685552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 1686552f7358SJed Brown /* Calculate supports */ 1687552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 16881795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 16891795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 1690552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1691552f7358SJed Brown PetscInt dof, off, c; 1692552f7358SJed Brown 1693552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1694552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1695552f7358SJed Brown for (c = off; c < off+dof; ++c) { 1696552f7358SJed Brown const PetscInt q = mesh->cones[c]; 1697552f7358SJed Brown PetscInt offS; 1698552f7358SJed Brown 1699552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 17000d644c17SKarl Rupp 1701552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 1702552f7358SJed Brown ++offsets[q]; 1703552f7358SJed Brown } 1704552f7358SJed Brown } 1705552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 1706552f7358SJed Brown PetscFunctionReturn(0); 1707552f7358SJed Brown } 1708552f7358SJed Brown 1709552f7358SJed Brown #undef __FUNCT__ 1710552f7358SJed Brown #define __FUNCT__ "DMPlexStratify" 1711552f7358SJed Brown /*@ 1712552f7358SJed Brown DMPlexStratify - The Sieve DAG for most topologies is a graded poset (http://en.wikipedia.org/wiki/Graded_poset), and 1713552f7358SJed Brown can be illustrated by Hasse Diagram (a http://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 1714552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 1715552f7358SJed Brown the DAG. 1716552f7358SJed Brown 1717552f7358SJed Brown Not collective 1718552f7358SJed Brown 1719552f7358SJed Brown Input Parameter: 1720552f7358SJed Brown . mesh - The DMPlex 1721552f7358SJed Brown 1722552f7358SJed Brown Output Parameter: 1723552f7358SJed Brown 1724552f7358SJed Brown Notes: 1725150b719bSJed Brown Concretely, DMPlexStratify() creates a new label named "depth" containing the dimension of each element: 0 for vertices, 1726150b719bSJed Brown 1 for edges, and so on. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 1727150b719bSJed Brown manually via DMPlexGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 1728150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 1729552f7358SJed Brown 1730150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 1731552f7358SJed Brown 1732552f7358SJed Brown Level: beginner 1733552f7358SJed Brown 1734552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSymmetrize() 1735552f7358SJed Brown @*/ 1736552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 1737552f7358SJed Brown { 1738aa50250dSMatthew G. Knepley DMLabel label; 1739552f7358SJed Brown PetscInt pStart, pEnd, p; 1740552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 1741552f7358SJed Brown PetscErrorCode ierr; 1742552f7358SJed Brown 1743552f7358SJed Brown PetscFunctionBegin; 1744552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1745552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 1746552f7358SJed Brown /* Calculate depth */ 1747aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 1748aa50250dSMatthew G. Knepley ierr = DMPlexCreateLabel(dm, "depth");CHKERRQ(ierr); 1749aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 1750552f7358SJed Brown /* Initialize roots and count leaves */ 1751552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1752552f7358SJed Brown PetscInt coneSize, supportSize; 1753552f7358SJed Brown 1754552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 1755552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 1756552f7358SJed Brown if (!coneSize && supportSize) { 1757552f7358SJed Brown ++numRoots; 1758aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 0);CHKERRQ(ierr); 1759552f7358SJed Brown } else if (!supportSize && coneSize) { 1760552f7358SJed Brown ++numLeaves; 1761552f7358SJed Brown } else if (!supportSize && !coneSize) { 1762552f7358SJed Brown /* Isolated points */ 1763aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 0);CHKERRQ(ierr); 1764552f7358SJed Brown } 1765552f7358SJed Brown } 1766552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 1767552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 1768552f7358SJed Brown PetscInt coneSize, supportSize; 1769552f7358SJed Brown 1770552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 1771552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 1772552f7358SJed Brown if (!supportSize && coneSize) { 1773aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 1);CHKERRQ(ierr); 1774552f7358SJed Brown } 1775552f7358SJed Brown } 1776552f7358SJed Brown } else { 177774ef644bSMatthew G. Knepley IS pointIS; 177874ef644bSMatthew G. Knepley PetscInt numPoints = 0, level = 0; 1779552f7358SJed Brown 178074ef644bSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, level, &pointIS);CHKERRQ(ierr); 178174ef644bSMatthew G. Knepley if (pointIS) {ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);} 178274ef644bSMatthew G. Knepley while (numPoints) { 178374ef644bSMatthew G. Knepley const PetscInt *points; 178474ef644bSMatthew G. Knepley const PetscInt newLevel = level+1; 178574ef644bSMatthew G. Knepley 178674ef644bSMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 178774ef644bSMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 178874ef644bSMatthew G. Knepley const PetscInt point = points[p]; 178974ef644bSMatthew G. Knepley const PetscInt *support; 179074ef644bSMatthew G. Knepley PetscInt supportSize, s; 179174ef644bSMatthew G. Knepley 179274ef644bSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, point, &supportSize);CHKERRQ(ierr); 179374ef644bSMatthew G. Knepley ierr = DMPlexGetSupport(dm, point, &support);CHKERRQ(ierr); 179474ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 179574ef644bSMatthew G. Knepley ierr = DMLabelSetValue(label, support[s], newLevel);CHKERRQ(ierr); 1796552f7358SJed Brown } 1797552f7358SJed Brown } 17985edfc765SMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 179974ef644bSMatthew G. Knepley ++level; 180074ef644bSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 180174ef644bSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, level, &pointIS);CHKERRQ(ierr); 180274ef644bSMatthew G. Knepley if (pointIS) {ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);} 180374ef644bSMatthew G. Knepley else {numPoints = 0;} 180474ef644bSMatthew G. Knepley } 180574ef644bSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 180674ef644bSMatthew G. Knepley } 1807552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 1808552f7358SJed Brown PetscFunctionReturn(0); 1809552f7358SJed Brown } 1810552f7358SJed Brown 1811552f7358SJed Brown #undef __FUNCT__ 1812552f7358SJed Brown #define __FUNCT__ "DMPlexGetJoin" 1813552f7358SJed Brown /*@C 1814552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 1815552f7358SJed Brown 1816552f7358SJed Brown Not Collective 1817552f7358SJed Brown 1818552f7358SJed Brown Input Parameters: 1819552f7358SJed Brown + dm - The DMPlex object 1820552f7358SJed Brown . numPoints - The number of input points for the join 1821552f7358SJed Brown - points - The input points 1822552f7358SJed Brown 1823552f7358SJed Brown Output Parameters: 1824552f7358SJed Brown + numCoveredPoints - The number of points in the join 1825552f7358SJed Brown - coveredPoints - The points in the join 1826552f7358SJed Brown 1827552f7358SJed Brown Level: intermediate 1828552f7358SJed Brown 1829552f7358SJed Brown Note: Currently, this is restricted to a single level join 1830552f7358SJed Brown 18313813dfbdSMatthew G Knepley Fortran Notes: 18323813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 18333813dfbdSMatthew G Knepley include petsc.h90 in your code. 18343813dfbdSMatthew G Knepley 18353813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 18363813dfbdSMatthew G Knepley 1837552f7358SJed Brown .keywords: mesh 1838552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 1839552f7358SJed Brown @*/ 1840552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 1841552f7358SJed Brown { 1842552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1843552f7358SJed Brown PetscInt *join[2]; 1844552f7358SJed Brown PetscInt joinSize, i = 0; 1845552f7358SJed Brown PetscInt dof, off, p, c, m; 1846552f7358SJed Brown PetscErrorCode ierr; 1847552f7358SJed Brown 1848552f7358SJed Brown PetscFunctionBegin; 1849552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1850552f7358SJed Brown PetscValidPointer(points, 2); 1851552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 1852552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 1853552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[0]);CHKERRQ(ierr); 1854552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[1]);CHKERRQ(ierr); 1855552f7358SJed Brown /* Copy in support of first point */ 1856552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 1857552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 1858552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 1859552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 1860552f7358SJed Brown } 1861552f7358SJed Brown /* Check each successive support */ 1862552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 1863552f7358SJed Brown PetscInt newJoinSize = 0; 1864552f7358SJed Brown 1865552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 1866552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 1867552f7358SJed Brown for (c = 0; c < dof; ++c) { 1868552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 1869552f7358SJed Brown 1870552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 1871552f7358SJed Brown if (point == join[i][m]) { 1872552f7358SJed Brown join[1-i][newJoinSize++] = point; 1873552f7358SJed Brown break; 1874552f7358SJed Brown } 1875552f7358SJed Brown } 1876552f7358SJed Brown } 1877552f7358SJed Brown joinSize = newJoinSize; 1878552f7358SJed Brown i = 1-i; 1879552f7358SJed Brown } 1880552f7358SJed Brown *numCoveredPoints = joinSize; 1881552f7358SJed Brown *coveredPoints = join[i]; 1882552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[1-i]);CHKERRQ(ierr); 1883552f7358SJed Brown PetscFunctionReturn(0); 1884552f7358SJed Brown } 1885552f7358SJed Brown 1886552f7358SJed Brown #undef __FUNCT__ 1887552f7358SJed Brown #define __FUNCT__ "DMPlexRestoreJoin" 1888552f7358SJed Brown /*@C 1889552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 1890552f7358SJed Brown 1891552f7358SJed Brown Not Collective 1892552f7358SJed Brown 1893552f7358SJed Brown Input Parameters: 1894552f7358SJed Brown + dm - The DMPlex object 1895552f7358SJed Brown . numPoints - The number of input points for the join 1896552f7358SJed Brown - points - The input points 1897552f7358SJed Brown 1898552f7358SJed Brown Output Parameters: 1899552f7358SJed Brown + numCoveredPoints - The number of points in the join 1900552f7358SJed Brown - coveredPoints - The points in the join 1901552f7358SJed Brown 19023813dfbdSMatthew G Knepley Fortran Notes: 19033813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 19043813dfbdSMatthew G Knepley include petsc.h90 in your code. 19053813dfbdSMatthew G Knepley 19063813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 19073813dfbdSMatthew G Knepley 1908552f7358SJed Brown Level: intermediate 1909552f7358SJed Brown 1910552f7358SJed Brown .keywords: mesh 1911552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 1912552f7358SJed Brown @*/ 1913552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 1914552f7358SJed Brown { 1915552f7358SJed Brown PetscErrorCode ierr; 1916552f7358SJed Brown 1917552f7358SJed Brown PetscFunctionBegin; 1918552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1919d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 1920d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 1921d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 1922552f7358SJed Brown ierr = DMRestoreWorkArray(dm, 0, PETSC_INT, (void*) coveredPoints);CHKERRQ(ierr); 1923d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 1924552f7358SJed Brown PetscFunctionReturn(0); 1925552f7358SJed Brown } 1926552f7358SJed Brown 1927552f7358SJed Brown #undef __FUNCT__ 1928552f7358SJed Brown #define __FUNCT__ "DMPlexGetFullJoin" 1929552f7358SJed Brown /*@C 1930552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 1931552f7358SJed Brown 1932552f7358SJed Brown Not Collective 1933552f7358SJed Brown 1934552f7358SJed Brown Input Parameters: 1935552f7358SJed Brown + dm - The DMPlex object 1936552f7358SJed Brown . numPoints - The number of input points for the join 1937552f7358SJed Brown - points - The input points 1938552f7358SJed Brown 1939552f7358SJed Brown Output Parameters: 1940552f7358SJed Brown + numCoveredPoints - The number of points in the join 1941552f7358SJed Brown - coveredPoints - The points in the join 1942552f7358SJed Brown 19433813dfbdSMatthew G Knepley Fortran Notes: 19443813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 19453813dfbdSMatthew G Knepley include petsc.h90 in your code. 19463813dfbdSMatthew G Knepley 19473813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 19483813dfbdSMatthew G Knepley 1949552f7358SJed Brown Level: intermediate 1950552f7358SJed Brown 1951552f7358SJed Brown .keywords: mesh 1952552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 1953552f7358SJed Brown @*/ 1954552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 1955552f7358SJed Brown { 1956552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1957552f7358SJed Brown PetscInt *offsets, **closures; 1958552f7358SJed Brown PetscInt *join[2]; 1959552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 196024c766afSToby Isaac PetscInt p, d, c, m, ms; 1961552f7358SJed Brown PetscErrorCode ierr; 1962552f7358SJed Brown 1963552f7358SJed Brown PetscFunctionBegin; 1964552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1965552f7358SJed Brown PetscValidPointer(points, 2); 1966552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 1967552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 1968552f7358SJed Brown 1969552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 19701795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 1971552f7358SJed Brown ierr = DMGetWorkArray(dm, numPoints*(depth+2), PETSC_INT, &offsets);CHKERRQ(ierr); 197224c766afSToby Isaac ms = mesh->maxSupportSize; 197324c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 1974552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &join[0]);CHKERRQ(ierr); 1975552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &join[1]);CHKERRQ(ierr); 1976552f7358SJed Brown 1977552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 1978552f7358SJed Brown PetscInt closureSize; 1979552f7358SJed Brown 1980552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 19810d644c17SKarl Rupp 1982552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 1983552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 1984552f7358SJed Brown PetscInt pStart, pEnd, i; 1985552f7358SJed Brown 1986552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 1987552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 1988552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 1989552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 1990552f7358SJed Brown break; 1991552f7358SJed Brown } 1992552f7358SJed Brown } 1993552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 1994552f7358SJed Brown } 199582f516ccSBarry 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); 1996552f7358SJed Brown } 1997552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 1998552f7358SJed Brown PetscInt dof; 1999552f7358SJed Brown 2000552f7358SJed Brown /* Copy in support of first point */ 2001552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 2002552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 2003552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 2004552f7358SJed Brown } 2005552f7358SJed Brown /* Check each successive cone */ 2006552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 2007552f7358SJed Brown PetscInt newJoinSize = 0; 2008552f7358SJed Brown 2009552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 2010552f7358SJed Brown for (c = 0; c < dof; ++c) { 2011552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 2012552f7358SJed Brown 2013552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 2014552f7358SJed Brown if (point == join[i][m]) { 2015552f7358SJed Brown join[1-i][newJoinSize++] = point; 2016552f7358SJed Brown break; 2017552f7358SJed Brown } 2018552f7358SJed Brown } 2019552f7358SJed Brown } 2020552f7358SJed Brown joinSize = newJoinSize; 2021552f7358SJed Brown i = 1-i; 2022552f7358SJed Brown } 2023552f7358SJed Brown if (joinSize) break; 2024552f7358SJed Brown } 2025552f7358SJed Brown *numCoveredPoints = joinSize; 2026552f7358SJed Brown *coveredPoints = join[i]; 2027552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 20280298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 2029552f7358SJed Brown } 2030552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 2031552f7358SJed Brown ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), PETSC_INT, &offsets);CHKERRQ(ierr); 2032552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, PETSC_INT, &join[1-i]);CHKERRQ(ierr); 2033552f7358SJed Brown PetscFunctionReturn(0); 2034552f7358SJed Brown } 2035552f7358SJed Brown 2036552f7358SJed Brown #undef __FUNCT__ 2037552f7358SJed Brown #define __FUNCT__ "DMPlexGetMeet" 2038552f7358SJed Brown /*@C 2039552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 2040552f7358SJed Brown 2041552f7358SJed Brown Not Collective 2042552f7358SJed Brown 2043552f7358SJed Brown Input Parameters: 2044552f7358SJed Brown + dm - The DMPlex object 2045552f7358SJed Brown . numPoints - The number of input points for the meet 2046552f7358SJed Brown - points - The input points 2047552f7358SJed Brown 2048552f7358SJed Brown Output Parameters: 2049552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2050552f7358SJed Brown - coveredPoints - The points in the meet 2051552f7358SJed Brown 2052552f7358SJed Brown Level: intermediate 2053552f7358SJed Brown 2054552f7358SJed Brown Note: Currently, this is restricted to a single level meet 2055552f7358SJed Brown 20563813dfbdSMatthew G Knepley Fortran Notes: 20573813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 20583813dfbdSMatthew G Knepley include petsc.h90 in your code. 20593813dfbdSMatthew G Knepley 20603813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 20613813dfbdSMatthew G Knepley 2062552f7358SJed Brown .keywords: mesh 2063552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 2064552f7358SJed Brown @*/ 2065552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 2066552f7358SJed Brown { 2067552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2068552f7358SJed Brown PetscInt *meet[2]; 2069552f7358SJed Brown PetscInt meetSize, i = 0; 2070552f7358SJed Brown PetscInt dof, off, p, c, m; 2071552f7358SJed Brown PetscErrorCode ierr; 2072552f7358SJed Brown 2073552f7358SJed Brown PetscFunctionBegin; 2074552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2075552f7358SJed Brown PetscValidPointer(points, 2); 2076552f7358SJed Brown PetscValidPointer(numCoveringPoints, 3); 2077552f7358SJed Brown PetscValidPointer(coveringPoints, 4); 2078552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[0]);CHKERRQ(ierr); 2079552f7358SJed Brown ierr = DMGetWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[1]);CHKERRQ(ierr); 2080552f7358SJed Brown /* Copy in cone of first point */ 2081552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 2082552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 2083552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 2084552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 2085552f7358SJed Brown } 2086552f7358SJed Brown /* Check each successive cone */ 2087552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 2088552f7358SJed Brown PetscInt newMeetSize = 0; 2089552f7358SJed Brown 2090552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 2091552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 2092552f7358SJed Brown for (c = 0; c < dof; ++c) { 2093552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 2094552f7358SJed Brown 2095552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 2096552f7358SJed Brown if (point == meet[i][m]) { 2097552f7358SJed Brown meet[1-i][newMeetSize++] = point; 2098552f7358SJed Brown break; 2099552f7358SJed Brown } 2100552f7358SJed Brown } 2101552f7358SJed Brown } 2102552f7358SJed Brown meetSize = newMeetSize; 2103552f7358SJed Brown i = 1-i; 2104552f7358SJed Brown } 2105552f7358SJed Brown *numCoveringPoints = meetSize; 2106552f7358SJed Brown *coveringPoints = meet[i]; 2107552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[1-i]);CHKERRQ(ierr); 2108552f7358SJed Brown PetscFunctionReturn(0); 2109552f7358SJed Brown } 2110552f7358SJed Brown 2111552f7358SJed Brown #undef __FUNCT__ 2112552f7358SJed Brown #define __FUNCT__ "DMPlexRestoreMeet" 2113552f7358SJed Brown /*@C 2114552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 2115552f7358SJed Brown 2116552f7358SJed Brown Not Collective 2117552f7358SJed Brown 2118552f7358SJed Brown Input Parameters: 2119552f7358SJed Brown + dm - The DMPlex object 2120552f7358SJed Brown . numPoints - The number of input points for the meet 2121552f7358SJed Brown - points - The input points 2122552f7358SJed Brown 2123552f7358SJed Brown Output Parameters: 2124552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2125552f7358SJed Brown - coveredPoints - The points in the meet 2126552f7358SJed Brown 2127552f7358SJed Brown Level: intermediate 2128552f7358SJed Brown 21293813dfbdSMatthew G Knepley Fortran Notes: 21303813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 21313813dfbdSMatthew G Knepley include petsc.h90 in your code. 21323813dfbdSMatthew G Knepley 21333813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 21343813dfbdSMatthew G Knepley 2135552f7358SJed Brown .keywords: mesh 2136552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 2137552f7358SJed Brown @*/ 2138552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2139552f7358SJed Brown { 2140552f7358SJed Brown PetscErrorCode ierr; 2141552f7358SJed Brown 2142552f7358SJed Brown PetscFunctionBegin; 2143552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2144d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 2145d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 2146d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 2147552f7358SJed Brown ierr = DMRestoreWorkArray(dm, 0, PETSC_INT, (void*) coveredPoints);CHKERRQ(ierr); 2148d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 2149552f7358SJed Brown PetscFunctionReturn(0); 2150552f7358SJed Brown } 2151552f7358SJed Brown 2152552f7358SJed Brown #undef __FUNCT__ 2153552f7358SJed Brown #define __FUNCT__ "DMPlexGetFullMeet" 2154552f7358SJed Brown /*@C 2155552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 2156552f7358SJed Brown 2157552f7358SJed Brown Not Collective 2158552f7358SJed Brown 2159552f7358SJed Brown Input Parameters: 2160552f7358SJed Brown + dm - The DMPlex object 2161552f7358SJed Brown . numPoints - The number of input points for the meet 2162552f7358SJed Brown - points - The input points 2163552f7358SJed Brown 2164552f7358SJed Brown Output Parameters: 2165552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2166552f7358SJed Brown - coveredPoints - The points in the meet 2167552f7358SJed Brown 2168552f7358SJed Brown Level: intermediate 2169552f7358SJed Brown 21703813dfbdSMatthew G Knepley Fortran Notes: 21713813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 21723813dfbdSMatthew G Knepley include petsc.h90 in your code. 21733813dfbdSMatthew G Knepley 21743813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 21753813dfbdSMatthew G Knepley 2176552f7358SJed Brown .keywords: mesh 2177552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 2178552f7358SJed Brown @*/ 2179552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2180552f7358SJed Brown { 2181552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2182552f7358SJed Brown PetscInt *offsets, **closures; 2183552f7358SJed Brown PetscInt *meet[2]; 2184552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 218524c766afSToby Isaac PetscInt p, h, c, m, mc; 2186552f7358SJed Brown PetscErrorCode ierr; 2187552f7358SJed Brown 2188552f7358SJed Brown PetscFunctionBegin; 2189552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2190552f7358SJed Brown PetscValidPointer(points, 2); 2191552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 2192552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 2193552f7358SJed Brown 2194552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 2195785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 2196552f7358SJed Brown ierr = DMGetWorkArray(dm, numPoints*(height+2), PETSC_INT, &offsets);CHKERRQ(ierr); 219724c766afSToby Isaac mc = mesh->maxConeSize; 219824c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 2199552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &meet[0]);CHKERRQ(ierr); 2200552f7358SJed Brown ierr = DMGetWorkArray(dm, maxSize, PETSC_INT, &meet[1]);CHKERRQ(ierr); 2201552f7358SJed Brown 2202552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 2203552f7358SJed Brown PetscInt closureSize; 2204552f7358SJed Brown 2205552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 22060d644c17SKarl Rupp 2207552f7358SJed Brown offsets[p*(height+2)+0] = 0; 2208552f7358SJed Brown for (h = 0; h < height+1; ++h) { 2209552f7358SJed Brown PetscInt pStart, pEnd, i; 2210552f7358SJed Brown 2211552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 2212552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 2213552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 2214552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 2215552f7358SJed Brown break; 2216552f7358SJed Brown } 2217552f7358SJed Brown } 2218552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 2219552f7358SJed Brown } 222082f516ccSBarry 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); 2221552f7358SJed Brown } 2222552f7358SJed Brown for (h = 0; h < height+1; ++h) { 2223552f7358SJed Brown PetscInt dof; 2224552f7358SJed Brown 2225552f7358SJed Brown /* Copy in cone of first point */ 2226552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 2227552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 2228552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 2229552f7358SJed Brown } 2230552f7358SJed Brown /* Check each successive cone */ 2231552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 2232552f7358SJed Brown PetscInt newMeetSize = 0; 2233552f7358SJed Brown 2234552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 2235552f7358SJed Brown for (c = 0; c < dof; ++c) { 2236552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 2237552f7358SJed Brown 2238552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 2239552f7358SJed Brown if (point == meet[i][m]) { 2240552f7358SJed Brown meet[1-i][newMeetSize++] = point; 2241552f7358SJed Brown break; 2242552f7358SJed Brown } 2243552f7358SJed Brown } 2244552f7358SJed Brown } 2245552f7358SJed Brown meetSize = newMeetSize; 2246552f7358SJed Brown i = 1-i; 2247552f7358SJed Brown } 2248552f7358SJed Brown if (meetSize) break; 2249552f7358SJed Brown } 2250552f7358SJed Brown *numCoveredPoints = meetSize; 2251552f7358SJed Brown *coveredPoints = meet[i]; 2252552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 22530298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 2254552f7358SJed Brown } 2255552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 2256552f7358SJed Brown ierr = DMRestoreWorkArray(dm, numPoints*(height+2), PETSC_INT, &offsets);CHKERRQ(ierr); 2257552f7358SJed Brown ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, PETSC_INT, &meet[1-i]);CHKERRQ(ierr); 2258552f7358SJed Brown PetscFunctionReturn(0); 2259552f7358SJed Brown } 2260552f7358SJed Brown 2261552f7358SJed Brown #undef __FUNCT__ 22624e3744c5SMatthew G. Knepley #define __FUNCT__ "DMPlexEqual" 22634e3744c5SMatthew G. Knepley /*@C 22644e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 22654e3744c5SMatthew G. Knepley 22664e3744c5SMatthew G. Knepley Not Collective 22674e3744c5SMatthew G. Knepley 22684e3744c5SMatthew G. Knepley Input Parameters: 22694e3744c5SMatthew G. Knepley + dmA - A DMPlex object 22704e3744c5SMatthew G. Knepley - dmB - A DMPlex object 22714e3744c5SMatthew G. Knepley 22724e3744c5SMatthew G. Knepley Output Parameters: 22734e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 22744e3744c5SMatthew G. Knepley 22754e3744c5SMatthew G. Knepley Level: intermediate 22764e3744c5SMatthew G. Knepley 22774e3744c5SMatthew G. Knepley Notes: 22784e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 22794e3744c5SMatthew G. Knepley 22804e3744c5SMatthew G. Knepley .keywords: mesh 22814e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 22824e3744c5SMatthew G. Knepley @*/ 22834e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 22844e3744c5SMatthew G. Knepley { 22854e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 22864e3744c5SMatthew G. Knepley PetscErrorCode ierr; 22874e3744c5SMatthew G. Knepley 22884e3744c5SMatthew G. Knepley PetscFunctionBegin; 22894e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 22904e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 22914e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 22924e3744c5SMatthew G. Knepley 22934e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 22944e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 22954e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 22964e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 22974e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 22984e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 22994e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 23004e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 23014e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 23024e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 23034e3744c5SMatthew G. Knepley 23044e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 23054e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 23064e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 23074e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 23084e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 23094e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 23104e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 23114e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 23124e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 23134e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 23144e3744c5SMatthew G. Knepley } 23154e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 23164e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 23174e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 23184e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 23194e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 23204e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 23214e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 23224e3744c5SMatthew G. Knepley } 23234e3744c5SMatthew G. Knepley } 23244e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 23254e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 23264e3744c5SMatthew G. Knepley } 23274e3744c5SMatthew G. Knepley 23284e3744c5SMatthew G. Knepley #undef __FUNCT__ 232918ad9376SMatthew G. Knepley #define __FUNCT__ "DMPlexGetNumFaceVertices" 233018ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 2331a6dfd86eSKarl Rupp { 233282f516ccSBarry Smith MPI_Comm comm; 2333552f7358SJed Brown PetscErrorCode ierr; 2334552f7358SJed Brown 2335552f7358SJed Brown PetscFunctionBegin; 233682f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 2337552f7358SJed Brown PetscValidPointer(numFaceVertices,3); 2338552f7358SJed Brown switch (cellDim) { 2339552f7358SJed Brown case 0: 2340552f7358SJed Brown *numFaceVertices = 0; 2341552f7358SJed Brown break; 2342552f7358SJed Brown case 1: 2343552f7358SJed Brown *numFaceVertices = 1; 2344552f7358SJed Brown break; 2345552f7358SJed Brown case 2: 2346552f7358SJed Brown switch (numCorners) { 234719436ca2SJed Brown case 3: /* triangle */ 234819436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 2349552f7358SJed Brown break; 235019436ca2SJed Brown case 4: /* quadrilateral */ 235119436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 2352552f7358SJed Brown break; 235319436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 235419436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 2355552f7358SJed Brown break; 235619436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 235719436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 2358552f7358SJed Brown break; 2359552f7358SJed Brown default: 2360552f7358SJed Brown SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %d for dimension %d", numCorners, cellDim); 2361552f7358SJed Brown } 2362552f7358SJed Brown break; 2363552f7358SJed Brown case 3: 2364552f7358SJed Brown switch (numCorners) { 236519436ca2SJed Brown case 4: /* tetradehdron */ 236619436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 2367552f7358SJed Brown break; 236819436ca2SJed Brown case 6: /* tet cohesive cells */ 236919436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 2370552f7358SJed Brown break; 237119436ca2SJed Brown case 8: /* hexahedron */ 237219436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 2373552f7358SJed Brown break; 237419436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 237519436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2376552f7358SJed Brown break; 237719436ca2SJed Brown case 10: /* quadratic tetrahedron */ 237819436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2379552f7358SJed Brown break; 238019436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 238119436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2382552f7358SJed Brown break; 238319436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 238419436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 2385552f7358SJed Brown break; 238619436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 238719436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 2388552f7358SJed Brown break; 2389552f7358SJed Brown default: 2390552f7358SJed Brown SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %d for dimension %d", numCorners, cellDim); 2391552f7358SJed Brown } 2392552f7358SJed Brown break; 2393552f7358SJed Brown default: 2394552f7358SJed Brown SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %d", cellDim); 2395552f7358SJed Brown } 2396552f7358SJed Brown PetscFunctionReturn(0); 2397552f7358SJed Brown } 2398552f7358SJed Brown 2399552f7358SJed Brown #undef __FUNCT__ 2400d49fcaecSMatthew G. Knepley #define __FUNCT__ "DMPlexLocalizeCoordinate_Internal" 2401d49fcaecSMatthew G. Knepley PetscErrorCode DMPlexLocalizeCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 2402d49fcaecSMatthew G. Knepley { 2403d49fcaecSMatthew G. Knepley PetscInt d; 2404d49fcaecSMatthew G. Knepley 2405d49fcaecSMatthew G. Knepley PetscFunctionBegin; 2406d49fcaecSMatthew G. Knepley if (!dm->maxCell) { 2407d49fcaecSMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] = in[d]; 2408d49fcaecSMatthew G. Knepley } else { 2409d49fcaecSMatthew G. Knepley for (d = 0; d < dim; ++d) { 2410d49fcaecSMatthew G. Knepley if (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d]) { 2411858aadebSMatthew G. Knepley out[d] = PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 2412d49fcaecSMatthew G. Knepley } else { 2413d49fcaecSMatthew G. Knepley out[d] = in[d]; 2414d49fcaecSMatthew G. Knepley } 2415d49fcaecSMatthew G. Knepley } 2416d49fcaecSMatthew G. Knepley } 2417d49fcaecSMatthew G. Knepley PetscFunctionReturn(0); 2418d49fcaecSMatthew G. Knepley } 2419d49fcaecSMatthew G. Knepley 2420d49fcaecSMatthew G. Knepley #undef __FUNCT__ 2421d49fcaecSMatthew G. Knepley #define __FUNCT__ "DMPlexLocalizeAddCoordinate_Internal" 2422d49fcaecSMatthew G. Knepley PetscErrorCode DMPlexLocalizeAddCoordinate_Internal(DM dm, PetscInt dim, const PetscScalar anchor[], const PetscScalar in[], PetscScalar out[]) 2423d49fcaecSMatthew G. Knepley { 2424d49fcaecSMatthew G. Knepley PetscInt d; 2425d49fcaecSMatthew G. Knepley 2426d49fcaecSMatthew G. Knepley PetscFunctionBegin; 2427d49fcaecSMatthew G. Knepley if (!dm->maxCell) { 2428d49fcaecSMatthew G. Knepley for (d = 0; d < dim; ++d) out[d] += in[d]; 2429d49fcaecSMatthew G. Knepley } else { 2430d49fcaecSMatthew G. Knepley for (d = 0; d < dim; ++d) { 2431d49fcaecSMatthew G. Knepley if (PetscAbsScalar(anchor[d] - in[d]) > dm->maxCell[d]) { 2432858aadebSMatthew G. Knepley out[d] += PetscRealPart(anchor[d]) > PetscRealPart(in[d]) ? dm->L[d] + in[d] : in[d] - dm->L[d]; 2433d49fcaecSMatthew G. Knepley } else { 2434d49fcaecSMatthew G. Knepley out[d] += in[d]; 2435d49fcaecSMatthew G. Knepley } 2436d49fcaecSMatthew G. Knepley } 2437d49fcaecSMatthew G. Knepley } 2438d49fcaecSMatthew G. Knepley PetscFunctionReturn(0); 2439d49fcaecSMatthew G. Knepley } 2440d49fcaecSMatthew G. Knepley 2441d49fcaecSMatthew G. Knepley #undef __FUNCT__ 2442d49fcaecSMatthew G. Knepley #define __FUNCT__ "DMPlexLocalizeCoordinates" 2443d49fcaecSMatthew G. Knepley PetscErrorCode DMPlexLocalizeCoordinates(DM dm) 2444d49fcaecSMatthew G. Knepley { 2445d49fcaecSMatthew G. Knepley PetscSection coordSection, cSection; 2446d49fcaecSMatthew G. Knepley Vec coordinates, cVec; 2447d49fcaecSMatthew G. Knepley PetscScalar *coords, *coords2, *anchor; 24488c7f9fc6SMatthew G. Knepley PetscInt Nc, cStart, cEnd, c, vStart, vEnd, v, dof, d, off, off2, bs, coordSize; 2449d49fcaecSMatthew G. Knepley PetscErrorCode ierr; 2450d49fcaecSMatthew G. Knepley 2451d49fcaecSMatthew G. Knepley PetscFunctionBegin; 2452d49fcaecSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2453d49fcaecSMatthew G. Knepley if (!dm->maxCell) PetscFunctionReturn(0); 2454d49fcaecSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 2455d49fcaecSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 2456d49fcaecSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 2457d49fcaecSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 2458d49fcaecSMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &cSection);CHKERRQ(ierr); 24598c7f9fc6SMatthew G. Knepley ierr = PetscSectionSetNumFields(cSection, 1);CHKERRQ(ierr); 24608c7f9fc6SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 24618c7f9fc6SMatthew G. Knepley ierr = PetscSectionSetFieldComponents(cSection, 0, Nc);CHKERRQ(ierr); 2462d49fcaecSMatthew G. Knepley ierr = PetscSectionSetChart(cSection, cStart, vEnd);CHKERRQ(ierr); 2463d49fcaecSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 2464d49fcaecSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 2465d49fcaecSMatthew G. Knepley ierr = PetscSectionSetDof(cSection, v, dof);CHKERRQ(ierr); 24668c7f9fc6SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, v, 0, dof);CHKERRQ(ierr); 2467d49fcaecSMatthew G. Knepley } 2468d49fcaecSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 2469d49fcaecSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &dof, NULL);CHKERRQ(ierr); 2470d49fcaecSMatthew G. Knepley ierr = PetscSectionSetDof(cSection, c, dof);CHKERRQ(ierr); 24718c7f9fc6SMatthew G. Knepley ierr = PetscSectionSetFieldDof(cSection, c, 0, dof);CHKERRQ(ierr); 2472d49fcaecSMatthew G. Knepley } 2473d49fcaecSMatthew G. Knepley ierr = PetscSectionSetUp(cSection);CHKERRQ(ierr); 2474d49fcaecSMatthew G. Knepley ierr = PetscSectionGetStorageSize(cSection, &coordSize);CHKERRQ(ierr); 2475d49fcaecSMatthew G. Knepley ierr = VecCreate(PetscObjectComm((PetscObject) dm), &cVec);CHKERRQ(ierr); 2476d49fcaecSMatthew G. Knepley ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 2477d49fcaecSMatthew G. Knepley ierr = VecSetBlockSize(cVec, bs);CHKERRQ(ierr); 2478d49fcaecSMatthew G. Knepley ierr = VecSetSizes(cVec, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 2479d49fcaecSMatthew G. Knepley ierr = VecSetType(cVec,VECSTANDARD);CHKERRQ(ierr); 2480d49fcaecSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 2481d49fcaecSMatthew G. Knepley ierr = VecGetArray(cVec, &coords2);CHKERRQ(ierr); 2482d49fcaecSMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 2483d49fcaecSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 2484d49fcaecSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 2485d49fcaecSMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, v, &off2);CHKERRQ(ierr); 2486d49fcaecSMatthew G. Knepley for (d = 0; d < dof; ++d) coords2[off2+d] = coords[off+d]; 2487d49fcaecSMatthew G. Knepley } 2488d49fcaecSMatthew G. Knepley ierr = DMGetWorkArray(dm, 3, PETSC_SCALAR, &anchor);CHKERRQ(ierr); 2489d49fcaecSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 2490d49fcaecSMatthew G. Knepley PetscScalar *cellCoords = NULL; 2491d49fcaecSMatthew G. Knepley PetscInt b; 2492d49fcaecSMatthew G. Knepley 2493d49fcaecSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 2494d49fcaecSMatthew G. Knepley ierr = PetscSectionGetOffset(cSection, c, &off2);CHKERRQ(ierr); 2495d49fcaecSMatthew G. Knepley for (b = 0; b < bs; ++b) anchor[b] = cellCoords[b]; 2496d49fcaecSMatthew G. Knepley for (d = 0; d < dof/bs; ++d) {ierr = DMPlexLocalizeCoordinate_Internal(dm, bs, anchor, &cellCoords[d*bs], &coords2[off2+d*bs]);CHKERRQ(ierr);} 2497d49fcaecSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &dof, &cellCoords);CHKERRQ(ierr); 2498d49fcaecSMatthew G. Knepley } 2499d49fcaecSMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 3, PETSC_SCALAR, &anchor);CHKERRQ(ierr); 2500d49fcaecSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 2501d49fcaecSMatthew G. Knepley ierr = VecRestoreArray(cVec, &coords2);CHKERRQ(ierr); 250246e270d4SMatthew G. Knepley ierr = DMSetCoordinateSection(dm, PETSC_DETERMINE, cSection);CHKERRQ(ierr); 2503d49fcaecSMatthew G. Knepley ierr = DMSetCoordinatesLocal(dm, cVec);CHKERRQ(ierr); 2504d49fcaecSMatthew G. Knepley ierr = VecDestroy(&cVec);CHKERRQ(ierr); 2505d49fcaecSMatthew G. Knepley ierr = PetscSectionDestroy(&cSection);CHKERRQ(ierr); 2506d49fcaecSMatthew G. Knepley PetscFunctionReturn(0); 2507d49fcaecSMatthew G. Knepley } 2508d49fcaecSMatthew G. Knepley 2509d49fcaecSMatthew G. Knepley #undef __FUNCT__ 2510aa50250dSMatthew G. Knepley #define __FUNCT__ "DMPlexGetDepthLabel" 2511552f7358SJed Brown /*@ 2512aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 2513552f7358SJed Brown 2514552f7358SJed Brown Not Collective 2515552f7358SJed Brown 2516aa50250dSMatthew G. Knepley Input Parameter: 2517552f7358SJed Brown . dm - The DMPlex object 2518552f7358SJed Brown 2519aa50250dSMatthew G. Knepley Output Parameter: 2520aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 2521552f7358SJed Brown 2522552f7358SJed Brown Level: developer 2523552f7358SJed Brown 2524aa50250dSMatthew G. Knepley .keywords: mesh, points 2525aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 2526aa50250dSMatthew G. Knepley @*/ 2527aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 2528aa50250dSMatthew G. Knepley { 2529aa50250dSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2530aa50250dSMatthew G. Knepley PetscErrorCode ierr; 2531aa50250dSMatthew G. Knepley 2532aa50250dSMatthew G. Knepley PetscFunctionBegin; 2533aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2534aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 253563d1a920SMatthew G. Knepley if (!mesh->depthLabel) {ierr = DMPlexGetLabel(dm, "depth", &mesh->depthLabel);CHKERRQ(ierr);} 2536aa50250dSMatthew G. Knepley *depthLabel = mesh->depthLabel; 2537aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 2538aa50250dSMatthew G. Knepley } 2539aa50250dSMatthew G. Knepley 2540aa50250dSMatthew G. Knepley #undef __FUNCT__ 2541aa50250dSMatthew G. Knepley #define __FUNCT__ "DMPlexGetDepth" 2542aa50250dSMatthew G. Knepley /*@ 2543aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 2544aa50250dSMatthew G. Knepley 2545aa50250dSMatthew G. Knepley Not Collective 2546aa50250dSMatthew G. Knepley 2547aa50250dSMatthew G. Knepley Input Parameter: 2548aa50250dSMatthew G. Knepley . dm - The DMPlex object 2549aa50250dSMatthew G. Knepley 2550aa50250dSMatthew G. Knepley Output Parameter: 2551aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 2552aa50250dSMatthew G. Knepley 2553aa50250dSMatthew G. Knepley Level: developer 2554552f7358SJed Brown 2555552f7358SJed Brown .keywords: mesh, points 2556aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepthLabel(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 2557552f7358SJed Brown @*/ 2558552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 2559552f7358SJed Brown { 2560aa50250dSMatthew G. Knepley DMLabel label; 2561aa50250dSMatthew G. Knepley PetscInt d = 0; 2562552f7358SJed Brown PetscErrorCode ierr; 2563552f7358SJed Brown 2564552f7358SJed Brown PetscFunctionBegin; 2565552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2566552f7358SJed Brown PetscValidPointer(depth, 2); 2567aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2568aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 2569552f7358SJed Brown *depth = d-1; 2570552f7358SJed Brown PetscFunctionReturn(0); 2571552f7358SJed Brown } 2572552f7358SJed Brown 2573552f7358SJed Brown #undef __FUNCT__ 2574552f7358SJed Brown #define __FUNCT__ "DMPlexGetDepthStratum" 2575552f7358SJed Brown /*@ 2576552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 2577552f7358SJed Brown 2578552f7358SJed Brown Not Collective 2579552f7358SJed Brown 2580552f7358SJed Brown Input Parameters: 2581552f7358SJed Brown + dm - The DMPlex object 2582552f7358SJed Brown - stratumValue - The requested depth 2583552f7358SJed Brown 2584552f7358SJed Brown Output Parameters: 2585552f7358SJed Brown + start - The first point at this depth 2586552f7358SJed Brown - end - One beyond the last point at this depth 2587552f7358SJed Brown 2588552f7358SJed Brown Level: developer 2589552f7358SJed Brown 2590552f7358SJed Brown .keywords: mesh, points 2591552f7358SJed Brown .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth() 2592552f7358SJed Brown @*/ 25930adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 25940adebc6cSBarry Smith { 2595aa50250dSMatthew G. Knepley DMLabel label; 259663d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 2597552f7358SJed Brown PetscErrorCode ierr; 2598552f7358SJed Brown 2599552f7358SJed Brown PetscFunctionBegin; 2600552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 260163d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 260263d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 2603552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 26040d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 260563d1a920SMatthew G. Knepley if (stratumValue < 0) { 260663d1a920SMatthew G. Knepley if (start) *start = pStart; 260763d1a920SMatthew G. Knepley if (end) *end = pEnd; 260863d1a920SMatthew G. Knepley PetscFunctionReturn(0); 2609552f7358SJed Brown } 2610aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 261163d1a920SMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 261263d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 2613552f7358SJed Brown PetscFunctionReturn(0); 2614552f7358SJed Brown } 2615552f7358SJed Brown 2616552f7358SJed Brown #undef __FUNCT__ 2617552f7358SJed Brown #define __FUNCT__ "DMPlexGetHeightStratum" 2618552f7358SJed Brown /*@ 2619552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 2620552f7358SJed Brown 2621552f7358SJed Brown Not Collective 2622552f7358SJed Brown 2623552f7358SJed Brown Input Parameters: 2624552f7358SJed Brown + dm - The DMPlex object 2625552f7358SJed Brown - stratumValue - The requested height 2626552f7358SJed Brown 2627552f7358SJed Brown Output Parameters: 2628552f7358SJed Brown + start - The first point at this height 2629552f7358SJed Brown - end - One beyond the last point at this height 2630552f7358SJed Brown 2631552f7358SJed Brown Level: developer 2632552f7358SJed Brown 2633552f7358SJed Brown .keywords: mesh, points 2634552f7358SJed Brown .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth() 2635552f7358SJed Brown @*/ 26360adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 26370adebc6cSBarry Smith { 2638aa50250dSMatthew G. Knepley DMLabel label; 263963d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 2640552f7358SJed Brown PetscErrorCode ierr; 2641552f7358SJed Brown 2642552f7358SJed Brown PetscFunctionBegin; 2643552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 264463d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 264563d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 2646552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 26470d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 264863d1a920SMatthew G. Knepley if (stratumValue < 0) { 264963d1a920SMatthew G. Knepley if (start) *start = pStart; 265063d1a920SMatthew G. Knepley if (end) *end = pEnd; 265163d1a920SMatthew G. Knepley PetscFunctionReturn(0); 2652552f7358SJed Brown } 2653aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2654aa50250dSMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found");CHKERRQ(ierr); 265563d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 265663d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 2657552f7358SJed Brown PetscFunctionReturn(0); 2658552f7358SJed Brown } 2659552f7358SJed Brown 2660552f7358SJed Brown #undef __FUNCT__ 2661552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSectionInitial" 2662552f7358SJed Brown /* Set the number of dof on each point and separate by fields */ 2663a6dfd86eSKarl Rupp PetscErrorCode DMPlexCreateSectionInitial(DM dm, PetscInt dim, PetscInt numFields,const PetscInt numComp[],const PetscInt numDof[], PetscSection *section) 2664a6dfd86eSKarl Rupp { 2665552f7358SJed Brown PetscInt *numDofTot; 2666916f0f19SMatthew G. Knepley PetscInt depth, pStart = 0, pEnd = 0; 2667916f0f19SMatthew G. Knepley PetscInt p, d, dep, f; 2668552f7358SJed Brown PetscErrorCode ierr; 2669552f7358SJed Brown 2670552f7358SJed Brown PetscFunctionBegin; 2671854ce69bSBarry Smith ierr = PetscMalloc1(dim+1, &numDofTot);CHKERRQ(ierr); 2672552f7358SJed Brown for (d = 0; d <= dim; ++d) { 2673552f7358SJed Brown numDofTot[d] = 0; 26740d644c17SKarl Rupp for (f = 0; f < numFields; ++f) numDofTot[d] += numDof[f*(dim+1)+d]; 2675552f7358SJed Brown } 267682f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), section);CHKERRQ(ierr); 2677552f7358SJed Brown if (numFields > 0) { 2678552f7358SJed Brown ierr = PetscSectionSetNumFields(*section, numFields);CHKERRQ(ierr); 2679552f7358SJed Brown if (numComp) { 2680552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2681552f7358SJed Brown ierr = PetscSectionSetFieldComponents(*section, f, numComp[f]);CHKERRQ(ierr); 2682552f7358SJed Brown } 2683552f7358SJed Brown } 2684552f7358SJed Brown } 2685552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2686552f7358SJed Brown ierr = PetscSectionSetChart(*section, pStart, pEnd);CHKERRQ(ierr); 2687916f0f19SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 2688916f0f19SMatthew G. Knepley for (dep = 0; dep <= depth; ++dep) { 2689916f0f19SMatthew G. Knepley d = dim == depth ? dep : (!dep ? 0 : dim); 2690916f0f19SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, dep, &pStart, &pEnd);CHKERRQ(ierr); 2691552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2692552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2693552f7358SJed Brown ierr = PetscSectionSetFieldDof(*section, p, f, numDof[f*(dim+1)+d]);CHKERRQ(ierr); 2694552f7358SJed Brown } 2695552f7358SJed Brown ierr = PetscSectionSetDof(*section, p, numDofTot[d]);CHKERRQ(ierr); 2696552f7358SJed Brown } 2697552f7358SJed Brown } 2698552f7358SJed Brown ierr = PetscFree(numDofTot);CHKERRQ(ierr); 2699552f7358SJed Brown PetscFunctionReturn(0); 2700552f7358SJed Brown } 2701552f7358SJed Brown 2702552f7358SJed Brown #undef __FUNCT__ 2703552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSectionBCDof" 2704552f7358SJed Brown /* Set the number of dof on each point and separate by fields 2705552f7358SJed Brown If constDof is PETSC_DETERMINE, constrain every dof on the point 2706552f7358SJed Brown */ 2707a6dfd86eSKarl Rupp PetscErrorCode DMPlexCreateSectionBCDof(DM dm, PetscInt numBC,const PetscInt bcField[],const IS bcPoints[], PetscInt constDof, PetscSection section) 2708a6dfd86eSKarl Rupp { 2709552f7358SJed Brown PetscInt numFields; 2710552f7358SJed Brown PetscInt bc; 2711a68b90caSToby Isaac PetscSection aSec; 2712552f7358SJed Brown PetscErrorCode ierr; 2713552f7358SJed Brown 2714552f7358SJed Brown PetscFunctionBegin; 2715552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 2716552f7358SJed Brown for (bc = 0; bc < numBC; ++bc) { 2717552f7358SJed Brown PetscInt field = 0; 2718552f7358SJed Brown const PetscInt *idx; 2719552f7358SJed Brown PetscInt n, i; 2720552f7358SJed Brown 27210d644c17SKarl Rupp if (numFields) field = bcField[bc]; 2722552f7358SJed Brown ierr = ISGetLocalSize(bcPoints[bc], &n);CHKERRQ(ierr); 2723552f7358SJed Brown ierr = ISGetIndices(bcPoints[bc], &idx);CHKERRQ(ierr); 2724552f7358SJed Brown for (i = 0; i < n; ++i) { 2725552f7358SJed Brown const PetscInt p = idx[i]; 2726552f7358SJed Brown PetscInt numConst = constDof; 2727552f7358SJed Brown 2728552f7358SJed Brown /* Constrain every dof on the point */ 2729552f7358SJed Brown if (numConst < 0) { 2730552f7358SJed Brown if (numFields) { 2731552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, p, field, &numConst);CHKERRQ(ierr); 2732552f7358SJed Brown } else { 2733552f7358SJed Brown ierr = PetscSectionGetDof(section, p, &numConst);CHKERRQ(ierr); 2734552f7358SJed Brown } 2735552f7358SJed Brown } 2736552f7358SJed Brown if (numFields) { 2737552f7358SJed Brown ierr = PetscSectionAddFieldConstraintDof(section, p, field, numConst);CHKERRQ(ierr); 2738552f7358SJed Brown } 2739552f7358SJed Brown ierr = PetscSectionAddConstraintDof(section, p, numConst);CHKERRQ(ierr); 2740552f7358SJed Brown } 2741552f7358SJed Brown ierr = ISRestoreIndices(bcPoints[bc], &idx);CHKERRQ(ierr); 2742552f7358SJed Brown } 2743a17985deSToby Isaac ierr = DMPlexGetAnchors(dm, &aSec, NULL);CHKERRQ(ierr); 2744a68b90caSToby Isaac if (aSec) { 2745a68b90caSToby Isaac PetscInt aStart, aEnd, a; 2746a68b90caSToby Isaac 2747a68b90caSToby Isaac ierr = PetscSectionGetChart(aSec, &aStart, &aEnd);CHKERRQ(ierr); 2748a68b90caSToby Isaac for (a = aStart; a < aEnd; a++) { 2749a68b90caSToby Isaac PetscInt dof; 2750a68b90caSToby Isaac 2751a68b90caSToby Isaac ierr = PetscSectionGetDof(aSec, a, &dof);CHKERRQ(ierr); 2752a68b90caSToby Isaac if (dof) { 2753a68b90caSToby Isaac /* if there are point-to-point constraints, then all dofs are constrained */ 2754a68b90caSToby Isaac ierr = PetscSectionGetDof(section, a, &dof);CHKERRQ(ierr); 2755a68b90caSToby Isaac ierr = PetscSectionSetConstraintDof(section, a, dof);CHKERRQ(ierr); 2756a68b90caSToby Isaac if (numFields) { 2757a68b90caSToby Isaac PetscInt f; 2758a68b90caSToby Isaac 2759a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 2760a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &dof);CHKERRQ(ierr); 2761a68b90caSToby Isaac ierr = PetscSectionSetFieldConstraintDof(section, a, f, dof);CHKERRQ(ierr); 2762a68b90caSToby Isaac } 2763a68b90caSToby Isaac } 2764a68b90caSToby Isaac } 2765a68b90caSToby Isaac } 2766a68b90caSToby Isaac } 2767552f7358SJed Brown PetscFunctionReturn(0); 2768552f7358SJed Brown } 2769552f7358SJed Brown 2770552f7358SJed Brown #undef __FUNCT__ 2771552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSectionBCIndicesAll" 2772552f7358SJed Brown /* Set the constrained indices on each point and separate by fields */ 27730adebc6cSBarry Smith PetscErrorCode DMPlexCreateSectionBCIndicesAll(DM dm, PetscSection section) 27740adebc6cSBarry Smith { 2775552f7358SJed Brown PetscInt *maxConstraints; 2776552f7358SJed Brown PetscInt numFields, f, pStart = 0, pEnd = 0, p; 2777552f7358SJed Brown PetscErrorCode ierr; 2778552f7358SJed Brown 2779552f7358SJed Brown PetscFunctionBegin; 2780552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 2781552f7358SJed Brown ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 2782854ce69bSBarry Smith ierr = PetscMalloc1(numFields+1, &maxConstraints);CHKERRQ(ierr); 27830d644c17SKarl Rupp for (f = 0; f <= numFields; ++f) maxConstraints[f] = 0; 2784552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2785552f7358SJed Brown PetscInt cdof; 2786552f7358SJed Brown 2787552f7358SJed Brown if (numFields) { 2788552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2789552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, p, f, &cdof);CHKERRQ(ierr); 2790552f7358SJed Brown maxConstraints[f] = PetscMax(maxConstraints[f], cdof); 2791552f7358SJed Brown } 2792552f7358SJed Brown } else { 2793552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 2794552f7358SJed Brown maxConstraints[0] = PetscMax(maxConstraints[0], cdof); 2795552f7358SJed Brown } 2796552f7358SJed Brown } 2797552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2798552f7358SJed Brown maxConstraints[numFields] += maxConstraints[f]; 2799552f7358SJed Brown } 2800552f7358SJed Brown if (maxConstraints[numFields]) { 2801552f7358SJed Brown PetscInt *indices; 2802552f7358SJed Brown 2803785e854fSJed Brown ierr = PetscMalloc1(maxConstraints[numFields], &indices);CHKERRQ(ierr); 2804552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2805552f7358SJed Brown PetscInt cdof, d; 2806552f7358SJed Brown 2807552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 2808552f7358SJed Brown if (cdof) { 2809552f7358SJed Brown if (cdof > maxConstraints[numFields]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_LIB, "Likely memory corruption, point %D cDof %D > maxConstraints %D", p, cdof, maxConstraints[numFields]); 2810552f7358SJed Brown if (numFields) { 2811552f7358SJed Brown PetscInt numConst = 0, foff = 0; 2812552f7358SJed Brown 2813552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2814552f7358SJed Brown PetscInt cfdof, fdof; 2815552f7358SJed Brown 2816552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 2817552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, p, f, &cfdof);CHKERRQ(ierr); 2818552f7358SJed Brown /* Change constraint numbering from absolute local dof number to field relative local dof number */ 28190d644c17SKarl Rupp for (d = 0; d < cfdof; ++d) indices[numConst+d] = d; 2820552f7358SJed Brown ierr = PetscSectionSetFieldConstraintIndices(section, p, f, &indices[numConst]);CHKERRQ(ierr); 28210d644c17SKarl Rupp for (d = 0; d < cfdof; ++d) indices[numConst+d] += foff; 2822552f7358SJed Brown numConst += cfdof; 2823552f7358SJed Brown foff += fdof; 2824552f7358SJed Brown } 2825552f7358SJed Brown if (cdof != numConst) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Total number of field constraints %D should be %D", numConst, cdof); 2826552f7358SJed Brown } else { 28270d644c17SKarl Rupp for (d = 0; d < cdof; ++d) indices[d] = d; 2828552f7358SJed Brown } 2829552f7358SJed Brown ierr = PetscSectionSetConstraintIndices(section, p, indices);CHKERRQ(ierr); 2830552f7358SJed Brown } 2831552f7358SJed Brown } 2832552f7358SJed Brown ierr = PetscFree(indices);CHKERRQ(ierr); 2833552f7358SJed Brown } 2834552f7358SJed Brown ierr = PetscFree(maxConstraints);CHKERRQ(ierr); 2835552f7358SJed Brown PetscFunctionReturn(0); 2836552f7358SJed Brown } 2837552f7358SJed Brown 2838552f7358SJed Brown #undef __FUNCT__ 2839552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSectionBCIndicesField" 2840552f7358SJed Brown /* Set the constrained field indices on each point */ 28410adebc6cSBarry Smith PetscErrorCode DMPlexCreateSectionBCIndicesField(DM dm, PetscInt field, IS bcPoints, IS constraintIndices, PetscSection section) 28420adebc6cSBarry Smith { 2843552f7358SJed Brown const PetscInt *points, *indices; 2844552f7358SJed Brown PetscInt numFields, maxDof, numPoints, p, numConstraints; 2845552f7358SJed Brown PetscErrorCode ierr; 2846552f7358SJed Brown 2847552f7358SJed Brown PetscFunctionBegin; 2848552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 2849552f7358SJed Brown if ((field < 0) || (field >= numFields)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Section field %d should be in [%d, %d)", field, 0, numFields); 2850552f7358SJed Brown 2851552f7358SJed Brown ierr = ISGetLocalSize(bcPoints, &numPoints);CHKERRQ(ierr); 2852552f7358SJed Brown ierr = ISGetIndices(bcPoints, &points);CHKERRQ(ierr); 2853552f7358SJed Brown if (!constraintIndices) { 2854552f7358SJed Brown PetscInt *idx, i; 2855552f7358SJed Brown 2856552f7358SJed Brown ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 2857785e854fSJed Brown ierr = PetscMalloc1(maxDof, &idx);CHKERRQ(ierr); 28580d644c17SKarl Rupp for (i = 0; i < maxDof; ++i) idx[i] = i; 2859552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 2860552f7358SJed Brown ierr = PetscSectionSetFieldConstraintIndices(section, points[p], field, idx);CHKERRQ(ierr); 2861552f7358SJed Brown } 2862552f7358SJed Brown ierr = PetscFree(idx);CHKERRQ(ierr); 2863552f7358SJed Brown } else { 2864552f7358SJed Brown ierr = ISGetLocalSize(constraintIndices, &numConstraints);CHKERRQ(ierr); 2865552f7358SJed Brown ierr = ISGetIndices(constraintIndices, &indices);CHKERRQ(ierr); 2866552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 2867552f7358SJed Brown PetscInt fcdof; 2868552f7358SJed Brown 2869552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, points[p], field, &fcdof);CHKERRQ(ierr); 287082f516ccSBarry Smith if (fcdof != numConstraints) SETERRQ4(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Section point %d field %d has %d constraints, but yo ugave %d indices", p, field, fcdof, numConstraints); 2871552f7358SJed Brown ierr = PetscSectionSetFieldConstraintIndices(section, points[p], field, indices);CHKERRQ(ierr); 2872552f7358SJed Brown } 2873552f7358SJed Brown ierr = ISRestoreIndices(constraintIndices, &indices);CHKERRQ(ierr); 2874552f7358SJed Brown } 2875552f7358SJed Brown ierr = ISRestoreIndices(bcPoints, &points);CHKERRQ(ierr); 2876552f7358SJed Brown PetscFunctionReturn(0); 2877552f7358SJed Brown } 2878552f7358SJed Brown 2879552f7358SJed Brown #undef __FUNCT__ 2880552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSectionBCIndices" 2881552f7358SJed Brown /* Set the constrained indices on each point and separate by fields */ 28820adebc6cSBarry Smith PetscErrorCode DMPlexCreateSectionBCIndices(DM dm, PetscSection section) 28830adebc6cSBarry Smith { 2884552f7358SJed Brown PetscInt *indices; 2885552f7358SJed Brown PetscInt numFields, maxDof, f, pStart = 0, pEnd = 0, p; 2886552f7358SJed Brown PetscErrorCode ierr; 2887552f7358SJed Brown 2888552f7358SJed Brown PetscFunctionBegin; 2889552f7358SJed Brown ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 2890785e854fSJed Brown ierr = PetscMalloc1(maxDof, &indices);CHKERRQ(ierr); 2891552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 289282f516ccSBarry Smith if (!numFields) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "This function only works after users have set field constraint indices."); 2893552f7358SJed Brown ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 2894552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2895552f7358SJed Brown PetscInt cdof, d; 2896552f7358SJed Brown 2897552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, p, &cdof);CHKERRQ(ierr); 2898552f7358SJed Brown if (cdof) { 2899552f7358SJed Brown PetscInt numConst = 0, foff = 0; 2900552f7358SJed Brown 2901552f7358SJed Brown for (f = 0; f < numFields; ++f) { 2902552f7358SJed Brown const PetscInt *fcind; 2903552f7358SJed Brown PetscInt fdof, fcdof; 2904552f7358SJed Brown 2905552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 2906552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 2907552f7358SJed Brown if (fcdof) {ierr = PetscSectionGetFieldConstraintIndices(section, p, f, &fcind);CHKERRQ(ierr);} 2908552f7358SJed Brown /* Change constraint numbering from field relative local dof number to absolute local dof number */ 29090d644c17SKarl Rupp for (d = 0; d < fcdof; ++d) indices[numConst+d] = fcind[d]+foff; 2910552f7358SJed Brown foff += fdof; 2911552f7358SJed Brown numConst += fcdof; 2912552f7358SJed Brown } 291382f516ccSBarry Smith if (cdof != numConst) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_LIB, "Total number of field constraints %D should be %D", numConst, cdof); 2914552f7358SJed Brown ierr = PetscSectionSetConstraintIndices(section, p, indices);CHKERRQ(ierr); 2915552f7358SJed Brown } 2916552f7358SJed Brown } 2917552f7358SJed Brown ierr = PetscFree(indices);CHKERRQ(ierr); 2918552f7358SJed Brown PetscFunctionReturn(0); 2919552f7358SJed Brown } 2920552f7358SJed Brown 2921552f7358SJed Brown #undef __FUNCT__ 2922552f7358SJed Brown #define __FUNCT__ "DMPlexCreateSection" 2923552f7358SJed Brown /*@C 2924552f7358SJed Brown DMPlexCreateSection - Create a PetscSection based upon the dof layout specification provided. 2925552f7358SJed Brown 2926552f7358SJed Brown Not Collective 2927552f7358SJed Brown 2928552f7358SJed Brown Input Parameters: 2929552f7358SJed Brown + dm - The DMPlex object 2930552f7358SJed Brown . dim - The spatial dimension of the problem 2931552f7358SJed Brown . numFields - The number of fields in the problem 2932552f7358SJed Brown . numComp - An array of size numFields that holds the number of components for each field 2933552f7358SJed 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 2934552f7358SJed Brown . numBC - The number of boundary conditions 2935552f7358SJed Brown . bcField - An array of size numBC giving the field number for each boundry condition 2936f8f126e8SMatthew G. Knepley . bcPoints - An array of size numBC giving an IS holding the sieve points to which each boundary condition applies 2937f8f126e8SMatthew G. Knepley - perm - Optional permutation of the chart, or NULL 2938552f7358SJed Brown 2939552f7358SJed Brown Output Parameter: 2940552f7358SJed Brown . section - The PetscSection object 2941552f7358SJed Brown 2942552f7358SJed 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 2943f8f126e8SMatthew G. Knepley number of dof for field 0 on each edge. 2944f8f126e8SMatthew G. Knepley 2945f8f126e8SMatthew G. Knepley The chart permutation is the same one set using PetscSectionSetPermutation() 2946552f7358SJed Brown 2947552f7358SJed Brown Level: developer 2948552f7358SJed Brown 29493813dfbdSMatthew G Knepley Fortran Notes: 29503813dfbdSMatthew G Knepley A Fortran 90 version is available as DMPlexCreateSectionF90() 29513813dfbdSMatthew G Knepley 2952552f7358SJed Brown .keywords: mesh, elements 2953f8f126e8SMatthew G. Knepley .seealso: DMPlexCreate(), PetscSectionCreate(), PetscSectionSetPermutation() 2954552f7358SJed Brown @*/ 2955f8f126e8SMatthew G. Knepley PetscErrorCode DMPlexCreateSection(DM dm, PetscInt dim, PetscInt numFields,const PetscInt numComp[],const PetscInt numDof[], PetscInt numBC,const PetscInt bcField[],const IS bcPoints[], IS perm, PetscSection *section) 2956a6dfd86eSKarl Rupp { 2957a68b90caSToby Isaac PetscSection aSec; 2958552f7358SJed Brown PetscErrorCode ierr; 2959552f7358SJed Brown 2960552f7358SJed Brown PetscFunctionBegin; 2961552f7358SJed Brown ierr = DMPlexCreateSectionInitial(dm, dim, numFields, numComp, numDof, section);CHKERRQ(ierr); 2962552f7358SJed Brown ierr = DMPlexCreateSectionBCDof(dm, numBC, bcField, bcPoints, PETSC_DETERMINE, *section);CHKERRQ(ierr); 2963f8f126e8SMatthew G. Knepley if (perm) {ierr = PetscSectionSetPermutation(*section, perm);CHKERRQ(ierr);} 2964552f7358SJed Brown ierr = PetscSectionSetUp(*section);CHKERRQ(ierr); 2965a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,NULL);CHKERRQ(ierr); 2966a68b90caSToby Isaac if (numBC || aSec) {ierr = DMPlexCreateSectionBCIndicesAll(dm, *section);CHKERRQ(ierr);} 2967ce1779c8SBarry Smith ierr = PetscSectionViewFromOptions(*section,NULL,"-section_view");CHKERRQ(ierr); 2968552f7358SJed Brown PetscFunctionReturn(0); 2969552f7358SJed Brown } 2970552f7358SJed Brown 2971552f7358SJed Brown #undef __FUNCT__ 2972552f7358SJed Brown #define __FUNCT__ "DMCreateCoordinateDM_Plex" 29730adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 29740adebc6cSBarry Smith { 2975552f7358SJed Brown PetscSection section; 2976552f7358SJed Brown PetscErrorCode ierr; 2977552f7358SJed Brown 2978552f7358SJed Brown PetscFunctionBegin; 297938221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 298082f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 2981552f7358SJed Brown ierr = DMSetDefaultSection(*cdm, section);CHKERRQ(ierr); 29821d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2983552f7358SJed Brown PetscFunctionReturn(0); 2984552f7358SJed Brown } 2985552f7358SJed Brown 2986552f7358SJed Brown #undef __FUNCT__ 2987552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeSection" 29880adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 29890adebc6cSBarry Smith { 2990552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2991552f7358SJed Brown 2992552f7358SJed Brown PetscFunctionBegin; 2993552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2994552f7358SJed Brown if (section) *section = mesh->coneSection; 2995552f7358SJed Brown PetscFunctionReturn(0); 2996552f7358SJed Brown } 2997552f7358SJed Brown 2998552f7358SJed Brown #undef __FUNCT__ 29998cb4d582SMatthew G. Knepley #define __FUNCT__ "DMPlexGetSupportSection" 30008cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 30018cb4d582SMatthew G. Knepley { 30028cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 30038cb4d582SMatthew G. Knepley 30048cb4d582SMatthew G. Knepley PetscFunctionBegin; 30058cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 30068cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 30078cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 30088cb4d582SMatthew G. Knepley } 30098cb4d582SMatthew G. Knepley 30108cb4d582SMatthew G. Knepley #undef __FUNCT__ 3011552f7358SJed Brown #define __FUNCT__ "DMPlexGetCones" 3012a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 3013a6dfd86eSKarl Rupp { 3014552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3015552f7358SJed Brown 3016552f7358SJed Brown PetscFunctionBegin; 3017552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3018552f7358SJed Brown if (cones) *cones = mesh->cones; 3019552f7358SJed Brown PetscFunctionReturn(0); 3020552f7358SJed Brown } 3021552f7358SJed Brown 3022552f7358SJed Brown #undef __FUNCT__ 3023552f7358SJed Brown #define __FUNCT__ "DMPlexGetConeOrientations" 3024a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 3025a6dfd86eSKarl Rupp { 3026552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3027552f7358SJed Brown 3028552f7358SJed Brown PetscFunctionBegin; 3029552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3030552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 3031552f7358SJed Brown PetscFunctionReturn(0); 3032552f7358SJed Brown } 3033552f7358SJed Brown 3034552f7358SJed Brown /******************************** FEM Support **********************************/ 3035552f7358SJed Brown 3036552f7358SJed Brown #undef __FUNCT__ 30371a271a75SMatthew G. Knepley #define __FUNCT__ "DMPlexVecGetClosure_Depth1_Static" 30381a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3039a6dfd86eSKarl Rupp { 3040552f7358SJed Brown PetscScalar *array, *vArray; 3041d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 30421a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 3043552f7358SJed Brown PetscErrorCode ierr; 3044552f7358SJed Brown 30451b406b76SMatthew G. Knepley PetscFunctionBeginHot; 30462a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 30475a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 30485a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 30495a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 30503f7cbbe7SMatthew G. Knepley if (!values || !*values) { 30519df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 30529df71ca4SMatthew G. Knepley PetscInt dof; 3053d9917b9dSMatthew G. Knepley 30549df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 30559df71ca4SMatthew G. Knepley size += dof; 30569df71ca4SMatthew G. Knepley } 30579df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 30589df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 30592a3aaacfSMatthew G. Knepley PetscInt dof; 30605a1bb5cfSMatthew G. Knepley 30615a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 30622a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 30635a1bb5cfSMatthew G. Knepley size += dof; 30645a1bb5cfSMatthew G. Knepley } 30653f7cbbe7SMatthew G. Knepley if (!values) { 30663f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 30673f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 30683f7cbbe7SMatthew G. Knepley } 30695a1bb5cfSMatthew G. Knepley ierr = DMGetWorkArray(dm, size, PETSC_SCALAR, &array);CHKERRQ(ierr); 3070982e9ed1SMatthew G. Knepley } else { 3071982e9ed1SMatthew G. Knepley array = *values; 3072982e9ed1SMatthew G. Knepley } 30739df71ca4SMatthew G. Knepley size = 0; 30745a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 30759df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 30769df71ca4SMatthew G. Knepley PetscInt dof, off, d; 30779df71ca4SMatthew G. Knepley PetscScalar *varr; 3078d9917b9dSMatthew G. Knepley 30799df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 30809df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 30819df71ca4SMatthew G. Knepley varr = &vArray[off]; 30821a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 30831a271a75SMatthew G. Knepley array[offset] = varr[d]; 30849df71ca4SMatthew G. Knepley } 30859df71ca4SMatthew G. Knepley size += dof; 30869df71ca4SMatthew G. Knepley } 30879df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 30889df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 30899df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 30905a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 30915a1bb5cfSMatthew G. Knepley PetscScalar *varr; 30925a1bb5cfSMatthew G. Knepley 309352ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 30945a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 30955a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 30965a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 30975a1bb5cfSMatthew G. Knepley if (o >= 0) { 30981a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 30991a271a75SMatthew G. Knepley array[offset] = varr[d]; 31005a1bb5cfSMatthew G. Knepley } 31015a1bb5cfSMatthew G. Knepley } else { 31021a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 31031a271a75SMatthew G. Knepley array[offset] = varr[d]; 31045a1bb5cfSMatthew G. Knepley } 31055a1bb5cfSMatthew G. Knepley } 31069df71ca4SMatthew G. Knepley size += dof; 31075a1bb5cfSMatthew G. Knepley } 31085a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 31099df71ca4SMatthew G. Knepley if (!*values) { 31105a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 31115a1bb5cfSMatthew G. Knepley *values = array; 31129df71ca4SMatthew G. Knepley } else { 31139df71ca4SMatthew G. Knepley if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %d < actual size %d", *csize, size); 31148c312ff3SMatthew G. Knepley *csize = size; 31159df71ca4SMatthew G. Knepley } 31165a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 31175a1bb5cfSMatthew G. Knepley } 3118d9917b9dSMatthew G. Knepley 3119d9917b9dSMatthew G. Knepley #undef __FUNCT__ 31201a271a75SMatthew G. Knepley #define __FUNCT__ "DMPlexVecGetClosure_Static" 31211a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Static(PetscSection section, PetscInt numPoints, const PetscInt points[], const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 31221a271a75SMatthew G. Knepley { 31231a271a75SMatthew G. Knepley PetscInt offset = 0, p; 31241a271a75SMatthew G. Knepley PetscErrorCode ierr; 31251a271a75SMatthew G. Knepley 31261a271a75SMatthew G. Knepley PetscFunctionBeginHot; 3127fe02ba77SJed Brown *size = 0; 31281a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 31291a271a75SMatthew G. Knepley const PetscInt point = points[p]; 31301a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 31311a271a75SMatthew G. Knepley PetscInt dof, off, d; 31321a271a75SMatthew G. Knepley const PetscScalar *varr; 31331a271a75SMatthew G. Knepley 31341a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 31351a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 31361a271a75SMatthew G. Knepley varr = &vArray[off]; 31371a271a75SMatthew G. Knepley if (o >= 0) { 31381a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) array[offset] = varr[d]; 31391a271a75SMatthew G. Knepley } else { 31401a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) array[offset] = varr[d]; 31411a271a75SMatthew G. Knepley } 31421a271a75SMatthew G. Knepley } 31431a271a75SMatthew G. Knepley *size = offset; 31441a271a75SMatthew G. Knepley PetscFunctionReturn(0); 31451a271a75SMatthew G. Knepley } 31461a271a75SMatthew G. Knepley 31471a271a75SMatthew G. Knepley #undef __FUNCT__ 31481a271a75SMatthew G. Knepley #define __FUNCT__ "DMPlexVecGetClosure_Fields_Static" 31491a271a75SMatthew 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[]) 31501a271a75SMatthew G. Knepley { 31511a271a75SMatthew G. Knepley PetscInt offset = 0, f; 31521a271a75SMatthew G. Knepley PetscErrorCode ierr; 31531a271a75SMatthew G. Knepley 31541a271a75SMatthew G. Knepley PetscFunctionBeginHot; 3155fe02ba77SJed Brown *size = 0; 31561a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 31571a271a75SMatthew G. Knepley PetscInt fcomp, p; 31581a271a75SMatthew G. Knepley 31591a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 31601a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 31611a271a75SMatthew G. Knepley const PetscInt point = points[p]; 31621a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 31631a271a75SMatthew G. Knepley PetscInt fdof, foff, d, c; 31641a271a75SMatthew G. Knepley const PetscScalar *varr; 31651a271a75SMatthew G. Knepley 31661a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 31671a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 31681a271a75SMatthew G. Knepley varr = &vArray[foff]; 31691a271a75SMatthew G. Knepley if (o >= 0) { 31701a271a75SMatthew G. Knepley for (d = 0; d < fdof; ++d, ++offset) array[offset] = varr[d]; 31711a271a75SMatthew G. Knepley } else { 31721a271a75SMatthew G. Knepley for (d = fdof/fcomp-1; d >= 0; --d) { 31731a271a75SMatthew G. Knepley for (c = 0; c < fcomp; ++c, ++offset) { 31741a271a75SMatthew G. Knepley array[offset] = varr[d*fcomp+c]; 31751a271a75SMatthew G. Knepley } 31761a271a75SMatthew G. Knepley } 31771a271a75SMatthew G. Knepley } 31781a271a75SMatthew G. Knepley } 31791a271a75SMatthew G. Knepley } 31801a271a75SMatthew G. Knepley *size = offset; 31811a271a75SMatthew G. Knepley PetscFunctionReturn(0); 31821a271a75SMatthew G. Knepley } 31831a271a75SMatthew G. Knepley 31841a271a75SMatthew G. Knepley #undef __FUNCT__ 3185552f7358SJed Brown #define __FUNCT__ "DMPlexVecGetClosure" 3186552f7358SJed Brown /*@C 3187552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 3188552f7358SJed Brown 3189552f7358SJed Brown Not collective 3190552f7358SJed Brown 3191552f7358SJed Brown Input Parameters: 3192552f7358SJed Brown + dm - The DM 3193552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 3194552f7358SJed Brown . v - The local vector 3195552f7358SJed Brown - point - The sieve point in the DM 3196552f7358SJed Brown 3197552f7358SJed Brown Output Parameters: 3198552f7358SJed Brown + csize - The number of values in the closure, or NULL 3199552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 3200552f7358SJed Brown 3201552f7358SJed Brown Fortran Notes: 3202552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 3203552f7358SJed Brown include petsc.h90 in your code. 3204552f7358SJed Brown 3205552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 3206552f7358SJed Brown 3207552f7358SJed Brown Level: intermediate 3208552f7358SJed Brown 3209552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 3210552f7358SJed Brown @*/ 3211552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3212552f7358SJed Brown { 3213552f7358SJed Brown PetscSection clSection; 3214d9917b9dSMatthew G. Knepley IS clPoints; 3215552f7358SJed Brown PetscScalar *array, *vArray; 3216552f7358SJed Brown PetscInt *points = NULL; 3217d9917b9dSMatthew G. Knepley const PetscInt *clp; 32181a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, size; 3219552f7358SJed Brown PetscErrorCode ierr; 3220552f7358SJed Brown 3221d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 3222552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3223552f7358SJed Brown if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 32241a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 32251a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 3226552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3227552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 3228552f7358SJed Brown if (depth == 1 && numFields < 2) { 32291a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 3230552f7358SJed Brown PetscFunctionReturn(0); 3231552f7358SJed Brown } 32321a271a75SMatthew G. Knepley /* Get points */ 3233d9917b9dSMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 3234d9917b9dSMatthew G. Knepley if (!clPoints) { 32351a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, q; 3236552f7358SJed Brown 32371a271a75SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3238552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 3239552f7358SJed Brown /* Compress out points not in the section */ 3240552f7358SJed Brown for (p = 0, q = 0; p < numPoints*2; p += 2) { 3241552f7358SJed Brown if ((points[p] >= pStart) && (points[p] < pEnd)) { 3242552f7358SJed Brown points[q*2] = points[p]; 3243552f7358SJed Brown points[q*2+1] = points[p+1]; 3244552f7358SJed Brown ++q; 3245552f7358SJed Brown } 3246552f7358SJed Brown } 3247552f7358SJed Brown numPoints = q; 3248d9917b9dSMatthew G. Knepley } else { 3249d9917b9dSMatthew G. Knepley PetscInt dof, off; 3250552f7358SJed Brown 3251d9917b9dSMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 3252d9917b9dSMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 3253d9917b9dSMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 32541a271a75SMatthew G. Knepley numPoints = dof/2; 3255d9917b9dSMatthew G. Knepley points = (PetscInt *) &clp[off]; 3256552f7358SJed Brown } 32571a271a75SMatthew G. Knepley /* Get array */ 3258552f7358SJed Brown if (!values || !*values) { 32591a271a75SMatthew G. Knepley PetscInt asize = 0, dof, p; 3260552f7358SJed Brown 32611a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3262552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 32631a271a75SMatthew G. Knepley asize += dof; 3264552f7358SJed Brown } 3265bd6c0d32SMatthew G. Knepley if (!values) { 3266d9917b9dSMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 32671a271a75SMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 32681a271a75SMatthew G. Knepley if (csize) *csize = asize; 3269bd6c0d32SMatthew G. Knepley PetscFunctionReturn(0); 3270bd6c0d32SMatthew G. Knepley } 32711a271a75SMatthew G. Knepley ierr = DMGetWorkArray(dm, asize, PETSC_SCALAR, &array);CHKERRQ(ierr); 3272d0f6b257SMatthew G. Knepley } else { 3273d0f6b257SMatthew G. Knepley array = *values; 3274d0f6b257SMatthew G. Knepley } 3275552f7358SJed Brown ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 32761a271a75SMatthew G. Knepley /* Get values */ 3277ef90cfe2SMatthew G. Knepley if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(section, numPoints, points, numFields, vArray, &size, array);CHKERRQ(ierr);} 32781a271a75SMatthew G. Knepley else {ierr = DMPlexVecGetClosure_Static(section, numPoints, points, vArray, &size, array);CHKERRQ(ierr);} 32791a271a75SMatthew G. Knepley /* Cleanup points */ 32801a271a75SMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 32811a271a75SMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 32821a271a75SMatthew G. Knepley /* Cleanup array */ 3283552f7358SJed Brown ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 3284d0f6b257SMatthew G. Knepley if (!*values) { 3285552f7358SJed Brown if (csize) *csize = size; 3286552f7358SJed Brown *values = array; 3287d0f6b257SMatthew G. Knepley } else { 3288d0f6b257SMatthew G. Knepley if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %d < actual size %d", *csize, size); 3289d0f6b257SMatthew G. Knepley *csize = size; 3290d0f6b257SMatthew G. Knepley } 3291552f7358SJed Brown PetscFunctionReturn(0); 3292552f7358SJed Brown } 3293552f7358SJed Brown 3294552f7358SJed Brown #undef __FUNCT__ 3295552f7358SJed Brown #define __FUNCT__ "DMPlexVecRestoreClosure" 3296552f7358SJed Brown /*@C 3297552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 3298552f7358SJed Brown 3299552f7358SJed Brown Not collective 3300552f7358SJed Brown 3301552f7358SJed Brown Input Parameters: 3302552f7358SJed Brown + dm - The DM 33030298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 3304552f7358SJed Brown . v - The local vector 3305552f7358SJed Brown . point - The sieve point in the DM 33060298fd71SBarry Smith . csize - The number of values in the closure, or NULL 3307552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 3308552f7358SJed Brown 33093813dfbdSMatthew G Knepley Fortran Notes: 33103813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 33113813dfbdSMatthew G Knepley include petsc.h90 in your code. 33123813dfbdSMatthew G Knepley 33133813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 33143813dfbdSMatthew G Knepley 3315552f7358SJed Brown Level: intermediate 3316552f7358SJed Brown 3317552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 3318552f7358SJed Brown @*/ 33197c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3320a6dfd86eSKarl Rupp { 3321552f7358SJed Brown PetscInt size = 0; 3322552f7358SJed Brown PetscErrorCode ierr; 3323552f7358SJed Brown 3324552f7358SJed Brown PetscFunctionBegin; 3325552f7358SJed Brown /* Should work without recalculating size */ 3326552f7358SJed Brown ierr = DMRestoreWorkArray(dm, size, PETSC_SCALAR, (void*) values);CHKERRQ(ierr); 3327552f7358SJed Brown PetscFunctionReturn(0); 3328552f7358SJed Brown } 3329552f7358SJed Brown 3330552f7358SJed Brown PETSC_STATIC_INLINE void add (PetscScalar *x, PetscScalar y) {*x += y;} 3331552f7358SJed Brown PETSC_STATIC_INLINE void insert(PetscScalar *x, PetscScalar y) {*x = y;} 3332552f7358SJed Brown 3333552f7358SJed Brown #undef __FUNCT__ 3334552f7358SJed Brown #define __FUNCT__ "updatePoint_private" 33351a271a75SMatthew 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[]) 3336552f7358SJed Brown { 3337552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 3338552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 3339552f7358SJed Brown PetscScalar *a; 3340552f7358SJed Brown PetscInt off, cind = 0, k; 3341552f7358SJed Brown PetscErrorCode ierr; 3342552f7358SJed Brown 3343552f7358SJed Brown PetscFunctionBegin; 3344552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 3345552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 3346552f7358SJed Brown a = &array[off]; 3347552f7358SJed Brown if (!cdof || setBC) { 3348552f7358SJed Brown if (orientation >= 0) { 3349552f7358SJed Brown for (k = 0; k < dof; ++k) { 3350552f7358SJed Brown fuse(&a[k], values[k]); 3351552f7358SJed Brown } 3352552f7358SJed Brown } else { 3353552f7358SJed Brown for (k = 0; k < dof; ++k) { 3354552f7358SJed Brown fuse(&a[k], values[dof-k-1]); 3355552f7358SJed Brown } 3356552f7358SJed Brown } 3357552f7358SJed Brown } else { 3358552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 3359552f7358SJed Brown if (orientation >= 0) { 3360552f7358SJed Brown for (k = 0; k < dof; ++k) { 3361552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3362552f7358SJed Brown fuse(&a[k], values[k]); 3363552f7358SJed Brown } 3364552f7358SJed Brown } else { 3365552f7358SJed Brown for (k = 0; k < dof; ++k) { 3366552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3367552f7358SJed Brown fuse(&a[k], values[dof-k-1]); 3368552f7358SJed Brown } 3369552f7358SJed Brown } 3370552f7358SJed Brown } 3371552f7358SJed Brown PetscFunctionReturn(0); 3372552f7358SJed Brown } 3373552f7358SJed Brown 3374552f7358SJed Brown #undef __FUNCT__ 3375a5e93ea8SMatthew G. Knepley #define __FUNCT__ "updatePointBC_private" 33761a271a75SMatthew 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[]) 3377a5e93ea8SMatthew G. Knepley { 3378a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 3379a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 3380a5e93ea8SMatthew G. Knepley PetscScalar *a; 3381a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 3382a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 3383a5e93ea8SMatthew G. Knepley 3384a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 3385a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 3386a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 3387a5e93ea8SMatthew G. Knepley a = &array[off]; 3388a5e93ea8SMatthew G. Knepley if (cdof) { 3389a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 3390a5e93ea8SMatthew G. Knepley if (orientation >= 0) { 3391a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3392a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 3393a5e93ea8SMatthew G. Knepley fuse(&a[k], values[k]); 3394a5e93ea8SMatthew G. Knepley ++cind; 3395a5e93ea8SMatthew G. Knepley } 3396a5e93ea8SMatthew G. Knepley } 3397a5e93ea8SMatthew G. Knepley } else { 3398a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3399a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 3400a5e93ea8SMatthew G. Knepley fuse(&a[k], values[dof-k-1]); 3401a5e93ea8SMatthew G. Knepley ++cind; 3402a5e93ea8SMatthew G. Knepley } 3403a5e93ea8SMatthew G. Knepley } 3404a5e93ea8SMatthew G. Knepley } 3405a5e93ea8SMatthew G. Knepley } 3406a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 3407a5e93ea8SMatthew G. Knepley } 3408a5e93ea8SMatthew G. Knepley 3409a5e93ea8SMatthew G. Knepley #undef __FUNCT__ 3410552f7358SJed Brown #define __FUNCT__ "updatePointFields_private" 34111a271a75SMatthew 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[]) 3412a6dfd86eSKarl Rupp { 3413552f7358SJed Brown PetscScalar *a; 34141a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 34151a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 34161a271a75SMatthew G. Knepley PetscInt cind = 0, k, c; 3417552f7358SJed Brown PetscErrorCode ierr; 3418552f7358SJed Brown 3419552f7358SJed Brown PetscFunctionBegin; 3420552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 3421552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 34221a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 34231a271a75SMatthew G. Knepley a = &array[foff]; 3424552f7358SJed Brown if (!fcdof || setBC) { 34251a271a75SMatthew G. Knepley if (o >= 0) { 34261a271a75SMatthew G. Knepley for (k = 0; k < fdof; ++k) fuse(&a[k], values[foffset+k]); 3427552f7358SJed Brown } else { 3428552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 3429552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 34301a271a75SMatthew G. Knepley fuse(&a[(fdof/fcomp-1-k)*fcomp+c], values[foffset+k*fcomp+c]); 3431552f7358SJed Brown } 3432552f7358SJed Brown } 3433552f7358SJed Brown } 3434552f7358SJed Brown } else { 3435552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 34361a271a75SMatthew G. Knepley if (o >= 0) { 3437552f7358SJed Brown for (k = 0; k < fdof; ++k) { 3438552f7358SJed Brown if ((cind < fcdof) && (k == fcdofs[cind])) {++cind; continue;} 34391a271a75SMatthew G. Knepley fuse(&a[k], values[foffset+k]); 3440552f7358SJed Brown } 3441552f7358SJed Brown } else { 3442552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 3443552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 3444552f7358SJed Brown if ((cind < fcdof) && (k*fcomp+c == fcdofs[cind])) {++cind; continue;} 34451a271a75SMatthew G. Knepley fuse(&a[(fdof/fcomp-1-k)*fcomp+c], values[foffset+k*fcomp+c]); 3446552f7358SJed Brown } 3447552f7358SJed Brown } 3448552f7358SJed Brown } 3449552f7358SJed Brown } 34501a271a75SMatthew G. Knepley *offset += fdof; 3451552f7358SJed Brown PetscFunctionReturn(0); 3452552f7358SJed Brown } 3453552f7358SJed Brown 3454552f7358SJed Brown #undef __FUNCT__ 3455a5e93ea8SMatthew G. Knepley #define __FUNCT__ "updatePointFieldsBC_private" 34561a271a75SMatthew 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[]) 3457a5e93ea8SMatthew G. Knepley { 3458a5e93ea8SMatthew G. Knepley PetscScalar *a; 34591a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 34601a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 34611a271a75SMatthew G. Knepley PetscInt cind = 0, k, c; 3462a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 3463a5e93ea8SMatthew G. Knepley 3464a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 3465a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 3466a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 34671a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 34681a271a75SMatthew G. Knepley a = &array[foff]; 3469a5e93ea8SMatthew G. Knepley if (fcdof) { 3470a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 34711a271a75SMatthew G. Knepley if (o >= 0) { 3472a5e93ea8SMatthew G. Knepley for (k = 0; k < fdof; ++k) { 3473a5e93ea8SMatthew G. Knepley if ((cind < fcdof) && (k == fcdofs[cind])) { 34741a271a75SMatthew G. Knepley fuse(&a[k], values[foffset+k]); 3475a5e93ea8SMatthew G. Knepley ++cind; 3476a5e93ea8SMatthew G. Knepley } 3477a5e93ea8SMatthew G. Knepley } 3478a5e93ea8SMatthew G. Knepley } else { 3479a5e93ea8SMatthew G. Knepley for (k = fdof/fcomp-1; k >= 0; --k) { 3480a5e93ea8SMatthew G. Knepley for (c = 0; c < fcomp; ++c) { 3481a5e93ea8SMatthew G. Knepley if ((cind < fcdof) && (k*fcomp+c == fcdofs[cind])) { 34821a271a75SMatthew G. Knepley fuse(&a[(fdof/fcomp-1-k)*fcomp+c], values[foffset+k*fcomp+c]); 3483a5e93ea8SMatthew G. Knepley ++cind; 3484a5e93ea8SMatthew G. Knepley } 3485a5e93ea8SMatthew G. Knepley } 3486a5e93ea8SMatthew G. Knepley } 3487a5e93ea8SMatthew G. Knepley } 3488a5e93ea8SMatthew G. Knepley } 34891a271a75SMatthew G. Knepley *offset += fdof; 3490a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 3491a5e93ea8SMatthew G. Knepley } 3492a5e93ea8SMatthew G. Knepley 3493a5e93ea8SMatthew G. Knepley #undef __FUNCT__ 34941b406b76SMatthew G. Knepley #define __FUNCT__ "DMPlexVecSetClosure_Static" 34951a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecSetClosure_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 3496a6dfd86eSKarl Rupp { 3497552f7358SJed Brown PetscScalar *array; 34981b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 34991b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 3500552f7358SJed Brown PetscErrorCode ierr; 3501552f7358SJed Brown 35021b406b76SMatthew G. Knepley PetscFunctionBeginHot; 3503b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3504b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 3505b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3506b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 3507b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 3508b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 3509b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 3510b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 3511b6ebb6e6SMatthew G. Knepley 3512b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 3513b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 3514b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 3515b6ebb6e6SMatthew G. Knepley { 3516b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 3517b6ebb6e6SMatthew G. Knepley PetscScalar *a; 3518b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 3519b6ebb6e6SMatthew G. Knepley 3520b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 3521b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 3522b6ebb6e6SMatthew G. Knepley a = &array[coff]; 3523b6ebb6e6SMatthew G. Knepley if (!cdof) { 3524b6ebb6e6SMatthew G. Knepley if (o >= 0) { 3525b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3526b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 3527b6ebb6e6SMatthew G. Knepley } 3528b6ebb6e6SMatthew G. Knepley } else { 3529b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3530b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 3531b6ebb6e6SMatthew G. Knepley } 3532b6ebb6e6SMatthew G. Knepley } 3533b6ebb6e6SMatthew G. Knepley } else { 3534b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 3535b6ebb6e6SMatthew G. Knepley if (o >= 0) { 3536b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3537b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3538b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 3539b6ebb6e6SMatthew G. Knepley } 3540b6ebb6e6SMatthew G. Knepley } else { 3541b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 3542b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 3543b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 3544b6ebb6e6SMatthew G. Knepley } 3545b6ebb6e6SMatthew G. Knepley } 3546b6ebb6e6SMatthew G. Knepley } 3547b6ebb6e6SMatthew G. Knepley } 3548b6ebb6e6SMatthew G. Knepley } 3549b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 3550b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 3551b6ebb6e6SMatthew G. Knepley } 35521b406b76SMatthew G. Knepley 35531b406b76SMatthew G. Knepley #undef __FUNCT__ 35541b406b76SMatthew G. Knepley #define __FUNCT__ "DMPlexVecSetClosure" 35551b406b76SMatthew G. Knepley /*@C 35561b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 35571b406b76SMatthew G. Knepley 35581b406b76SMatthew G. Knepley Not collective 35591b406b76SMatthew G. Knepley 35601b406b76SMatthew G. Knepley Input Parameters: 35611b406b76SMatthew G. Knepley + dm - The DM 35621b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 35631b406b76SMatthew G. Knepley . v - The local vector 35641b406b76SMatthew G. Knepley . point - The sieve point in the DM 35651b406b76SMatthew G. Knepley . values - The array of values 35661b406b76SMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 35671b406b76SMatthew G. Knepley 35681b406b76SMatthew G. Knepley Fortran Notes: 35691b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 35701b406b76SMatthew G. Knepley 35711b406b76SMatthew G. Knepley Level: intermediate 35721b406b76SMatthew G. Knepley 35731b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 35741b406b76SMatthew G. Knepley @*/ 35751b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 35761b406b76SMatthew G. Knepley { 35771b406b76SMatthew G. Knepley PetscSection clSection; 35781b406b76SMatthew G. Knepley IS clPoints; 35791b406b76SMatthew G. Knepley PetscScalar *array; 35801b406b76SMatthew G. Knepley PetscInt *points = NULL; 35811b406b76SMatthew G. Knepley const PetscInt *clp; 35821a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, p; 35831b406b76SMatthew G. Knepley PetscErrorCode ierr; 35841b406b76SMatthew G. Knepley 35851a271a75SMatthew G. Knepley PetscFunctionBeginHot; 35861b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 35871b406b76SMatthew G. Knepley if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 35881a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 35891a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 35901b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 35911b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 35921b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 35931a271a75SMatthew G. Knepley ierr = DMPlexVecSetClosure_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 35941b406b76SMatthew G. Knepley PetscFunctionReturn(0); 35951b406b76SMatthew G. Knepley } 35961a271a75SMatthew G. Knepley /* Get points */ 35971b406b76SMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 35981b406b76SMatthew G. Knepley if (!clPoints) { 35991a271a75SMatthew G. Knepley PetscInt pStart, pEnd, q; 36001a271a75SMatthew G. Knepley 36011a271a75SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3602552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 3603552f7358SJed Brown /* Compress out points not in the section */ 3604552f7358SJed Brown for (p = 0, q = 0; p < numPoints*2; p += 2) { 3605552f7358SJed Brown if ((points[p] >= pStart) && (points[p] < pEnd)) { 3606552f7358SJed Brown points[q*2] = points[p]; 3607552f7358SJed Brown points[q*2+1] = points[p+1]; 3608552f7358SJed Brown ++q; 3609552f7358SJed Brown } 3610552f7358SJed Brown } 3611552f7358SJed Brown numPoints = q; 36121b406b76SMatthew G. Knepley } else { 36131b406b76SMatthew G. Knepley PetscInt dof, off; 3614552f7358SJed Brown 36151b406b76SMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 36161b406b76SMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 36171b406b76SMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 36181a271a75SMatthew G. Knepley numPoints = dof/2; 36191b406b76SMatthew G. Knepley points = (PetscInt *) &clp[off]; 3620552f7358SJed Brown } 36211a271a75SMatthew G. Knepley /* Get array */ 3622552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 36231a271a75SMatthew G. Knepley /* Get values */ 3624ef90cfe2SMatthew G. Knepley if (numFields > 0) { 36251a271a75SMatthew G. Knepley PetscInt offset = 0, fcomp, f; 3626552f7358SJed Brown for (f = 0; f < numFields; ++f) { 36271a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 3628552f7358SJed Brown switch (mode) { 3629552f7358SJed Brown case INSERT_VALUES: 3630552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 36311a271a75SMatthew G. Knepley const PetscInt point = points[p]; 36321a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 36331a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_FALSE, values, &offset, array); 3634552f7358SJed Brown } break; 3635552f7358SJed Brown case INSERT_ALL_VALUES: 3636552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 36371a271a75SMatthew G. Knepley const PetscInt point = points[p]; 36381a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 36391a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_TRUE, values, &offset, array); 3640552f7358SJed Brown } break; 3641a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 3642a5e93ea8SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 36431a271a75SMatthew G. Knepley const PetscInt point = points[p]; 36441a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 36451a271a75SMatthew G. Knepley updatePointFieldsBC_private(section, point, o, f, fcomp, insert, values, &offset, array); 3646a5e93ea8SMatthew G. Knepley } break; 3647552f7358SJed Brown case ADD_VALUES: 3648552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 36491a271a75SMatthew G. Knepley const PetscInt point = points[p]; 36501a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 36511a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_FALSE, values, &offset, array); 3652552f7358SJed Brown } break; 3653552f7358SJed Brown case ADD_ALL_VALUES: 3654552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 36551a271a75SMatthew G. Knepley const PetscInt point = points[p]; 36561a271a75SMatthew G. Knepley const PetscInt o = points[p+1]; 36571a271a75SMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_TRUE, values, &offset, array); 3658552f7358SJed Brown } break; 3659552f7358SJed Brown default: 366082f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %D", mode); 3661552f7358SJed Brown } 36621a271a75SMatthew G. Knepley } 3663552f7358SJed Brown } else { 36641a271a75SMatthew G. Knepley PetscInt dof, off; 36651a271a75SMatthew G. Knepley 3666552f7358SJed Brown switch (mode) { 3667552f7358SJed Brown case INSERT_VALUES: 3668552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3669552f7358SJed Brown PetscInt o = points[p+1]; 3670552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3671552f7358SJed Brown updatePoint_private(section, points[p], dof, insert, PETSC_FALSE, o, &values[off], array); 3672552f7358SJed Brown } break; 3673552f7358SJed Brown case INSERT_ALL_VALUES: 3674552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3675552f7358SJed Brown PetscInt o = points[p+1]; 3676552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3677552f7358SJed Brown updatePoint_private(section, points[p], dof, insert, PETSC_TRUE, o, &values[off], array); 3678552f7358SJed Brown } break; 3679a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 3680a5e93ea8SMatthew G. Knepley for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3681a5e93ea8SMatthew G. Knepley PetscInt o = points[p+1]; 3682a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3683a5e93ea8SMatthew G. Knepley updatePointBC_private(section, points[p], dof, insert, o, &values[off], array); 3684a5e93ea8SMatthew G. Knepley } break; 3685552f7358SJed Brown case ADD_VALUES: 3686552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3687552f7358SJed Brown PetscInt o = points[p+1]; 3688552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3689552f7358SJed Brown updatePoint_private(section, points[p], dof, add, PETSC_FALSE, o, &values[off], array); 3690552f7358SJed Brown } break; 3691552f7358SJed Brown case ADD_ALL_VALUES: 3692552f7358SJed Brown for (p = 0, off = 0; p < numPoints*2; p += 2, off += dof) { 3693552f7358SJed Brown PetscInt o = points[p+1]; 3694552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 3695552f7358SJed Brown updatePoint_private(section, points[p], dof, add, PETSC_TRUE, o, &values[off], array); 3696552f7358SJed Brown } break; 3697552f7358SJed Brown default: 369882f516ccSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %D", mode); 3699552f7358SJed Brown } 3700552f7358SJed Brown } 37011a271a75SMatthew G. Knepley /* Cleanup points */ 37021a271a75SMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 37031a271a75SMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 37041a271a75SMatthew G. Knepley /* Cleanup array */ 3705552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 3706552f7358SJed Brown PetscFunctionReturn(0); 3707552f7358SJed Brown } 3708552f7358SJed Brown 3709552f7358SJed Brown #undef __FUNCT__ 3710e07394fbSMatthew G. Knepley #define __FUNCT__ "DMPlexVecSetFieldClosure_Internal" 3711e07394fbSMatthew G. Knepley PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM dm, PetscSection section, Vec v, PetscBool fieldActive[], PetscInt point, const PetscScalar values[], InsertMode mode) 3712e07394fbSMatthew G. Knepley { 3713e07394fbSMatthew G. Knepley PetscSection clSection; 3714e07394fbSMatthew G. Knepley IS clPoints; 3715e07394fbSMatthew G. Knepley PetscScalar *array; 3716e07394fbSMatthew G. Knepley PetscInt *points = NULL; 3717e07394fbSMatthew G. Knepley const PetscInt *clp; 3718e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 3719e07394fbSMatthew G. Knepley PetscInt offset = 0, fcomp, f; 3720e07394fbSMatthew G. Knepley PetscErrorCode ierr; 3721e07394fbSMatthew G. Knepley 3722e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 3723e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3724e07394fbSMatthew G. Knepley if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 3725e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 3726e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 3727e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 3728e07394fbSMatthew G. Knepley /* Get points */ 3729e07394fbSMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 3730e07394fbSMatthew G. Knepley if (!clPoints) { 3731e07394fbSMatthew G. Knepley PetscInt pStart, pEnd, q; 3732e07394fbSMatthew G. Knepley 3733e07394fbSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3734e07394fbSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 3735e07394fbSMatthew G. Knepley /* Compress out points not in the section */ 3736e07394fbSMatthew G. Knepley for (p = 0, q = 0; p < numPoints*2; p += 2) { 3737e07394fbSMatthew G. Knepley if ((points[p] >= pStart) && (points[p] < pEnd)) { 3738e07394fbSMatthew G. Knepley points[q*2] = points[p]; 3739e07394fbSMatthew G. Knepley points[q*2+1] = points[p+1]; 3740e07394fbSMatthew G. Knepley ++q; 3741e07394fbSMatthew G. Knepley } 3742e07394fbSMatthew G. Knepley } 3743e07394fbSMatthew G. Knepley numPoints = q; 3744e07394fbSMatthew G. Knepley } else { 3745e07394fbSMatthew G. Knepley PetscInt dof, off; 3746e07394fbSMatthew G. Knepley 3747e07394fbSMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 3748e07394fbSMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 3749e07394fbSMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 3750e07394fbSMatthew G. Knepley numPoints = dof/2; 3751e07394fbSMatthew G. Knepley points = (PetscInt *) &clp[off]; 3752e07394fbSMatthew G. Knepley } 3753e07394fbSMatthew G. Knepley /* Get array */ 3754e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 3755e07394fbSMatthew G. Knepley /* Get values */ 3756e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 3757e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 3758e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 3759e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3760e07394fbSMatthew G. Knepley PetscInt fdof; 3761e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 3762e07394fbSMatthew G. Knepley offset += fdof; 3763e07394fbSMatthew G. Knepley } 3764e07394fbSMatthew G. Knepley continue; 3765e07394fbSMatthew G. Knepley } 3766e07394fbSMatthew G. Knepley switch (mode) { 3767e07394fbSMatthew G. Knepley case INSERT_VALUES: 3768e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3769e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3770e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3771e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_FALSE, values, &offset, array); 3772e07394fbSMatthew G. Knepley } break; 3773e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 3774e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3775e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3776e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3777e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, insert, PETSC_TRUE, values, &offset, array); 3778e07394fbSMatthew G. Knepley } break; 3779e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 3780e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3781e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3782e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3783e07394fbSMatthew G. Knepley updatePointFieldsBC_private(section, point, o, f, fcomp, insert, values, &offset, array); 3784e07394fbSMatthew G. Knepley } break; 3785e07394fbSMatthew G. Knepley case ADD_VALUES: 3786e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3787e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3788e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3789e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_FALSE, values, &offset, array); 3790e07394fbSMatthew G. Knepley } break; 3791e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 3792e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 3793e07394fbSMatthew G. Knepley const PetscInt point = points[p]; 3794e07394fbSMatthew G. Knepley const PetscInt o = points[p+1]; 3795e07394fbSMatthew G. Knepley updatePointFields_private(section, point, o, f, fcomp, add, PETSC_TRUE, values, &offset, array); 3796e07394fbSMatthew G. Knepley } break; 3797e07394fbSMatthew G. Knepley default: 3798e07394fbSMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %D", mode); 3799e07394fbSMatthew G. Knepley } 3800e07394fbSMatthew G. Knepley } 3801e07394fbSMatthew G. Knepley /* Cleanup points */ 3802e07394fbSMatthew G. Knepley if (!clPoints) {ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr);} 3803e07394fbSMatthew G. Knepley else {ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr);} 3804e07394fbSMatthew G. Knepley /* Cleanup array */ 3805e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 3806e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 3807e07394fbSMatthew G. Knepley } 3808e07394fbSMatthew G. Knepley 3809e07394fbSMatthew G. Knepley #undef __FUNCT__ 3810552f7358SJed Brown #define __FUNCT__ "DMPlexPrintMatSetValues" 3811b0ecff45SMatthew G. Knepley PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 3812552f7358SJed Brown { 3813552f7358SJed Brown PetscMPIInt rank; 3814552f7358SJed Brown PetscInt i, j; 3815552f7358SJed Brown PetscErrorCode ierr; 3816552f7358SJed Brown 3817552f7358SJed Brown PetscFunctionBegin; 381882f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr); 381977a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "[%D]mat for sieve point %D\n", rank, point);CHKERRQ(ierr); 3820b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%D]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 3821b0ecff45SMatthew G. Knepley for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%D]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 3822b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 3823b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 382477a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "[%D]", rank);CHKERRQ(ierr); 3825b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 3826519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 38277eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 3828552f7358SJed Brown #else 3829b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 3830552f7358SJed Brown #endif 3831552f7358SJed Brown } 383277a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 3833552f7358SJed Brown } 3834552f7358SJed Brown PetscFunctionReturn(0); 3835552f7358SJed Brown } 3836552f7358SJed Brown 3837552f7358SJed Brown #undef __FUNCT__ 3838552f7358SJed Brown #define __FUNCT__ "indicesPoint_private" 3839552f7358SJed Brown /* . off - The global offset of this point */ 3840e6ccafaeSMatthew G Knepley PetscErrorCode indicesPoint_private(PetscSection section, PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, PetscInt orientation, PetscInt indices[]) 3841a6dfd86eSKarl Rupp { 3842e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 3843552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 3844552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 3845552f7358SJed Brown PetscInt cind = 0, k; 3846552f7358SJed Brown PetscErrorCode ierr; 3847552f7358SJed Brown 3848552f7358SJed Brown PetscFunctionBegin; 3849552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 3850552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 3851552f7358SJed Brown if (!cdof || setBC) { 3852552f7358SJed Brown if (orientation >= 0) { 3853e6ccafaeSMatthew G Knepley for (k = 0; k < dof; ++k) indices[*loff+k] = off+k; 3854552f7358SJed Brown } else { 3855e6ccafaeSMatthew G Knepley for (k = 0; k < dof; ++k) indices[*loff+dof-k-1] = off+k; 3856552f7358SJed Brown } 3857552f7358SJed Brown } else { 3858552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 3859552f7358SJed Brown if (orientation >= 0) { 3860552f7358SJed Brown for (k = 0; k < dof; ++k) { 3861552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) { 3862552f7358SJed Brown /* Insert check for returning constrained indices */ 3863e6ccafaeSMatthew G Knepley indices[*loff+k] = -(off+k+1); 3864552f7358SJed Brown ++cind; 3865552f7358SJed Brown } else { 3866e6ccafaeSMatthew G Knepley indices[*loff+k] = off+k-cind; 3867552f7358SJed Brown } 3868552f7358SJed Brown } 3869552f7358SJed Brown } else { 3870552f7358SJed Brown for (k = 0; k < dof; ++k) { 3871552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) { 3872552f7358SJed Brown /* Insert check for returning constrained indices */ 3873e6ccafaeSMatthew G Knepley indices[*loff+dof-k-1] = -(off+k+1); 3874552f7358SJed Brown ++cind; 3875552f7358SJed Brown } else { 3876e6ccafaeSMatthew G Knepley indices[*loff+dof-k-1] = off+k-cind; 3877552f7358SJed Brown } 3878552f7358SJed Brown } 3879552f7358SJed Brown } 3880552f7358SJed Brown } 3881e6ccafaeSMatthew G Knepley *loff += dof; 3882552f7358SJed Brown PetscFunctionReturn(0); 3883552f7358SJed Brown } 3884552f7358SJed Brown 3885552f7358SJed Brown #undef __FUNCT__ 3886552f7358SJed Brown #define __FUNCT__ "indicesPointFields_private" 3887552f7358SJed Brown /* . off - The global offset of this point */ 3888a6dfd86eSKarl Rupp PetscErrorCode indicesPointFields_private(PetscSection section, PetscInt point, PetscInt off, PetscInt foffs[], PetscBool setBC, PetscInt orientation, PetscInt indices[]) 3889a6dfd86eSKarl Rupp { 3890552f7358SJed Brown PetscInt numFields, foff, f; 3891552f7358SJed Brown PetscErrorCode ierr; 3892552f7358SJed Brown 3893552f7358SJed Brown PetscFunctionBegin; 3894552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 3895552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 3896552f7358SJed Brown PetscInt fdof, fcomp, cfdof; 3897552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 3898552f7358SJed Brown PetscInt cind = 0, k, c; 3899552f7358SJed Brown 3900552f7358SJed Brown ierr = PetscSectionGetFieldComponents(section, f, &fcomp);CHKERRQ(ierr); 3901552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 3902552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 3903552f7358SJed Brown if (!cfdof || setBC) { 3904552f7358SJed Brown if (orientation >= 0) { 39050d644c17SKarl Rupp for (k = 0; k < fdof; ++k) indices[foffs[f]+k] = off+foff+k; 3906552f7358SJed Brown } else { 3907552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 3908552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 3909552f7358SJed Brown indices[foffs[f]+k*fcomp+c] = off+foff+(fdof/fcomp-1-k)*fcomp+c; 3910552f7358SJed Brown } 3911552f7358SJed Brown } 3912552f7358SJed Brown } 3913552f7358SJed Brown } else { 3914552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 3915552f7358SJed Brown if (orientation >= 0) { 3916552f7358SJed Brown for (k = 0; k < fdof; ++k) { 3917552f7358SJed Brown if ((cind < cfdof) && (k == fcdofs[cind])) { 3918552f7358SJed Brown indices[foffs[f]+k] = -(off+foff+k+1); 3919552f7358SJed Brown ++cind; 3920552f7358SJed Brown } else { 3921552f7358SJed Brown indices[foffs[f]+k] = off+foff+k-cind; 3922552f7358SJed Brown } 3923552f7358SJed Brown } 3924552f7358SJed Brown } else { 3925552f7358SJed Brown for (k = fdof/fcomp-1; k >= 0; --k) { 3926552f7358SJed Brown for (c = 0; c < fcomp; ++c) { 3927552f7358SJed Brown if ((cind < cfdof) && ((fdof/fcomp-1-k)*fcomp+c == fcdofs[cind])) { 3928552f7358SJed Brown indices[foffs[f]+k*fcomp+c] = -(off+foff+(fdof/fcomp-1-k)*fcomp+c+1); 3929552f7358SJed Brown ++cind; 3930552f7358SJed Brown } else { 3931552f7358SJed Brown indices[foffs[f]+k*fcomp+c] = off+foff+(fdof/fcomp-1-k)*fcomp+c-cind; 3932552f7358SJed Brown } 3933552f7358SJed Brown } 3934552f7358SJed Brown } 3935552f7358SJed Brown } 3936552f7358SJed Brown } 3937552f7358SJed Brown foff += fdof - cfdof; 3938552f7358SJed Brown foffs[f] += fdof; 3939552f7358SJed Brown } 3940552f7358SJed Brown PetscFunctionReturn(0); 3941552f7358SJed Brown } 3942552f7358SJed Brown 3943552f7358SJed Brown #undef __FUNCT__ 3944f7c74593SToby Isaac #define __FUNCT__ "DMPlexAnchorsModifyMat" 3945f7c74593SToby Isaac static 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[]) 3946d3d1a6afSToby Isaac { 3947d3d1a6afSToby Isaac Mat cMat; 3948d3d1a6afSToby Isaac PetscSection aSec, cSec; 3949d3d1a6afSToby Isaac IS aIS; 3950d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 3951d3d1a6afSToby Isaac const PetscInt *anchors; 3952e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 3953d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 3954d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 3955d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 3956d3d1a6afSToby Isaac PetscInt newOffsets[32]; 3957d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 3958d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 3959d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 3960d3d1a6afSToby Isaac PetscScalar *newValues,*tmpValues; 3961d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 3962d3d1a6afSToby Isaac PetscErrorCode ierr; 3963d3d1a6afSToby Isaac 3964d3d1a6afSToby Isaac PetscFunctionBegin; 3965d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3966d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 3967d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 3968d3d1a6afSToby Isaac 3969a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 3970d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 3971d3d1a6afSToby Isaac if (aSec) { 3972d3d1a6afSToby Isaac ierr = PetscMemzero(newOffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 3973d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 3974d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 3975d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 3976d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 3977d3d1a6afSToby Isaac * into the global matrix anyway) */ 3978d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 3979d3d1a6afSToby Isaac PetscInt b = points[p]; 3980d3d1a6afSToby Isaac PetscInt bDof = 0; 3981d3d1a6afSToby Isaac 3982d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 3983d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 3984d3d1a6afSToby Isaac } 3985d3d1a6afSToby Isaac if (bDof) { 3986d3d1a6afSToby Isaac /* this point is constrained */ 3987d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 3988d3d1a6afSToby Isaac PetscInt bOff, q; 3989d3d1a6afSToby Isaac 3990d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 3991d3d1a6afSToby Isaac newNumPoints += bDof; 3992d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 3993d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 3994d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 3995d3d1a6afSToby Isaac PetscInt aDof; 3996d3d1a6afSToby Isaac 3997d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 3998d3d1a6afSToby Isaac newNumIndices += aDof; 3999d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 4000d3d1a6afSToby Isaac PetscInt fDof; 4001d3d1a6afSToby Isaac 4002d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 4003d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 4004d3d1a6afSToby Isaac } 4005d3d1a6afSToby Isaac } 4006d3d1a6afSToby Isaac } 4007d3d1a6afSToby Isaac else { 4008d3d1a6afSToby Isaac /* this point is not constrained */ 4009d3d1a6afSToby Isaac newNumPoints++; 4010d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&bDof);CHKERRQ(ierr); 4011d3d1a6afSToby Isaac newNumIndices += bDof; 4012d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 4013d3d1a6afSToby Isaac PetscInt fDof; 4014d3d1a6afSToby Isaac 4015d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 4016d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 4017d3d1a6afSToby Isaac } 4018d3d1a6afSToby Isaac } 4019d3d1a6afSToby Isaac } 4020d3d1a6afSToby Isaac } 4021d3d1a6afSToby Isaac if (!anyConstrained) { 4022d3d1a6afSToby Isaac *outNumPoints = 0; 4023d3d1a6afSToby Isaac *outNumIndices = 0; 4024d3d1a6afSToby Isaac *outPoints = NULL; 4025d3d1a6afSToby Isaac *outValues = NULL; 4026d3d1a6afSToby Isaac if (aSec) { 4027d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 4028d3d1a6afSToby Isaac } 4029d3d1a6afSToby Isaac PetscFunctionReturn(0); 4030d3d1a6afSToby Isaac } 4031d3d1a6afSToby Isaac 4032d3d1a6afSToby Isaac for (f = 1; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 4033d3d1a6afSToby Isaac 4034d3d1a6afSToby Isaac if (numFields && newOffsets[numFields] != newNumIndices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", newOffsets[numFields], newNumIndices); 4035d3d1a6afSToby Isaac 4036f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 4037d3d1a6afSToby Isaac 4038d3d1a6afSToby Isaac /* output arrays */ 4039d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,2*newNumPoints,PETSC_INT,&newPoints);CHKERRQ(ierr); 4040d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,PETSC_SCALAR,&newValues);CHKERRQ(ierr); 4041d3d1a6afSToby Isaac 4042d3d1a6afSToby Isaac /* workspaces */ 4043d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,newNumIndices*numIndices,PETSC_SCALAR,&tmpValues);CHKERRQ(ierr); 4044d3d1a6afSToby Isaac if (numFields) { 4045d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4046d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 4047d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints+1,PETSC_INT,&newPointOffsets[f]);CHKERRQ(ierr); 4048d3d1a6afSToby Isaac } 4049d3d1a6afSToby Isaac } 4050d3d1a6afSToby Isaac else { 4051d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 4052d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,numPoints,PETSC_INT,&newPointOffsets[0]);CHKERRQ(ierr); 4053d3d1a6afSToby Isaac } 4054d3d1a6afSToby Isaac 4055d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 4056d3d1a6afSToby Isaac if (numFields) { 4057d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4058d3d1a6afSToby Isaac PetscInt b = points[2*p]; 4059d3d1a6afSToby Isaac PetscInt bDof = 0; 4060d3d1a6afSToby Isaac 4061d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4062d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4063d3d1a6afSToby Isaac } 4064d3d1a6afSToby Isaac if (bDof) { 4065d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4066d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 4067d3d1a6afSToby Isaac 4068d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 4069d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 4070d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4071d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 4072d3d1a6afSToby Isaac PetscInt aFDof; 4073d3d1a6afSToby Isaac 4074d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 4075d3d1a6afSToby Isaac allFDof += aFDof; 4076d3d1a6afSToby Isaac } 4077d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 4078d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 4079d3d1a6afSToby Isaac } 4080d3d1a6afSToby Isaac } 4081d3d1a6afSToby Isaac else { 4082d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4083d3d1a6afSToby Isaac PetscInt fDof; 4084d3d1a6afSToby Isaac 4085d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 4086d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 4087d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 4088d3d1a6afSToby Isaac } 4089d3d1a6afSToby Isaac } 4090d3d1a6afSToby Isaac } 4091d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4092d3d1a6afSToby Isaac newPointOffsets[f][0] = 0; 4093d3d1a6afSToby Isaac pointMatOffsets[f][0] = 0; 4094d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4095d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 4096d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 4097d3d1a6afSToby Isaac } 4098d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],PETSC_SCALAR,&pointMat[f]);CHKERRQ(ierr); 4099d3d1a6afSToby Isaac } 4100d3d1a6afSToby Isaac } 4101d3d1a6afSToby Isaac else { 4102d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4103d3d1a6afSToby Isaac PetscInt b = points[2*p]; 4104d3d1a6afSToby Isaac PetscInt bDof = 0; 4105d3d1a6afSToby Isaac 4106d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4107d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4108d3d1a6afSToby Isaac } 4109d3d1a6afSToby Isaac if (bDof) { 4110d3d1a6afSToby Isaac PetscInt dof, bOff, q, allDof = 0; 4111d3d1a6afSToby Isaac 4112d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, b, &dof);CHKERRQ(ierr); 4113d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 4114d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4115d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 4116d3d1a6afSToby Isaac 4117d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 4118d3d1a6afSToby Isaac allDof += aDof; 4119d3d1a6afSToby Isaac } 4120d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 4121d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = dof * allDof; 4122d3d1a6afSToby Isaac } 4123d3d1a6afSToby Isaac else { 4124d3d1a6afSToby Isaac PetscInt dof; 4125d3d1a6afSToby Isaac 4126d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, b, &dof);CHKERRQ(ierr); 4127d3d1a6afSToby Isaac newPointOffsets[0][p+1] = dof; 4128d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 4129d3d1a6afSToby Isaac } 4130d3d1a6afSToby Isaac } 4131d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 4132d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 4133d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4134d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 4135d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 4136d3d1a6afSToby Isaac } 4137d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],PETSC_SCALAR,&pointMat[0]);CHKERRQ(ierr); 4138d3d1a6afSToby Isaac } 4139d3d1a6afSToby Isaac 4140d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 4141d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 4142d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 4143d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,maxDof,PETSC_INT,&indices);CHKERRQ(ierr); 4144d3d1a6afSToby Isaac ierr = DMGetWorkArray(dm,maxAnchor*maxDof,PETSC_INT,&newIndices);CHKERRQ(ierr); 4145d3d1a6afSToby Isaac if (numFields) { 4146d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 4147d3d1a6afSToby Isaac PetscInt b = points[2*p]; 4148d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 4149d3d1a6afSToby Isaac PetscInt bDof = 0; 4150d3d1a6afSToby Isaac 4151d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4152d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4153d3d1a6afSToby Isaac } 4154d3d1a6afSToby Isaac if (bDof) { 4155d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 4156d3d1a6afSToby Isaac 4157d3d1a6afSToby Isaac fStart[0] = 0; 4158d3d1a6afSToby Isaac fEnd[0] = 0; 4159d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4160d3d1a6afSToby Isaac PetscInt fDof; 4161d3d1a6afSToby Isaac 4162d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 4163d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 4164d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 4165d3d1a6afSToby Isaac } 4166d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 4167d3d1a6afSToby Isaac ierr = indicesPointFields_private(cSec, b, bOff, fEnd, PETSC_TRUE, o, indices);CHKERRQ(ierr); 4168d3d1a6afSToby Isaac 4169d3d1a6afSToby Isaac fAnchorStart[0] = 0; 4170d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 4171d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4172d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 4173d3d1a6afSToby Isaac 4174d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 4175d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 4176d3d1a6afSToby Isaac } 4177d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 4178d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4179d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 4180d3d1a6afSToby Isaac 4181d3d1a6afSToby 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 */ 4182d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 4183d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 4184d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(section, a, &aOff); 4185d3d1a6afSToby Isaac ierr = indicesPointFields_private(section, a, aOff, fAnchorEnd, PETSC_TRUE, 0, newIndices);CHKERRQ(ierr); 4186d3d1a6afSToby Isaac } 4187d3d1a6afSToby Isaac newP += bDof; 4188d3d1a6afSToby Isaac 4189d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 4190d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4191d3d1a6afSToby 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); 4192d3d1a6afSToby Isaac } 4193d3d1a6afSToby Isaac } 4194d3d1a6afSToby Isaac else { 4195d3d1a6afSToby Isaac newPoints[2 * newP] = b; 4196d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 4197d3d1a6afSToby Isaac newP++; 4198d3d1a6afSToby Isaac } 4199d3d1a6afSToby Isaac } 4200d3d1a6afSToby Isaac } else { 4201d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4202d3d1a6afSToby Isaac PetscInt b = points[2*p]; 4203d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 4204d3d1a6afSToby Isaac PetscInt bDof = 0; 4205d3d1a6afSToby Isaac 4206d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4207d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 4208d3d1a6afSToby Isaac } 4209d3d1a6afSToby Isaac if (bDof) { 4210d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 4211d3d1a6afSToby Isaac 4212d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 4213d3d1a6afSToby Isaac ierr = indicesPoint_private(cSec, b, bOff, &bEnd, PETSC_TRUE, o, indices);CHKERRQ(ierr); 4214d3d1a6afSToby Isaac 4215d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 4216d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4217d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 4218d3d1a6afSToby Isaac 4219d3d1a6afSToby 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 */ 4220d3d1a6afSToby Isaac 4221d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 4222d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 4223d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(section, a, &aOff); 4224d3d1a6afSToby Isaac ierr = indicesPoint_private(section, a, aOff, &bAnchorEnd, PETSC_TRUE, 0, newIndices);CHKERRQ(ierr); 4225d3d1a6afSToby Isaac } 4226d3d1a6afSToby Isaac newP += bDof; 4227d3d1a6afSToby Isaac 4228d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 4229d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 4230d3d1a6afSToby Isaac } 4231d3d1a6afSToby Isaac else { 4232d3d1a6afSToby Isaac newPoints[2 * newP] = b; 4233d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 4234d3d1a6afSToby Isaac newP++; 4235d3d1a6afSToby Isaac } 4236d3d1a6afSToby Isaac } 4237d3d1a6afSToby Isaac } 4238d3d1a6afSToby Isaac 4239d3d1a6afSToby Isaac ierr = PetscMemzero(tmpValues,newNumIndices*numIndices*sizeof(*tmpValues));CHKERRQ(ierr); 4240d3d1a6afSToby Isaac /* multiply constraints on the right */ 4241d3d1a6afSToby Isaac if (numFields) { 4242d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4243d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 4244d3d1a6afSToby Isaac 4245d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4246d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 4247d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4248d3d1a6afSToby Isaac PetscInt c, r, k; 4249d3d1a6afSToby Isaac PetscInt dof; 4250d3d1a6afSToby Isaac 4251d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 4252d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 4253d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 4254d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 4255d3d1a6afSToby Isaac 4256d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4257d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 4258d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4259d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 4260d3d1a6afSToby Isaac } 4261d3d1a6afSToby Isaac } 4262d3d1a6afSToby Isaac } 4263d3d1a6afSToby Isaac } 4264d3d1a6afSToby Isaac else { 4265d3d1a6afSToby Isaac /* copy this column as is */ 4266d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4267d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 4268d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 4269d3d1a6afSToby Isaac } 4270d3d1a6afSToby Isaac } 4271d3d1a6afSToby Isaac } 4272d3d1a6afSToby Isaac oldOff += dof; 4273d3d1a6afSToby Isaac } 4274d3d1a6afSToby Isaac } 4275d3d1a6afSToby Isaac } 4276d3d1a6afSToby Isaac else { 4277d3d1a6afSToby Isaac PetscInt oldOff = 0; 4278d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4279d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 4280d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4281d3d1a6afSToby Isaac PetscInt c, r, k; 4282d3d1a6afSToby Isaac PetscInt dof; 4283d3d1a6afSToby Isaac 4284d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 4285d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 4286d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 4287d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 4288d3d1a6afSToby Isaac 4289d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4290d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 4291d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4292d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 4293d3d1a6afSToby Isaac } 4294d3d1a6afSToby Isaac } 4295d3d1a6afSToby Isaac } 4296d3d1a6afSToby Isaac } 4297d3d1a6afSToby Isaac else { 4298d3d1a6afSToby Isaac /* copy this column as is */ 4299d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 4300d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 4301d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 4302d3d1a6afSToby Isaac } 4303d3d1a6afSToby Isaac } 4304d3d1a6afSToby Isaac } 4305d3d1a6afSToby Isaac oldOff += dof; 4306d3d1a6afSToby Isaac } 4307d3d1a6afSToby Isaac } 4308d3d1a6afSToby Isaac 4309d3d1a6afSToby Isaac ierr = PetscMemzero(newValues,newNumIndices*newNumIndices*sizeof(*newValues));CHKERRQ(ierr); 4310d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 4311d3d1a6afSToby Isaac if (numFields) { 4312d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4313d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 4314d3d1a6afSToby Isaac 4315d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4316d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 4317d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4318d3d1a6afSToby Isaac PetscInt c, r, k; 4319d3d1a6afSToby Isaac PetscInt dof; 4320d3d1a6afSToby Isaac 4321d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 4322d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 4323d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 4324d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 4325d3d1a6afSToby Isaac 4326d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 4327d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4328d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4329d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 4330d3d1a6afSToby Isaac } 4331d3d1a6afSToby Isaac } 4332d3d1a6afSToby Isaac } 4333d3d1a6afSToby Isaac } 4334d3d1a6afSToby Isaac else { 4335d3d1a6afSToby Isaac /* copy this row as is */ 4336d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 4337d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4338d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 4339d3d1a6afSToby Isaac } 4340d3d1a6afSToby Isaac } 4341d3d1a6afSToby Isaac } 4342d3d1a6afSToby Isaac oldOff += dof; 4343d3d1a6afSToby Isaac } 4344d3d1a6afSToby Isaac } 4345d3d1a6afSToby Isaac } 4346d3d1a6afSToby Isaac else { 4347d3d1a6afSToby Isaac PetscInt oldOff = 0; 4348d3d1a6afSToby Isaac 4349d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 4350d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 4351d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 4352d3d1a6afSToby Isaac PetscInt c, r, k; 4353d3d1a6afSToby Isaac PetscInt dof; 4354d3d1a6afSToby Isaac 4355d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 4356d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 4357d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 4358d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 4359d3d1a6afSToby Isaac 4360d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 4361d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4362d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 4363d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 4364d3d1a6afSToby Isaac } 4365d3d1a6afSToby Isaac } 4366d3d1a6afSToby Isaac } 4367d3d1a6afSToby Isaac } 4368d3d1a6afSToby Isaac else { 4369d3d1a6afSToby Isaac /* copy this row as is */ 4370d3d1a6afSToby Isaac for (r = 0; r < dof; c++) { 4371d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 4372d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 4373d3d1a6afSToby Isaac } 4374d3d1a6afSToby Isaac } 4375d3d1a6afSToby Isaac } 4376d3d1a6afSToby Isaac oldOff += dof; 4377d3d1a6afSToby Isaac } 4378d3d1a6afSToby Isaac } 4379d3d1a6afSToby Isaac 4380d3d1a6afSToby Isaac /* clean up */ 4381d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,maxDof,PETSC_INT,&indices);CHKERRQ(ierr); 4382d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,PETSC_INT,&newIndices);CHKERRQ(ierr); 4383d3d1a6afSToby Isaac if (numFields) { 4384d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4385d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],PETSC_SCALAR,&pointMat[f]);CHKERRQ(ierr); 4386d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 4387d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&newPointOffsets[f]);CHKERRQ(ierr); 4388d3d1a6afSToby Isaac } 4389d3d1a6afSToby Isaac } 4390d3d1a6afSToby Isaac else { 4391d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],PETSC_SCALAR,&pointMat[0]);CHKERRQ(ierr); 4392d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 4393d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,numPoints+1,PETSC_INT,&newPointOffsets[0]);CHKERRQ(ierr); 4394d3d1a6afSToby Isaac } 4395d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,PETSC_SCALAR,&tmpValues);CHKERRQ(ierr); 4396d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 4397d3d1a6afSToby Isaac 4398d3d1a6afSToby Isaac /* output */ 4399d3d1a6afSToby Isaac *outNumPoints = newNumPoints; 4400d3d1a6afSToby Isaac *outNumIndices = newNumIndices; 4401d3d1a6afSToby Isaac *outPoints = newPoints; 4402d3d1a6afSToby Isaac *outValues = newValues; 4403d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 4404d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 4405d3d1a6afSToby Isaac } 4406d3d1a6afSToby Isaac PetscFunctionReturn(0); 4407d3d1a6afSToby Isaac } 4408d3d1a6afSToby Isaac 4409d3d1a6afSToby Isaac #undef __FUNCT__ 4410552f7358SJed Brown #define __FUNCT__ "DMPlexMatSetClosure" 44117f5d1fdeSMatthew G. Knepley /*@C 44127f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 44137f5d1fdeSMatthew G. Knepley 44147f5d1fdeSMatthew G. Knepley Not collective 44157f5d1fdeSMatthew G. Knepley 44167f5d1fdeSMatthew G. Knepley Input Parameters: 44177f5d1fdeSMatthew G. Knepley + dm - The DM 4418ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 4419ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 44207f5d1fdeSMatthew G. Knepley . A - The matrix 44217f5d1fdeSMatthew G. Knepley . point - The sieve point in the DM 44227f5d1fdeSMatthew G. Knepley . values - The array of values 44237f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 44247f5d1fdeSMatthew G. Knepley 44257f5d1fdeSMatthew G. Knepley Fortran Notes: 44267f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 44277f5d1fdeSMatthew G. Knepley 44287f5d1fdeSMatthew G. Knepley Level: intermediate 44297f5d1fdeSMatthew G. Knepley 44307f5d1fdeSMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure() 44317f5d1fdeSMatthew G. Knepley @*/ 44327c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 4433552f7358SJed Brown { 4434552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 44351b406b76SMatthew G. Knepley PetscSection clSection; 44361b406b76SMatthew G. Knepley IS clPoints; 4437d3d1a6afSToby Isaac PetscInt *points = NULL, *newPoints; 44381b406b76SMatthew G. Knepley const PetscInt *clp; 4439552f7358SJed Brown PetscInt *indices; 4440552f7358SJed Brown PetscInt offsets[32]; 4441d3d1a6afSToby Isaac PetscInt numFields, numPoints, newNumPoints, numIndices, newNumIndices, dof, off, globalOff, pStart, pEnd, p, q, f; 4442d3d1a6afSToby Isaac PetscScalar *newValues; 4443552f7358SJed Brown PetscErrorCode ierr; 4444552f7358SJed Brown 4445552f7358SJed Brown PetscFunctionBegin; 4446552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4447ebd6d717SJed Brown if (!section) {ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr);} 44483dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 4449ebd6d717SJed Brown if (!globalSection) {ierr = DMGetDefaultGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 44503dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 44513dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 4452552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 445382f516ccSBarry Smith if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 4454552f7358SJed Brown ierr = PetscMemzero(offsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 44551b406b76SMatthew G. Knepley ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, &clSection, &clPoints);CHKERRQ(ierr); 44561b406b76SMatthew G. Knepley if (!clPoints) { 4457552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 4458552f7358SJed Brown /* Compress out points not in the section */ 4459552f7358SJed Brown ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 4460552f7358SJed Brown for (p = 0, q = 0; p < numPoints*2; p += 2) { 4461552f7358SJed Brown if ((points[p] >= pStart) && (points[p] < pEnd)) { 4462552f7358SJed Brown points[q*2] = points[p]; 4463552f7358SJed Brown points[q*2+1] = points[p+1]; 4464552f7358SJed Brown ++q; 4465552f7358SJed Brown } 4466552f7358SJed Brown } 4467552f7358SJed Brown numPoints = q; 44681b406b76SMatthew G. Knepley } else { 44691b406b76SMatthew G. Knepley PetscInt dof, off; 44701b406b76SMatthew G. Knepley 44711b406b76SMatthew G. Knepley ierr = PetscSectionGetDof(clSection, point, &dof);CHKERRQ(ierr); 44721b406b76SMatthew G. Knepley numPoints = dof/2; 44731b406b76SMatthew G. Knepley ierr = PetscSectionGetOffset(clSection, point, &off);CHKERRQ(ierr); 44741b406b76SMatthew G. Knepley ierr = ISGetIndices(clPoints, &clp);CHKERRQ(ierr); 44751b406b76SMatthew G. Knepley points = (PetscInt *) &clp[off]; 44761b406b76SMatthew G. Knepley } 4477552f7358SJed Brown for (p = 0, numIndices = 0; p < numPoints*2; p += 2) { 4478552f7358SJed Brown PetscInt fdof; 4479552f7358SJed Brown 4480552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 4481552f7358SJed Brown for (f = 0; f < numFields; ++f) { 4482552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 4483552f7358SJed Brown offsets[f+1] += fdof; 4484552f7358SJed Brown } 4485552f7358SJed Brown numIndices += dof; 4486552f7358SJed Brown } 44870d644c17SKarl Rupp for (f = 1; f < numFields; ++f) offsets[f+1] += offsets[f]; 44880d644c17SKarl Rupp 448982f516ccSBarry Smith if (numFields && offsets[numFields] != numIndices) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid size for closure %d should be %d", offsets[numFields], numIndices); 4490f7c74593SToby Isaac ierr = DMPlexAnchorsModifyMat(dm,section,numPoints,numIndices,points,values,&newNumPoints,&newNumIndices,&newPoints,&newValues,offsets);CHKERRQ(ierr); 4491d3d1a6afSToby Isaac if (newNumPoints) { 4492d3d1a6afSToby Isaac if (!clPoints) { 4493d3d1a6afSToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 4494d3d1a6afSToby Isaac } else { 4495d3d1a6afSToby Isaac ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr); 4496d3d1a6afSToby Isaac } 4497d3d1a6afSToby Isaac numPoints = newNumPoints; 4498d3d1a6afSToby Isaac numIndices = newNumIndices; 4499d3d1a6afSToby Isaac points = newPoints; 4500d3d1a6afSToby Isaac values = newValues; 4501d3d1a6afSToby Isaac } 4502552f7358SJed Brown ierr = DMGetWorkArray(dm, numIndices, PETSC_INT, &indices);CHKERRQ(ierr); 4503552f7358SJed Brown if (numFields) { 4504552f7358SJed Brown for (p = 0; p < numPoints*2; p += 2) { 4505552f7358SJed Brown PetscInt o = points[p+1]; 4506552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, points[p], &globalOff);CHKERRQ(ierr); 4507552f7358SJed Brown indicesPointFields_private(section, points[p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, o, indices); 4508552f7358SJed Brown } 4509552f7358SJed Brown } else { 4510e6ccafaeSMatthew G Knepley for (p = 0, off = 0; p < numPoints*2; p += 2) { 4511552f7358SJed Brown PetscInt o = points[p+1]; 4512552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, points[p], &globalOff);CHKERRQ(ierr); 4513e6ccafaeSMatthew G Knepley indicesPoint_private(section, points[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, indices); 4514552f7358SJed Brown } 4515552f7358SJed Brown } 4516b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 4517552f7358SJed Brown ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 4518552f7358SJed Brown if (ierr) { 4519552f7358SJed Brown PetscMPIInt rank; 4520552f7358SJed Brown PetscErrorCode ierr2; 4521552f7358SJed Brown 452282f516ccSBarry Smith ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 452377a6746dSMatthew G Knepley ierr2 = (*PetscErrorPrintf)("[%D]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 4524b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 45256a415b8fSMatthew G Knepley ierr2 = DMRestoreWorkArray(dm, numIndices, PETSC_INT, &indices);CHKERRQ(ierr2); 4526552f7358SJed Brown CHKERRQ(ierr); 4527552f7358SJed Brown } 4528d3d1a6afSToby Isaac if (newNumPoints) { 4529d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,newNumIndices*newNumIndices,PETSC_SCALAR,&newValues);CHKERRQ(ierr); 4530d3d1a6afSToby Isaac ierr = DMRestoreWorkArray(dm,2*newNumPoints,PETSC_INT,&newPoints);CHKERRQ(ierr); 4531d3d1a6afSToby Isaac } 4532d3d1a6afSToby Isaac else { 45331b406b76SMatthew G. Knepley if (!clPoints) { 4534552f7358SJed Brown ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 45351b406b76SMatthew G. Knepley } else { 45361b406b76SMatthew G. Knepley ierr = ISRestoreIndices(clPoints, &clp);CHKERRQ(ierr); 45371b406b76SMatthew G. Knepley } 4538d3d1a6afSToby Isaac } 4539552f7358SJed Brown ierr = DMRestoreWorkArray(dm, numIndices, PETSC_INT, &indices);CHKERRQ(ierr); 4540552f7358SJed Brown PetscFunctionReturn(0); 4541552f7358SJed Brown } 4542552f7358SJed Brown 4543552f7358SJed Brown #undef __FUNCT__ 4544de41b84cSMatthew G. Knepley #define __FUNCT__ "DMPlexMatSetClosureRefined" 4545de41b84cSMatthew 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) 4546de41b84cSMatthew G. Knepley { 4547de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 4548de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 4549de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 4550de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 4551de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 4552de41b84cSMatthew G. Knepley CellRefiner cellRefiner; 45534ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 4554de41b84cSMatthew G. Knepley PetscErrorCode ierr; 4555de41b84cSMatthew G. Knepley 4556de41b84cSMatthew G. Knepley PetscFunctionBegin; 4557de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 4558de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 4559de41b84cSMatthew G. Knepley if (!fsection) {ierr = DMGetDefaultSection(dmf, &fsection);CHKERRQ(ierr);} 4560de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 4561de41b84cSMatthew G. Knepley if (!csection) {ierr = DMGetDefaultSection(dmc, &csection);CHKERRQ(ierr);} 4562de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 4563de41b84cSMatthew G. Knepley if (!globalFSection) {ierr = DMGetDefaultGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 4564de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 4565de41b84cSMatthew G. Knepley if (!globalCSection) {ierr = DMGetDefaultGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 4566de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 4567de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 4568de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 4569de41b84cSMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 4570de41b84cSMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 4571de41b84cSMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 4572de41b84cSMatthew G. Knepley /* Column indices */ 4573de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 45744ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 4575de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 4576de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 4577de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 4578de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 4579de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 4580de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 4581de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 4582de41b84cSMatthew G. Knepley ++q; 4583de41b84cSMatthew G. Knepley } 4584de41b84cSMatthew G. Knepley } 4585de41b84cSMatthew G. Knepley numCPoints = q; 4586de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 4587de41b84cSMatthew G. Knepley PetscInt fdof; 4588de41b84cSMatthew G. Knepley 4589de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 45904ca5e9f5SMatthew G. Knepley if (!dof) continue; 4591de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 4592de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 4593de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 4594de41b84cSMatthew G. Knepley } 4595de41b84cSMatthew G. Knepley numCIndices += dof; 4596de41b84cSMatthew G. Knepley } 4597de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 4598de41b84cSMatthew G. Knepley /* Row indices */ 4599de41b84cSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 4600de41b84cSMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 46011ba5f902SMatthew G. Knepley ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 4602de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 4603de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 4604de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 4605de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 4606de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 4607de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 4608de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 46094ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 46104ca5e9f5SMatthew G. Knepley if (!dof) continue; 46114ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 46124ca5e9f5SMatthew G. Knepley if (s < q) continue; 4613de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 4614de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 4615de41b84cSMatthew G. Knepley ++q; 4616de41b84cSMatthew G. Knepley } 4617de41b84cSMatthew G. Knepley } 4618de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 4619de41b84cSMatthew G. Knepley } 4620de41b84cSMatthew G. Knepley numFPoints = q; 4621de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 4622de41b84cSMatthew G. Knepley PetscInt fdof; 4623de41b84cSMatthew G. Knepley 4624de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 46254ca5e9f5SMatthew G. Knepley if (!dof) continue; 4626de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 4627de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 4628de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 4629de41b84cSMatthew G. Knepley } 4630de41b84cSMatthew G. Knepley numFIndices += dof; 4631de41b84cSMatthew G. Knepley } 4632de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 4633de41b84cSMatthew G. Knepley 4634de41b84cSMatthew 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); 4635de41b84cSMatthew 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); 4636de41b84cSMatthew G. Knepley ierr = DMGetWorkArray(dmf, numFIndices, PETSC_INT, &findices);CHKERRQ(ierr); 4637de41b84cSMatthew G. Knepley ierr = DMGetWorkArray(dmc, numCIndices, PETSC_INT, &cindices);CHKERRQ(ierr); 4638de41b84cSMatthew G. Knepley if (numFields) { 4639de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 4640de41b84cSMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 4641de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 4642de41b84cSMatthew G. Knepley indicesPointFields_private(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, o, findices); 4643de41b84cSMatthew G. Knepley } 4644de41b84cSMatthew G. Knepley for (p = 0; p < numCPoints*2; p += 2) { 4645de41b84cSMatthew G. Knepley PetscInt o = cpoints[p+1]; 4646de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 4647de41b84cSMatthew G. Knepley indicesPointFields_private(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, o, cindices); 4648de41b84cSMatthew G. Knepley } 4649de41b84cSMatthew G. Knepley } else { 4650de41b84cSMatthew G. Knepley for (p = 0, off = 0; p < numFPoints*2; p += 2) { 4651de41b84cSMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 4652de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 4653de41b84cSMatthew G. Knepley indicesPoint_private(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, findices); 4654de41b84cSMatthew G. Knepley } 4655de41b84cSMatthew G. Knepley for (p = 0, off = 0; p < numCPoints*2; p += 2) { 4656de41b84cSMatthew G. Knepley PetscInt o = cpoints[p+1]; 4657de41b84cSMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 4658de41b84cSMatthew G. Knepley indicesPoint_private(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, cindices); 4659de41b84cSMatthew G. Knepley } 4660de41b84cSMatthew G. Knepley } 4661de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 4662de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 4663de41b84cSMatthew G. Knepley if (ierr) { 4664de41b84cSMatthew G. Knepley PetscMPIInt rank; 4665de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 4666de41b84cSMatthew G. Knepley 4667de41b84cSMatthew G. Knepley ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 4668de41b84cSMatthew G. Knepley ierr2 = (*PetscErrorPrintf)("[%D]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 4669de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 4670de41b84cSMatthew G. Knepley ierr2 = DMRestoreWorkArray(dmf, numFIndices, PETSC_INT, &findices);CHKERRQ(ierr2); 4671de41b84cSMatthew G. Knepley ierr2 = DMRestoreWorkArray(dmc, numCIndices, PETSC_INT, &cindices);CHKERRQ(ierr2); 4672de41b84cSMatthew G. Knepley CHKERRQ(ierr); 4673de41b84cSMatthew G. Knepley } 4674549a8adaSMatthew G. Knepley ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 4675de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 4676de41b84cSMatthew G. Knepley ierr = DMRestoreWorkArray(dmf, numFIndices, PETSC_INT, &findices);CHKERRQ(ierr); 4677de41b84cSMatthew G. Knepley ierr = DMRestoreWorkArray(dmc, numCIndices, PETSC_INT, &cindices);CHKERRQ(ierr); 4678de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 4679de41b84cSMatthew G. Knepley } 4680de41b84cSMatthew G. Knepley 4681de41b84cSMatthew G. Knepley #undef __FUNCT__ 46827c927364SMatthew G. Knepley #define __FUNCT__ "DMPlexMatGetClosureIndicesRefined" 46837c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 46847c927364SMatthew G. Knepley { 46857c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 46867c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 46877c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 46887c927364SMatthew G. Knepley CellRefiner cellRefiner; 46897c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 46907c927364SMatthew G. Knepley PetscErrorCode ierr; 46917c927364SMatthew G. Knepley 46927c927364SMatthew G. Knepley PetscFunctionBegin; 46937c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 46947c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 46957c927364SMatthew G. Knepley if (!fsection) {ierr = DMGetDefaultSection(dmf, &fsection);CHKERRQ(ierr);} 46967c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 46977c927364SMatthew G. Knepley if (!csection) {ierr = DMGetDefaultSection(dmc, &csection);CHKERRQ(ierr);} 46987c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 46997c927364SMatthew G. Knepley if (!globalFSection) {ierr = DMGetDefaultGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 47007c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 47017c927364SMatthew G. Knepley if (!globalCSection) {ierr = DMGetDefaultGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 47027c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 47037c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 47047c927364SMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 47057c927364SMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 47067c927364SMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 47077c927364SMatthew G. Knepley /* Column indices */ 47087c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 47097c927364SMatthew G. Knepley maxFPoints = numCPoints; 47107c927364SMatthew G. Knepley /* Compress out points not in the section */ 47117c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 47127c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 47137c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 47147c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 47157c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 47167c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 47177c927364SMatthew G. Knepley ++q; 47187c927364SMatthew G. Knepley } 47197c927364SMatthew G. Knepley } 47207c927364SMatthew G. Knepley numCPoints = q; 47217c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 47227c927364SMatthew G. Knepley PetscInt fdof; 47237c927364SMatthew G. Knepley 47247c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 47257c927364SMatthew G. Knepley if (!dof) continue; 47267c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 47277c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 47287c927364SMatthew G. Knepley coffsets[f+1] += fdof; 47297c927364SMatthew G. Knepley } 47307c927364SMatthew G. Knepley numCIndices += dof; 47317c927364SMatthew G. Knepley } 47327c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 47337c927364SMatthew G. Knepley /* Row indices */ 47347c927364SMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 47357c927364SMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 47367c927364SMatthew G. Knepley ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 47377c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 47387c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 47397c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 47407c927364SMatthew G. Knepley /* Compress out points not in the section */ 47417c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 47427c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 47437c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 47447c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 47457c927364SMatthew G. Knepley if (!dof) continue; 47467c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 47477c927364SMatthew G. Knepley if (s < q) continue; 47487c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 47497c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 47507c927364SMatthew G. Knepley ++q; 47517c927364SMatthew G. Knepley } 47527c927364SMatthew G. Knepley } 47537c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 47547c927364SMatthew G. Knepley } 47557c927364SMatthew G. Knepley numFPoints = q; 47567c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 47577c927364SMatthew G. Knepley PetscInt fdof; 47587c927364SMatthew G. Knepley 47597c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 47607c927364SMatthew G. Knepley if (!dof) continue; 47617c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 47627c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 47637c927364SMatthew G. Knepley foffsets[f+1] += fdof; 47647c927364SMatthew G. Knepley } 47657c927364SMatthew G. Knepley numFIndices += dof; 47667c927364SMatthew G. Knepley } 47677c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 47687c927364SMatthew G. Knepley 47697c927364SMatthew 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); 47707c927364SMatthew 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); 47717c927364SMatthew G. Knepley if (numFields) { 47727c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 47737c927364SMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 47747c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 47757c927364SMatthew G. Knepley indicesPointFields_private(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, o, findices); 47767c927364SMatthew G. Knepley } 47777c927364SMatthew G. Knepley for (p = 0; p < numCPoints*2; p += 2) { 47787c927364SMatthew G. Knepley PetscInt o = cpoints[p+1]; 47797c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 47807c927364SMatthew G. Knepley indicesPointFields_private(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, o, cindices); 47817c927364SMatthew G. Knepley } 47827c927364SMatthew G. Knepley } else { 47837c927364SMatthew G. Knepley for (p = 0, off = 0; p < numFPoints*2; p += 2) { 47847c927364SMatthew G. Knepley PetscInt o = ftotpoints[p+1]; 47857c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalFSection, ftotpoints[p], &globalOff);CHKERRQ(ierr); 47867c927364SMatthew G. Knepley indicesPoint_private(fsection, ftotpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, findices); 47877c927364SMatthew G. Knepley } 47887c927364SMatthew G. Knepley for (p = 0, off = 0; p < numCPoints*2; p += 2) { 47897c927364SMatthew G. Knepley PetscInt o = cpoints[p+1]; 47907c927364SMatthew G. Knepley ierr = PetscSectionGetOffset(globalCSection, cpoints[p], &globalOff);CHKERRQ(ierr); 47917c927364SMatthew G. Knepley indicesPoint_private(csection, cpoints[p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, o, cindices); 47927c927364SMatthew G. Knepley } 47937c927364SMatthew G. Knepley } 47947c927364SMatthew G. Knepley ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, PETSC_INT, &ftotpoints);CHKERRQ(ierr); 47957c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 47967c927364SMatthew G. Knepley PetscFunctionReturn(0); 47977c927364SMatthew G. Knepley } 47987c927364SMatthew G. Knepley 47997c927364SMatthew G. Knepley #undef __FUNCT__ 4800770b213bSMatthew G Knepley #define __FUNCT__ "DMPlexGetHybridBounds" 4801f96281f8SMatthew G. Knepley /*@ 4802f96281f8SMatthew G. Knepley DMPlexGetHybridBounds - Get the first mesh point of each dimension which is a hybrid 4803f96281f8SMatthew G. Knepley 4804f96281f8SMatthew G. Knepley Input Parameter: 4805f96281f8SMatthew G. Knepley . dm - The DMPlex object 4806f96281f8SMatthew G. Knepley 4807f96281f8SMatthew G. Knepley Output Parameters: 4808f96281f8SMatthew G. Knepley + cMax - The first hybrid cell 4809dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 4810dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 4811dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 4812f96281f8SMatthew G. Knepley 4813f96281f8SMatthew G. Knepley Level: developer 4814f96281f8SMatthew G. Knepley 4815dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexSetHybridBounds() 4816f96281f8SMatthew G. Knepley @*/ 4817770b213bSMatthew G Knepley PetscErrorCode DMPlexGetHybridBounds(DM dm, PetscInt *cMax, PetscInt *fMax, PetscInt *eMax, PetscInt *vMax) 4818552f7358SJed Brown { 4819552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4820770b213bSMatthew G Knepley PetscInt dim; 4821770b213bSMatthew G Knepley PetscErrorCode ierr; 4822552f7358SJed Brown 4823552f7358SJed Brown PetscFunctionBegin; 4824552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4825c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4826770b213bSMatthew G Knepley if (cMax) *cMax = mesh->hybridPointMax[dim]; 4827770b213bSMatthew G Knepley if (fMax) *fMax = mesh->hybridPointMax[dim-1]; 4828770b213bSMatthew G Knepley if (eMax) *eMax = mesh->hybridPointMax[1]; 4829770b213bSMatthew G Knepley if (vMax) *vMax = mesh->hybridPointMax[0]; 4830552f7358SJed Brown PetscFunctionReturn(0); 4831552f7358SJed Brown } 4832552f7358SJed Brown 4833552f7358SJed Brown #undef __FUNCT__ 4834770b213bSMatthew G Knepley #define __FUNCT__ "DMPlexSetHybridBounds" 4835dc5a3409SMatthew G. Knepley /*@ 4836dc5a3409SMatthew G. Knepley DMPlexSetHybridBounds - Set the first mesh point of each dimension which is a hybrid 4837dc5a3409SMatthew G. Knepley 4838dc5a3409SMatthew G. Knepley Input Parameters: 4839dc5a3409SMatthew G. Knepley . dm - The DMPlex object 4840dc5a3409SMatthew G. Knepley . cMax - The first hybrid cell 4841dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 4842dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 4843dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 4844dc5a3409SMatthew G. Knepley 4845dc5a3409SMatthew G. Knepley Level: developer 4846dc5a3409SMatthew G. Knepley 4847dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexGetHybridBounds() 4848dc5a3409SMatthew G. Knepley @*/ 4849770b213bSMatthew G Knepley PetscErrorCode DMPlexSetHybridBounds(DM dm, PetscInt cMax, PetscInt fMax, PetscInt eMax, PetscInt vMax) 4850552f7358SJed Brown { 4851552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4852770b213bSMatthew G Knepley PetscInt dim; 4853770b213bSMatthew G Knepley PetscErrorCode ierr; 4854552f7358SJed Brown 4855552f7358SJed Brown PetscFunctionBegin; 4856552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4857c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4858770b213bSMatthew G Knepley if (cMax >= 0) mesh->hybridPointMax[dim] = cMax; 4859770b213bSMatthew G Knepley if (fMax >= 0) mesh->hybridPointMax[dim-1] = fMax; 4860770b213bSMatthew G Knepley if (eMax >= 0) mesh->hybridPointMax[1] = eMax; 4861770b213bSMatthew G Knepley if (vMax >= 0) mesh->hybridPointMax[0] = vMax; 4862552f7358SJed Brown PetscFunctionReturn(0); 4863552f7358SJed Brown } 4864552f7358SJed Brown 4865552f7358SJed Brown #undef __FUNCT__ 4866552f7358SJed Brown #define __FUNCT__ "DMPlexGetVTKCellHeight" 4867552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 4868552f7358SJed Brown { 4869552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4870552f7358SJed Brown 4871552f7358SJed Brown PetscFunctionBegin; 4872552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4873552f7358SJed Brown PetscValidPointer(cellHeight, 2); 4874552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 4875552f7358SJed Brown PetscFunctionReturn(0); 4876552f7358SJed Brown } 4877552f7358SJed Brown 4878552f7358SJed Brown #undef __FUNCT__ 4879552f7358SJed Brown #define __FUNCT__ "DMPlexSetVTKCellHeight" 4880552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 4881552f7358SJed Brown { 4882552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4883552f7358SJed Brown 4884552f7358SJed Brown PetscFunctionBegin; 4885552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4886552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 4887552f7358SJed Brown PetscFunctionReturn(0); 4888552f7358SJed Brown } 4889552f7358SJed Brown 4890552f7358SJed Brown #undef __FUNCT__ 4891552f7358SJed Brown #define __FUNCT__ "DMPlexCreateNumbering_Private" 4892552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 4893ef48cebcSMatthew G. Knepley static PetscErrorCode DMPlexCreateNumbering_Private(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 4894552f7358SJed Brown { 4895552f7358SJed Brown PetscSection section, globalSection; 4896552f7358SJed Brown PetscInt *numbers, p; 4897552f7358SJed Brown PetscErrorCode ierr; 4898552f7358SJed Brown 4899552f7358SJed Brown PetscFunctionBegin; 490082f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 4901552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 4902552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 4903552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 4904552f7358SJed Brown } 4905552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 4906552f7358SJed Brown ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 4907854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 4908552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 4909552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 4910ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 4911ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 4912552f7358SJed Brown } 491382f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 4914ef48cebcSMatthew G. Knepley if (globalSize) { 4915ef48cebcSMatthew G. Knepley PetscLayout layout; 4916ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 4917ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 4918ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 4919ef48cebcSMatthew G. Knepley } 4920552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 4921552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 4922552f7358SJed Brown PetscFunctionReturn(0); 4923552f7358SJed Brown } 4924552f7358SJed Brown 4925552f7358SJed Brown #undef __FUNCT__ 4926552f7358SJed Brown #define __FUNCT__ "DMPlexGetCellNumbering" 4927552f7358SJed Brown PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 4928552f7358SJed Brown { 4929552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4930552f7358SJed Brown PetscInt cellHeight, cStart, cEnd, cMax; 4931552f7358SJed Brown PetscErrorCode ierr; 4932552f7358SJed Brown 4933552f7358SJed Brown PetscFunctionBegin; 4934552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4935552f7358SJed Brown if (!mesh->globalCellNumbers) { 4936552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 4937552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 49380298fd71SBarry Smith ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 49390d644c17SKarl Rupp if (cMax >= 0) cEnd = PetscMin(cEnd, cMax); 4940ef48cebcSMatthew G. Knepley ierr = DMPlexCreateNumbering_Private(dm, cStart, cEnd, 0, NULL, dm->sf, &mesh->globalCellNumbers);CHKERRQ(ierr); 4941552f7358SJed Brown } 4942552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 4943552f7358SJed Brown PetscFunctionReturn(0); 4944552f7358SJed Brown } 4945552f7358SJed Brown 4946552f7358SJed Brown #undef __FUNCT__ 4947552f7358SJed Brown #define __FUNCT__ "DMPlexGetVertexNumbering" 4948552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 4949552f7358SJed Brown { 4950552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4951552f7358SJed Brown PetscInt vStart, vEnd, vMax; 4952552f7358SJed Brown PetscErrorCode ierr; 4953552f7358SJed Brown 4954552f7358SJed Brown PetscFunctionBegin; 4955552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4956552f7358SJed Brown if (!mesh->globalVertexNumbers) { 4957552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 49580298fd71SBarry Smith ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); 49590d644c17SKarl Rupp if (vMax >= 0) vEnd = PetscMin(vEnd, vMax); 4960ef48cebcSMatthew G. Knepley ierr = DMPlexCreateNumbering_Private(dm, vStart, vEnd, 0, NULL, dm->sf, &mesh->globalVertexNumbers);CHKERRQ(ierr); 4961552f7358SJed Brown } 4962552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 4963552f7358SJed Brown PetscFunctionReturn(0); 4964552f7358SJed Brown } 4965552f7358SJed Brown 4966ef48cebcSMatthew G. Knepley #undef __FUNCT__ 4967ef48cebcSMatthew G. Knepley #define __FUNCT__ "DMPlexCreatePointNumbering" 4968ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 4969ef48cebcSMatthew G. Knepley { 4970ef48cebcSMatthew G. Knepley IS nums[4]; 4971ef48cebcSMatthew G. Knepley PetscInt depths[4]; 4972ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 4973ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 4974ef48cebcSMatthew G. Knepley 4975ef48cebcSMatthew G. Knepley PetscFunctionBegin; 4976ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4977ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4978ef48cebcSMatthew G. Knepley depths[0] = depth; depths[1] = 0; 4979ef48cebcSMatthew G. Knepley for (d = 2; d <= depth; ++d) depths[d] = depth-d+1; 4980ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 4981ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 4982ef48cebcSMatthew G. Knepley 4983ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, depths[d], &pStart, &pEnd);CHKERRQ(ierr); 4984ef48cebcSMatthew G. Knepley ierr = DMPlexCreateNumbering_Private(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 4985ef48cebcSMatthew G. Knepley shift += gsize; 4986ef48cebcSMatthew G. Knepley } 4987ef48cebcSMatthew G. Knepley ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers); 4988ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 4989ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 4990ef48cebcSMatthew G. Knepley } 4991ef48cebcSMatthew G. Knepley 4992552f7358SJed Brown 4993552f7358SJed Brown #undef __FUNCT__ 4994552f7358SJed Brown #define __FUNCT__ "PetscSectionCreateGlobalSectionLabel" 4995552f7358SJed Brown /*@C 4996552f7358SJed Brown PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using 4997552f7358SJed Brown the local section and an SF describing the section point overlap. 4998552f7358SJed Brown 4999552f7358SJed Brown Input Parameters: 5000552f7358SJed Brown + s - The PetscSection for the local field layout 5001552f7358SJed Brown . sf - The SF describing parallel layout of the section points 5002552f7358SJed Brown . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs 5003552f7358SJed Brown . label - The label specifying the points 5004552f7358SJed Brown - labelValue - The label stratum specifying the points 5005552f7358SJed Brown 5006552f7358SJed Brown Output Parameter: 5007552f7358SJed Brown . gsection - The PetscSection for the global field layout 5008552f7358SJed Brown 5009552f7358SJed Brown Note: This gives negative sizes and offsets to points not owned by this process 5010552f7358SJed Brown 5011552f7358SJed Brown Level: developer 5012552f7358SJed Brown 5013552f7358SJed Brown .seealso: PetscSectionCreate() 5014552f7358SJed Brown @*/ 5015552f7358SJed Brown PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection) 5016552f7358SJed Brown { 50177ec39499SMatthew G. Knepley PetscInt *neg = NULL, *tmpOff = NULL; 5018552f7358SJed Brown PetscInt pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots; 5019552f7358SJed Brown PetscErrorCode ierr; 5020552f7358SJed Brown 5021552f7358SJed Brown PetscFunctionBegin; 50224c0d72c2SMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr); 5023552f7358SJed Brown ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr); 5024552f7358SJed Brown ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr); 50257ec39499SMatthew G. Knepley ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 50267ec39499SMatthew G. Knepley if (nroots >= 0) { 50277ec39499SMatthew G. Knepley if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart); 50281795a4d1SJed Brown ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr); 50297ec39499SMatthew G. Knepley if (nroots > pEnd-pStart) { 50301795a4d1SJed Brown ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr); 50317ec39499SMatthew G. Knepley } else { 50327ec39499SMatthew G. Knepley tmpOff = &(*gsection)->atlasDof[-pStart]; 50337ec39499SMatthew G. Knepley } 50347ec39499SMatthew G. Knepley } 5035552f7358SJed Brown /* Mark ghost points with negative dof */ 5036552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 5037552f7358SJed Brown PetscInt value; 5038552f7358SJed Brown 5039552f7358SJed Brown ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr); 5040552f7358SJed Brown if (value != labelValue) continue; 5041552f7358SJed Brown ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr); 5042552f7358SJed Brown ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr); 5043552f7358SJed Brown ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr); 5044552f7358SJed Brown if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);} 50457ec39499SMatthew G. Knepley if (neg) neg[p] = -(dof+1); 5046552f7358SJed Brown } 5047552f7358SJed Brown ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr); 5048552f7358SJed Brown if (nroots >= 0) { 50497ec39499SMatthew G. Knepley ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 50507ec39499SMatthew G. Knepley ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 5051552f7358SJed Brown if (nroots > pEnd-pStart) { 50527ec39499SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];} 5053552f7358SJed Brown } 5054552f7358SJed Brown } 5055552f7358SJed Brown /* Calculate new sizes, get proccess offset, and calculate point offsets */ 5056552f7358SJed Brown for (p = 0, off = 0; p < pEnd-pStart; ++p) { 5057552f7358SJed Brown cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0; 5058552f7358SJed Brown (*gsection)->atlasOff[p] = off; 5059552f7358SJed Brown off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0; 5060552f7358SJed Brown } 50614c0d72c2SMatthew G. Knepley ierr = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRQ(ierr); 5062552f7358SJed Brown globalOff -= off; 5063552f7358SJed Brown for (p = 0, off = 0; p < pEnd-pStart; ++p) { 5064552f7358SJed Brown (*gsection)->atlasOff[p] += globalOff; 50657ec39499SMatthew G. Knepley if (neg) neg[p] = -((*gsection)->atlasOff[p]+1); 5066552f7358SJed Brown } 5067552f7358SJed Brown /* Put in negative offsets for ghost points */ 5068552f7358SJed Brown if (nroots >= 0) { 50697ec39499SMatthew G. Knepley ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 50707ec39499SMatthew G. Knepley ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr); 5071552f7358SJed Brown if (nroots > pEnd-pStart) { 50727ec39499SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];} 5073552f7358SJed Brown } 5074552f7358SJed Brown } 50757ec39499SMatthew G. Knepley if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);} 5076552f7358SJed Brown ierr = PetscFree(neg);CHKERRQ(ierr); 5077552f7358SJed Brown PetscFunctionReturn(0); 5078552f7358SJed Brown } 5079ca8062c8SMatthew G. Knepley 5080ca8062c8SMatthew G. Knepley #undef __FUNCT__ 5081ca8062c8SMatthew G. Knepley #define __FUNCT__ "DMPlexCheckSymmetry" 5082ca8062c8SMatthew G. Knepley /*@ 5083ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 5084ca8062c8SMatthew G. Knepley 5085ca8062c8SMatthew G. Knepley Input Parameters: 5086ca8062c8SMatthew G. Knepley + dm - The DMPlex object 5087ca8062c8SMatthew G. Knepley 5088ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 5089ca8062c8SMatthew G. Knepley 5090ca8062c8SMatthew G. Knepley Level: developer 5091ca8062c8SMatthew G. Knepley 50929bf0dad6SMatthew G. Knepley .seealso: DMCreate(), DMCheckSkeleton(), DMCheckFaces() 5093ca8062c8SMatthew G. Knepley @*/ 5094ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 5095ca8062c8SMatthew G. Knepley { 5096ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 5097ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 5098ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 5099ca8062c8SMatthew G. Knepley PetscInt pStart, pEnd, p, csize, ssize; 5100ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 5101ca8062c8SMatthew G. Knepley 5102ca8062c8SMatthew G. Knepley PetscFunctionBegin; 5103ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5104ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 5105ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 5106ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 5107ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 5108ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 5109ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 5110ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 5111ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 511242e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 511342e66dfaSMatthew G. Knepley PetscInt d; 511442e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 511542e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 511642e66dfaSMatthew G. Knepley } 5117ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 5118ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 5119ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 5120ca8062c8SMatthew G. Knepley if (support[s] == p) break; 5121ca8062c8SMatthew G. Knepley } 512242e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 5123ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d cone: ", p); 5124ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 5125ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", cone[s]); 5126ca8062c8SMatthew G. Knepley } 5127ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n"); 5128ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d support: ", cone[c]); 5129ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 5130ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", support[s]); 5131ca8062c8SMatthew G. Knepley } 5132ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n"); 513342e66dfaSMatthew G. Knepley if (dup) { 513442e66dfaSMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d not repeatedly found in support of repeated cone point %d", p, cone[c]); 513542e66dfaSMatthew G. Knepley } else { 5136ca8062c8SMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d not found in support of cone point %d", p, cone[c]); 5137ca8062c8SMatthew G. Knepley } 5138ca8062c8SMatthew G. Knepley } 513942e66dfaSMatthew G. Knepley } 5140ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 5141ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 5142ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 5143ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5144ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5145ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 5146ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 5147ca8062c8SMatthew G. Knepley } 5148ca8062c8SMatthew G. Knepley if (c >= coneSize) { 5149ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d support: ", p); 5150ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 5151ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", support[c]); 5152ca8062c8SMatthew G. Knepley } 5153ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n"); 5154ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "p: %d cone: ", support[s]); 5155ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 5156ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "%d, ", cone[c]); 5157ca8062c8SMatthew G. Knepley } 5158ca8062c8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n"); 5159ca8062c8SMatthew G. Knepley SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d not found in cone of support point %d", p, support[s]); 5160ca8062c8SMatthew G. Knepley } 5161ca8062c8SMatthew G. Knepley } 5162ca8062c8SMatthew G. Knepley } 5163ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 5164ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 5165ca8062c8SMatthew G. Knepley if (csize != ssize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %d != Total support size %d", csize, ssize); 5166ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 5167ca8062c8SMatthew G. Knepley } 5168ca8062c8SMatthew G. Knepley 5169ca8062c8SMatthew G. Knepley #undef __FUNCT__ 5170ca8062c8SMatthew G. Knepley #define __FUNCT__ "DMPlexCheckSkeleton" 5171ca8062c8SMatthew G. Knepley /*@ 5172ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 5173ca8062c8SMatthew G. Knepley 5174ca8062c8SMatthew G. Knepley Input Parameters: 5175ca8062c8SMatthew G. Knepley + dm - The DMPlex object 517658723a97SMatthew G. Knepley . isSimplex - Are the cells simplices or tensor products 517758723a97SMatthew G. Knepley - cellHeight - Normally 0 5178ca8062c8SMatthew G. Knepley 5179ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 5180ca8062c8SMatthew G. Knepley 5181ca8062c8SMatthew G. Knepley Level: developer 5182ca8062c8SMatthew G. Knepley 51839bf0dad6SMatthew G. Knepley .seealso: DMCreate(), DMCheckSymmetry(), DMCheckFaces() 5184ca8062c8SMatthew G. Knepley @*/ 518558723a97SMatthew G. Knepley PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscBool isSimplex, PetscInt cellHeight) 5186ca8062c8SMatthew G. Knepley { 518742363296SMatthew G. Knepley PetscInt dim, numCorners, numHybridCorners, vStart, vEnd, cStart, cEnd, cMax, c; 5188ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 5189ca8062c8SMatthew G. Knepley 5190ca8062c8SMatthew G. Knepley PetscFunctionBegin; 5191ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5192c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5193ca8062c8SMatthew G. Knepley switch (dim) { 519442363296SMatthew G. Knepley case 1: numCorners = isSimplex ? 2 : 2; numHybridCorners = isSimplex ? 2 : 2; break; 519542363296SMatthew G. Knepley case 2: numCorners = isSimplex ? 3 : 4; numHybridCorners = isSimplex ? 4 : 4; break; 519642363296SMatthew G. Knepley case 3: numCorners = isSimplex ? 4 : 8; numHybridCorners = isSimplex ? 6 : 8; break; 5197ca8062c8SMatthew G. Knepley default: 5198ca8062c8SMatthew G. Knepley SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle meshes of dimension %d", dim); 5199ca8062c8SMatthew G. Knepley } 520058723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 520158723a97SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 5202ca8062c8SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 5203ca8062c8SMatthew G. Knepley cMax = cMax >= 0 ? cMax : cEnd; 5204ca8062c8SMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 520558723a97SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 520658723a97SMatthew G. Knepley 520758723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 520858723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 520958723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 521058723a97SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 521158723a97SMatthew G. Knepley } 521258723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 5213ca8062c8SMatthew G. Knepley if (coneSize != numCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %d has %d vertices != %d", c, coneSize, numCorners); 5214ca8062c8SMatthew G. Knepley } 521542363296SMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 521642363296SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 521742363296SMatthew G. Knepley 521842363296SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 521942363296SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 522042363296SMatthew G. Knepley const PetscInt p = closure[cl]; 522142363296SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 522242363296SMatthew G. Knepley } 522342363296SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 522442363296SMatthew G. Knepley if (coneSize > numHybridCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Hybrid cell %d has %d vertices > %d", c, coneSize, numHybridCorners); 522542363296SMatthew G. Knepley } 5226ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 5227ca8062c8SMatthew G. Knepley } 52289bf0dad6SMatthew G. Knepley 52299bf0dad6SMatthew G. Knepley #undef __FUNCT__ 52309bf0dad6SMatthew G. Knepley #define __FUNCT__ "DMPlexCheckFaces" 52319bf0dad6SMatthew G. Knepley /*@ 52329bf0dad6SMatthew 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 52339bf0dad6SMatthew G. Knepley 52349bf0dad6SMatthew G. Knepley Input Parameters: 52359bf0dad6SMatthew G. Knepley + dm - The DMPlex object 52369bf0dad6SMatthew G. Knepley . isSimplex - Are the cells simplices or tensor products 52379bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 52389bf0dad6SMatthew G. Knepley 52399bf0dad6SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 52409bf0dad6SMatthew G. Knepley 52419bf0dad6SMatthew G. Knepley Level: developer 52429bf0dad6SMatthew G. Knepley 52439bf0dad6SMatthew G. Knepley .seealso: DMCreate(), DMCheckSymmetry(), DMCheckSkeleton() 52449bf0dad6SMatthew G. Knepley @*/ 52459bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexCheckFaces(DM dm, PetscBool isSimplex, PetscInt cellHeight) 52469bf0dad6SMatthew G. Knepley { 52473554e41dSMatthew G. Knepley PetscInt pMax[4]; 52483554e41dSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, h; 52499bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 52509bf0dad6SMatthew G. Knepley 52519bf0dad6SMatthew G. Knepley PetscFunctionBegin; 52529bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5253c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 52549bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 525525abba81SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &pMax[dim], &pMax[dim-1], &pMax[1], &pMax[0]);CHKERRQ(ierr); 52563554e41dSMatthew G. Knepley for (h = cellHeight; h < dim; ++h) { 52573554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 52583554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 52599bf0dad6SMatthew G. Knepley const PetscInt *cone, *ornt, *faces; 52609bf0dad6SMatthew G. Knepley PetscInt numFaces, faceSize, coneSize,f; 52619bf0dad6SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0; 52629bf0dad6SMatthew G. Knepley 526325abba81SMatthew G. Knepley if (pMax[dim-h] >= 0 && c >= pMax[dim-h]) continue; 52649bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 52659bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 52669bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 52679bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 52689bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 52699bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 52709bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 52719bf0dad6SMatthew G. Knepley } 52723554e41dSMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, dim-h, numCorners, closure, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 52739bf0dad6SMatthew 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); 52749bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 52759bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 52769bf0dad6SMatthew G. Knepley 52779bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 52789bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 52799bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 52809bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 52819bf0dad6SMatthew G. Knepley } 5282e003ed69SMatthew 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); 52839bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 5284e003ed69SMatthew 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]); 52859bf0dad6SMatthew G. Knepley } 52869bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 52879bf0dad6SMatthew G. Knepley } 52889bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreFaces_Internal(dm, dim, c, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 52899bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 52909bf0dad6SMatthew G. Knepley } 52913554e41dSMatthew G. Knepley } 5292552f7358SJed Brown PetscFunctionReturn(0); 5293552f7358SJed Brown } 52943913d7c8SMatthew G. Knepley 52953913d7c8SMatthew G. Knepley #undef __FUNCT__ 5296bceba477SMatthew G. Knepley #define __FUNCT__ "DMCreateInterpolation_Plex" 5297bceba477SMatthew G. Knepley /* Pointwise interpolation 5298bceba477SMatthew G. Knepley Just code FEM for now 5299bceba477SMatthew G. Knepley u^f = I u^c 53004ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 53014ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 53024ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 5303bceba477SMatthew G. Knepley */ 5304bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 5305bceba477SMatthew G. Knepley { 5306bceba477SMatthew G. Knepley PetscSection gsc, gsf; 5307bceba477SMatthew G. Knepley PetscInt m, n; 5308a063dac3SMatthew G. Knepley void *ctx; 5309bceba477SMatthew G. Knepley PetscErrorCode ierr; 5310bceba477SMatthew G. Knepley 5311bceba477SMatthew G. Knepley PetscFunctionBegin; 5312bceba477SMatthew G. Knepley /* 5313bceba477SMatthew G. Knepley Loop over coarse cells 5314bceba477SMatthew G. Knepley Loop over coarse basis functions 5315bceba477SMatthew G. Knepley Loop over fine cells in coarse cell 5316bceba477SMatthew G. Knepley Loop over fine dual basis functions 5317bceba477SMatthew G. Knepley Evaluate coarse basis on fine dual basis quad points 5318bceba477SMatthew G. Knepley Sum 5319bceba477SMatthew G. Knepley Update local element matrix 5320bceba477SMatthew G. Knepley Accumulate to interpolation matrix 5321bceba477SMatthew G. Knepley 5322bceba477SMatthew G. Knepley Can extend PetscFEIntegrateJacobian_Basic() to do a specialized cell loop 5323bceba477SMatthew G. Knepley */ 5324bceba477SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 5325bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 5326bceba477SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 5327bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 5328bceba477SMatthew G. Knepley /* We need to preallocate properly */ 5329bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 5330bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 5331bceba477SMatthew G. Knepley ierr = MatSetType(*interpolation, dmCoarse->mattype);CHKERRQ(ierr); 5332a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 5333a063dac3SMatthew G. Knepley ierr = DMPlexComputeInterpolatorFEM(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr); 53345d1c2e58SMatthew G. Knepley /* Use naive scaling */ 53355d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 5336a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 5337a063dac3SMatthew G. Knepley } 5338bceba477SMatthew G. Knepley 5339a063dac3SMatthew G. Knepley #undef __FUNCT__ 5340a063dac3SMatthew G. Knepley #define __FUNCT__ "DMCreateInjection_Plex" 5341a063dac3SMatthew G. Knepley PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, VecScatter *ctx) 5342a063dac3SMatthew G. Knepley { 534390748bafSMatthew G. Knepley PetscErrorCode ierr; 534490748bafSMatthew G. Knepley 5345a063dac3SMatthew G. Knepley PetscFunctionBegin; 53467c927364SMatthew G. Knepley ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, ctx, NULL);CHKERRQ(ierr); 5347bceba477SMatthew G. Knepley PetscFunctionReturn(0); 5348bceba477SMatthew G. Knepley } 5349bceba477SMatthew G. Knepley 5350bceba477SMatthew G. Knepley #undef __FUNCT__ 5351fd59a867SMatthew G. Knepley #define __FUNCT__ "DMCreateDefaultSection_Plex" 5352fd59a867SMatthew G. Knepley PetscErrorCode DMCreateDefaultSection_Plex(DM dm) 5353fd59a867SMatthew G. Knepley { 5354fd59a867SMatthew G. Knepley PetscSection section; 5355fd59a867SMatthew G. Knepley IS *bcPoints; 5356ebb3236fSMatthew G. Knepley PetscBool *isFE; 5357286d8613SMatthew G. Knepley PetscInt *bcFields, *numComp, *numDof; 5358ebb3236fSMatthew G. Knepley PetscInt depth, dim, numBd, numBC = 0, numFields, bd, bc = 0, f; 5359ebb3236fSMatthew G. Knepley PetscInt cStart, cEnd, cEndInterior; 5360fd59a867SMatthew G. Knepley PetscErrorCode ierr; 5361fd59a867SMatthew G. Knepley 5362fd59a867SMatthew G. Knepley PetscFunctionBegin; 5363ebb3236fSMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 5364ebb3236fSMatthew G. Knepley /* FE and FV boundary conditions are handled slightly differently */ 5365ebb3236fSMatthew G. Knepley ierr = PetscMalloc1(numFields, &isFE);CHKERRQ(ierr); 5366ebb3236fSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5367ebb3236fSMatthew G. Knepley PetscObject obj; 5368ebb3236fSMatthew G. Knepley PetscClassId id; 5369ebb3236fSMatthew G. Knepley 5370ebb3236fSMatthew G. Knepley ierr = DMGetField(dm, f, &obj);CHKERRQ(ierr); 5371ebb3236fSMatthew G. Knepley ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr); 5372ebb3236fSMatthew G. Knepley if (id == PETSCFE_CLASSID) {isFE[f] = PETSC_TRUE;} 5373ebb3236fSMatthew G. Knepley else if (id == PETSCFV_CLASSID) {isFE[f] = PETSC_FALSE;} 5374ebb3236fSMatthew G. Knepley else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f); 5375ebb3236fSMatthew G. Knepley } 5376ebb3236fSMatthew G. Knepley /* Allocate boundary point storage */ 5377286d8613SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5378c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5379ebb3236fSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5380ebb3236fSMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cEndInterior, NULL, NULL, NULL);CHKERRQ(ierr); 5381fd59a867SMatthew G. Knepley ierr = DMPlexGetNumBoundary(dm, &numBd);CHKERRQ(ierr); 5382fd59a867SMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5383fd59a867SMatthew G. Knepley PetscBool isEssential; 538463d5297fSMatthew G. Knepley ierr = DMPlexGetBoundary(dm, bd, &isEssential, NULL, NULL, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 5385fd59a867SMatthew G. Knepley if (isEssential) ++numBC; 5386fd59a867SMatthew G. Knepley } 5387ebb3236fSMatthew G. Knepley for (f = 0; f < numFields; ++f) if (!isFE[f] && cEndInterior >= 0) ++numBC; 5388fd59a867SMatthew G. Knepley ierr = PetscMalloc2(numBC,&bcFields,numBC,&bcPoints);CHKERRQ(ierr); 5389ebb3236fSMatthew G. Knepley /* Constrain ghost cells for FV */ 5390ebb3236fSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5391ebb3236fSMatthew G. Knepley PetscInt *newidx, c; 5392ebb3236fSMatthew G. Knepley 5393ebb3236fSMatthew G. Knepley if (isFE[f] || cEndInterior < 0) continue; 5394ebb3236fSMatthew G. Knepley ierr = PetscMalloc1(cEnd-cEndInterior,&newidx);CHKERRQ(ierr); 5395ebb3236fSMatthew G. Knepley for (c = cEndInterior; c < cEnd; ++c) newidx[c-cEndInterior] = c; 5396ebb3236fSMatthew G. Knepley bcFields[bc] = f; 5397ebb3236fSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), cEnd-cEndInterior, newidx, PETSC_OWN_POINTER, &bcPoints[bc++]);CHKERRQ(ierr); 5398ebb3236fSMatthew G. Knepley } 5399ebb3236fSMatthew G. Knepley /* Handle FEM Dirichlet boundaries */ 5400ebb3236fSMatthew G. Knepley for (bd = 0; bd < numBd; ++bd) { 5401fd59a867SMatthew G. Knepley const char *bdLabel; 5402fd59a867SMatthew G. Knepley DMLabel label; 5403fd59a867SMatthew G. Knepley const PetscInt *values; 54047391c1cbSMatthew G. Knepley PetscInt bd2, field, numValues; 5405c945be8dSMatthew G. Knepley PetscBool isEssential, duplicate = PETSC_FALSE; 5406fd59a867SMatthew G. Knepley 540763d5297fSMatthew G. Knepley ierr = DMPlexGetBoundary(dm, bd, &isEssential, NULL, &bdLabel, &field, NULL, &numValues, &values, NULL);CHKERRQ(ierr); 5408fd59a867SMatthew G. Knepley ierr = DMPlexGetLabel(dm, bdLabel, &label);CHKERRQ(ierr); 5409ebb3236fSMatthew G. Knepley /* Only want to modify label once */ 54107391c1cbSMatthew G. Knepley for (bd2 = 0; bd2 < bd; ++bd2) { 54117391c1cbSMatthew G. Knepley const char *bdname; 54122f81efd2SMatthew G. Knepley ierr = DMPlexGetBoundary(dm, bd2, NULL, NULL, &bdname, NULL, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 54137391c1cbSMatthew G. Knepley ierr = PetscStrcmp(bdname, bdLabel, &duplicate);CHKERRQ(ierr); 54147391c1cbSMatthew G. Knepley if (duplicate) break; 54157391c1cbSMatthew G. Knepley } 5416ebb3236fSMatthew G. Knepley if (!duplicate && (isFE[field])) { 5417fd59a867SMatthew G. Knepley ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); 541832720fa8SMatthew G. Knepley ierr = DMPlexLabelAddCells(dm, label);CHKERRQ(ierr); 54197391c1cbSMatthew G. Knepley } 5420ebb3236fSMatthew G. Knepley /* Filter out cells, if you actually want to constrain cells you need to do things by hand right now */ 5421fd59a867SMatthew G. Knepley if (isEssential) { 542293a5981aSMatthew G. Knepley PetscInt *newidx; 5423ebb3236fSMatthew G. Knepley PetscInt n, newn = 0, p, v; 542493a5981aSMatthew G. Knepley 5425fd59a867SMatthew G. Knepley bcFields[bc] = field; 5426ebb3236fSMatthew G. Knepley for (v = 0; v < numValues; ++v) { 5427ebb3236fSMatthew G. Knepley IS tmp; 5428ebb3236fSMatthew G. Knepley const PetscInt *idx; 5429ebb3236fSMatthew G. Knepley 5430ebb3236fSMatthew G. Knepley ierr = DMPlexGetStratumIS(dm, bdLabel, values[v], &tmp);CHKERRQ(ierr); 5431ebb3236fSMatthew G. Knepley if (!tmp) continue; 543293a5981aSMatthew G. Knepley ierr = ISGetLocalSize(tmp, &n);CHKERRQ(ierr); 543393a5981aSMatthew G. Knepley ierr = ISGetIndices(tmp, &idx);CHKERRQ(ierr); 5434ebb3236fSMatthew G. Knepley if (isFE[field]) { 543593a5981aSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] < cStart) || (idx[p] >= cEnd)) ++newn; 5436ebb3236fSMatthew G. Knepley } else { 5437ebb3236fSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] >= cStart) || (idx[p] < cEnd)) ++newn; 5438ebb3236fSMatthew G. Knepley } 543993a5981aSMatthew G. Knepley ierr = ISRestoreIndices(tmp, &idx);CHKERRQ(ierr); 544093a5981aSMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 5441fd59a867SMatthew G. Knepley } 5442ebb3236fSMatthew G. Knepley ierr = PetscMalloc1(newn,&newidx);CHKERRQ(ierr); 5443ebb3236fSMatthew G. Knepley newn = 0; 5444ebb3236fSMatthew G. Knepley for (v = 0; v < numValues; ++v) { 5445ebb3236fSMatthew G. Knepley IS tmp; 5446ebb3236fSMatthew G. Knepley const PetscInt *idx; 5447ebb3236fSMatthew G. Knepley 5448ebb3236fSMatthew G. Knepley ierr = DMPlexGetStratumIS(dm, bdLabel, values[v], &tmp);CHKERRQ(ierr); 5449ebb3236fSMatthew G. Knepley if (!tmp) continue; 5450ebb3236fSMatthew G. Knepley ierr = ISGetLocalSize(tmp, &n);CHKERRQ(ierr); 5451ebb3236fSMatthew G. Knepley ierr = ISGetIndices(tmp, &idx);CHKERRQ(ierr); 5452ebb3236fSMatthew G. Knepley if (isFE[field]) { 5453ebb3236fSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] < cStart) || (idx[p] >= cEnd)) newidx[newn++] = idx[p]; 5454ebb3236fSMatthew G. Knepley } else { 5455ebb3236fSMatthew G. Knepley for (p = 0; p < n; ++p) if ((idx[p] >= cStart) || (idx[p] < cEnd)) newidx[newn++] = idx[p]; 5456ebb3236fSMatthew G. Knepley } 5457ebb3236fSMatthew G. Knepley ierr = ISRestoreIndices(tmp, &idx);CHKERRQ(ierr); 5458ebb3236fSMatthew G. Knepley ierr = ISDestroy(&tmp);CHKERRQ(ierr); 5459ebb3236fSMatthew G. Knepley } 5460ebb3236fSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), newn, newidx, PETSC_OWN_POINTER, &bcPoints[bc++]);CHKERRQ(ierr); 5461ebb3236fSMatthew G. Knepley } 5462fd59a867SMatthew G. Knepley } 5463fd59a867SMatthew G. Knepley /* Handle discretization */ 5464ebb3236fSMatthew G. Knepley ierr = PetscCalloc2(numFields,&numComp,numFields*(dim+1),&numDof);CHKERRQ(ierr); 5465fd59a867SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 54660bacfa0aSMatthew G. Knepley PetscObject obj; 54670bacfa0aSMatthew G. Knepley 54680bacfa0aSMatthew G. Knepley ierr = DMGetField(dm, f, &obj);CHKERRQ(ierr); 5469ebb3236fSMatthew G. Knepley if (isFE[f]) { 54700bacfa0aSMatthew G. Knepley PetscFE fe = (PetscFE) obj; 5471286d8613SMatthew G. Knepley const PetscInt *numFieldDof; 5472fd59a867SMatthew G. Knepley PetscInt d; 5473fd59a867SMatthew G. Knepley 5474fd59a867SMatthew G. Knepley ierr = PetscFEGetNumComponents(fe, &numComp[f]);CHKERRQ(ierr); 5475286d8613SMatthew G. Knepley ierr = PetscFEGetNumDof(fe, &numFieldDof);CHKERRQ(ierr); 5476286d8613SMatthew G. Knepley for (d = 0; d < dim+1; ++d) numDof[f*(dim+1)+d] = numFieldDof[d]; 5477ebb3236fSMatthew G. Knepley } else { 54780bacfa0aSMatthew G. Knepley PetscFV fv = (PetscFV) obj; 54790bacfa0aSMatthew G. Knepley 54800bacfa0aSMatthew G. Knepley ierr = PetscFVGetNumComponents(fv, &numComp[f]);CHKERRQ(ierr); 54810bacfa0aSMatthew G. Knepley numDof[f*(dim+1)+dim] = numComp[f]; 5482ebb3236fSMatthew G. Knepley } 5483fd59a867SMatthew G. Knepley } 5484286d8613SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5485286d8613SMatthew G. Knepley PetscInt d; 5486286d8613SMatthew G. Knepley for (d = 1; d < dim; ++d) { 5487286d8613SMatthew 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."); 5488286d8613SMatthew G. Knepley } 5489286d8613SMatthew G. Knepley } 5490f8f126e8SMatthew G. Knepley ierr = DMPlexCreateSection(dm, dim, numFields, numComp, numDof, numBC, bcFields, bcPoints, NULL, §ion);CHKERRQ(ierr); 5491fd59a867SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5492fd59a867SMatthew G. Knepley PetscFE fe; 5493fd59a867SMatthew G. Knepley const char *name; 549418abd763SMatthew G. Knepley 549518abd763SMatthew G. Knepley ierr = DMGetField(dm, f, (PetscObject *) &fe);CHKERRQ(ierr); 5496fd59a867SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) fe, &name);CHKERRQ(ierr); 5497fd59a867SMatthew G. Knepley ierr = PetscSectionSetFieldName(section, f, name);CHKERRQ(ierr); 5498fd59a867SMatthew G. Knepley } 5499fd59a867SMatthew G. Knepley ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); 5500fd59a867SMatthew G. Knepley ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 5501fd59a867SMatthew G. Knepley for (bc = 0; bc < numBC; ++bc) {ierr = ISDestroy(&bcPoints[bc]);CHKERRQ(ierr);} 5502fd59a867SMatthew G. Knepley ierr = PetscFree2(bcFields,bcPoints);CHKERRQ(ierr); 5503286d8613SMatthew G. Knepley ierr = PetscFree2(numComp,numDof);CHKERRQ(ierr); 5504ebb3236fSMatthew G. Knepley ierr = PetscFree(isFE);CHKERRQ(ierr); 5505bceba477SMatthew G. Knepley PetscFunctionReturn(0); 5506bceba477SMatthew G. Knepley } 5507bceba477SMatthew G. Knepley 5508bceba477SMatthew G. Knepley #undef __FUNCT__ 55093913d7c8SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCoarseDM" 55103913d7c8SMatthew G. Knepley /*@ 55113913d7c8SMatthew G. Knepley DMPlexGetCoarseDM - Get the coarse mesh from which this was obtained by refinement 55123913d7c8SMatthew G. Knepley 55133913d7c8SMatthew G. Knepley Input Parameter: 55143913d7c8SMatthew G. Knepley . dm - The DMPlex object 55153913d7c8SMatthew G. Knepley 55163913d7c8SMatthew G. Knepley Output Parameter: 55173913d7c8SMatthew G. Knepley . cdm - The coarse DM 55183913d7c8SMatthew G. Knepley 55193913d7c8SMatthew G. Knepley Level: intermediate 55203913d7c8SMatthew G. Knepley 55213913d7c8SMatthew G. Knepley .seealso: DMPlexSetCoarseDM() 55223913d7c8SMatthew G. Knepley @*/ 55233913d7c8SMatthew G. Knepley PetscErrorCode DMPlexGetCoarseDM(DM dm, DM *cdm) 55243913d7c8SMatthew G. Knepley { 55253913d7c8SMatthew G. Knepley PetscFunctionBegin; 55263913d7c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55273913d7c8SMatthew G. Knepley PetscValidPointer(cdm, 2); 55283913d7c8SMatthew G. Knepley *cdm = ((DM_Plex *) dm->data)->coarseMesh; 55293913d7c8SMatthew G. Knepley PetscFunctionReturn(0); 55303913d7c8SMatthew G. Knepley } 55313913d7c8SMatthew G. Knepley 55323913d7c8SMatthew G. Knepley #undef __FUNCT__ 55333913d7c8SMatthew G. Knepley #define __FUNCT__ "DMPlexSetCoarseDM" 55343913d7c8SMatthew G. Knepley /*@ 55353913d7c8SMatthew G. Knepley DMPlexSetCoarseDM - Set the coarse mesh from which this was obtained by refinement 55363913d7c8SMatthew G. Knepley 55373913d7c8SMatthew G. Knepley Input Parameters: 55383913d7c8SMatthew G. Knepley + dm - The DMPlex object 55393913d7c8SMatthew G. Knepley - cdm - The coarse DM 55403913d7c8SMatthew G. Knepley 55413913d7c8SMatthew G. Knepley Level: intermediate 55423913d7c8SMatthew G. Knepley 55433913d7c8SMatthew G. Knepley .seealso: DMPlexGetCoarseDM() 55443913d7c8SMatthew G. Knepley @*/ 55453913d7c8SMatthew G. Knepley PetscErrorCode DMPlexSetCoarseDM(DM dm, DM cdm) 55463913d7c8SMatthew G. Knepley { 55473913d7c8SMatthew G. Knepley DM_Plex *mesh; 55483913d7c8SMatthew G. Knepley PetscErrorCode ierr; 55493913d7c8SMatthew G. Knepley 55503913d7c8SMatthew G. Knepley PetscFunctionBegin; 55513913d7c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55523913d7c8SMatthew G. Knepley if (cdm) PetscValidHeaderSpecific(cdm, DM_CLASSID, 2); 55533913d7c8SMatthew G. Knepley mesh = (DM_Plex *) dm->data; 55543913d7c8SMatthew G. Knepley ierr = DMDestroy(&mesh->coarseMesh);CHKERRQ(ierr); 55553913d7c8SMatthew G. Knepley mesh->coarseMesh = cdm; 55563913d7c8SMatthew G. Knepley ierr = PetscObjectReference((PetscObject) mesh->coarseMesh);CHKERRQ(ierr); 55573913d7c8SMatthew G. Knepley PetscFunctionReturn(0); 55583913d7c8SMatthew G. Knepley } 5559a68b90caSToby Isaac 5560f7c74593SToby Isaac /* anchors */ 5561a68b90caSToby Isaac #undef __FUNCT__ 5562a17985deSToby Isaac #define __FUNCT__ "DMPlexGetAnchors" 5563a68b90caSToby Isaac /*@ 5564f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 5565f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 5566a68b90caSToby Isaac 5567e228b242SToby Isaac not collective 5568a68b90caSToby Isaac 5569a68b90caSToby Isaac Input Parameters: 5570a68b90caSToby Isaac . dm - The DMPlex object 5571a68b90caSToby Isaac 5572a68b90caSToby Isaac Output Parameters: 5573a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 5574a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 5575a68b90caSToby Isaac 5576a68b90caSToby Isaac 5577a68b90caSToby Isaac Level: intermediate 5578a68b90caSToby Isaac 5579f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 5580a68b90caSToby Isaac @*/ 5581a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 5582a68b90caSToby Isaac { 5583a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 558441e6d900SToby Isaac PetscErrorCode ierr; 5585a68b90caSToby Isaac 5586a68b90caSToby Isaac PetscFunctionBegin; 5587a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 558841e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 5589a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 5590a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 5591a68b90caSToby Isaac PetscFunctionReturn(0); 5592a68b90caSToby Isaac } 5593a68b90caSToby Isaac 5594a68b90caSToby Isaac #undef __FUNCT__ 5595a17985deSToby Isaac #define __FUNCT__ "DMPlexSetAnchors" 5596a68b90caSToby Isaac /*@ 5597f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 5598f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 5599a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 5600a68b90caSToby Isaac 5601a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 5602f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 5603a68b90caSToby Isaac 5604e228b242SToby Isaac collective on dm 5605a68b90caSToby Isaac 5606a68b90caSToby Isaac Input Parameters: 5607a68b90caSToby Isaac + dm - The DMPlex object 5608e228b242SToby 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). 5609e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 5610a68b90caSToby Isaac 5611a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 5612a68b90caSToby Isaac 5613a68b90caSToby Isaac Level: intermediate 5614a68b90caSToby Isaac 5615f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 5616a68b90caSToby Isaac @*/ 5617a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 5618a68b90caSToby Isaac { 5619a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 5620e228b242SToby Isaac PetscMPIInt result; 5621a68b90caSToby Isaac PetscErrorCode ierr; 5622a68b90caSToby Isaac 5623a68b90caSToby Isaac PetscFunctionBegin; 5624a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5625e228b242SToby Isaac if (anchorSection) { 5626e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 5627e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRQ(ierr); 5628e228b242SToby Isaac if (result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 5629e228b242SToby Isaac } 5630e228b242SToby Isaac if (anchorIS) { 5631e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 5632e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRQ(ierr); 5633e228b242SToby Isaac if (result != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 5634e228b242SToby Isaac } 5635a68b90caSToby Isaac 5636a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 5637a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 5638a68b90caSToby Isaac plex->anchorSection = anchorSection; 5639a68b90caSToby Isaac 5640a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 5641a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 5642a68b90caSToby Isaac plex->anchorIS = anchorIS; 5643a68b90caSToby Isaac 5644a68b90caSToby Isaac #if defined(PETSC_USE_DEBUG) 5645a68b90caSToby Isaac if (anchorIS && anchorSection) { 5646a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 5647a68b90caSToby Isaac const PetscInt *anchors; 5648a68b90caSToby Isaac 5649a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 5650a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 5651a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 5652a68b90caSToby Isaac for (a = 0; a < size; a++) { 5653a68b90caSToby Isaac PetscInt p; 5654a68b90caSToby Isaac 5655a68b90caSToby Isaac p = anchors[a]; 5656a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 5657a68b90caSToby Isaac PetscInt dof; 5658a68b90caSToby Isaac 5659a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 5660a68b90caSToby Isaac if (dof) { 5661a68b90caSToby Isaac PetscErrorCode ierr2; 5662a68b90caSToby Isaac 5663a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 5664a68b90caSToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %d cannot be constrained and an anchor",p); 5665a68b90caSToby Isaac } 5666a68b90caSToby Isaac } 5667a68b90caSToby Isaac } 5668a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 5669a68b90caSToby Isaac } 5670a68b90caSToby Isaac #endif 5671f7c74593SToby Isaac /* reset the generic constraints */ 5672f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 5673a68b90caSToby Isaac PetscFunctionReturn(0); 5674a68b90caSToby Isaac } 5675a68b90caSToby Isaac 5676a68b90caSToby Isaac #undef __FUNCT__ 5677f7c74593SToby Isaac #define __FUNCT__ "DMPlexCreateConstraintSection_Anchors" 5678f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 5679a68b90caSToby Isaac { 5680f7c74593SToby Isaac PetscSection anchorSection; 5681a68b90caSToby Isaac PetscInt pStart, pEnd, p, dof, numFields, f; 5682a68b90caSToby Isaac PetscErrorCode ierr; 5683a68b90caSToby Isaac 5684a68b90caSToby Isaac PetscFunctionBegin; 5685a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5686a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 5687e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 5688a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 5689a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 5690a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 5691a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 5692a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 5693a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 5694a68b90caSToby Isaac if (dof) { 5695a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 5696a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 5697a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 5698a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 5699a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 5700a68b90caSToby Isaac } 5701a68b90caSToby Isaac } 5702a68b90caSToby Isaac } 5703a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 5704a68b90caSToby Isaac PetscFunctionReturn(0); 5705a68b90caSToby Isaac } 5706a68b90caSToby Isaac 5707a68b90caSToby Isaac #undef __FUNCT__ 5708f7c74593SToby Isaac #define __FUNCT__ "DMPlexCreateConstraintMatrix_Anchors" 5709f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 5710a68b90caSToby Isaac { 5711f7c74593SToby Isaac PetscSection aSec; 57120ac89760SToby Isaac PetscInt pStart, pEnd, p, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 57130ac89760SToby Isaac const PetscInt *anchors; 57140ac89760SToby Isaac PetscInt numFields, f; 571566ad2231SToby Isaac IS aIS; 57160ac89760SToby Isaac PetscErrorCode ierr; 57170ac89760SToby Isaac 57180ac89760SToby Isaac PetscFunctionBegin; 57190ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 57200ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 57210ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 57220ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 57230ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 57240ac89760SToby Isaac ierr = MatSetType(*cMat,MATSEQAIJ); 5725a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 572666ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 57270ac89760SToby Isaac ierr = PetscSectionGetChart(aSec,&pStart,&pEnd);CHKERRQ(ierr); 57280ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 57290ac89760SToby Isaac i[0] = 0; 57300ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 57310ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 57320ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&dof);CHKERRQ(ierr); 57330ac89760SToby Isaac if (!dof) continue; 57340ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&off);CHKERRQ(ierr); 57350ac89760SToby Isaac if (numFields) { 57360ac89760SToby Isaac for (f = 0; f < numFields; f++) { 57370ac89760SToby Isaac annz = 0; 57380ac89760SToby Isaac for (q = 0; q < dof; q++) { 57390ac89760SToby Isaac a = anchors[off + q]; 57400ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 57410ac89760SToby Isaac annz += aDof; 57420ac89760SToby Isaac } 57430ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 57440ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 57450ac89760SToby Isaac for (q = 0; q < dof; q++) { 57460ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 57470ac89760SToby Isaac } 57480ac89760SToby Isaac } 57490ac89760SToby Isaac } 57500ac89760SToby Isaac else { 57510ac89760SToby Isaac annz = 0; 57520ac89760SToby Isaac for (q = 0; q < dof; q++) { 57530ac89760SToby Isaac a = anchors[off + q]; 57540ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 57550ac89760SToby Isaac annz += aDof; 57560ac89760SToby Isaac } 57570ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 57580ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 57590ac89760SToby Isaac for (q = 0; q < dof; q++) { 57600ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 57610ac89760SToby Isaac } 57620ac89760SToby Isaac } 57630ac89760SToby Isaac } 57640ac89760SToby Isaac nnz = i[m]; 57650ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 57660ac89760SToby Isaac offset = 0; 57670ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 57680ac89760SToby Isaac if (numFields) { 57690ac89760SToby Isaac for (f = 0; f < numFields; f++) { 57700ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 57710ac89760SToby Isaac for (q = 0; q < dof; q++) { 57720ac89760SToby Isaac PetscInt rDof, rOff, r; 57730ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 57740ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 57750ac89760SToby Isaac for (r = 0; r < rDof; r++) { 57760ac89760SToby Isaac PetscInt s; 57770ac89760SToby Isaac 57780ac89760SToby Isaac a = anchors[rOff + r]; 57790ac89760SToby Isaac 57800ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 57810ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 57820ac89760SToby Isaac for (s = 0; s < aDof; s++) { 57830ac89760SToby Isaac j[offset++] = aOff + s; 57840ac89760SToby Isaac } 57850ac89760SToby Isaac } 57860ac89760SToby Isaac } 57870ac89760SToby Isaac } 57880ac89760SToby Isaac } 57890ac89760SToby Isaac else { 57900ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 57910ac89760SToby Isaac for (q = 0; q < dof; q++) { 57920ac89760SToby Isaac PetscInt rDof, rOff, r; 57930ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 57940ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 57950ac89760SToby Isaac for (r = 0; r < rDof; r++) { 57960ac89760SToby Isaac PetscInt s; 57970ac89760SToby Isaac 57980ac89760SToby Isaac a = anchors[rOff + r]; 57990ac89760SToby Isaac 58000ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 58010ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 58020ac89760SToby Isaac for (s = 0; s < aDof; s++) { 58030ac89760SToby Isaac j[offset++] = aOff + s; 58040ac89760SToby Isaac } 58050ac89760SToby Isaac } 58060ac89760SToby Isaac } 58070ac89760SToby Isaac } 58080ac89760SToby Isaac } 58090ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 58100ac89760SToby Isaac ierr = PetscFree2(i,j);CHKERRQ(ierr); 581166ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 58120ac89760SToby Isaac PetscFunctionReturn(0); 58130ac89760SToby Isaac } 58140ac89760SToby Isaac 58150ac89760SToby Isaac #undef __FUNCT__ 581666ad2231SToby Isaac #define __FUNCT__ "DMCreateDefaultConstraints_Plex" 581766ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 581866ad2231SToby Isaac { 5819f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 5820f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 582166ad2231SToby Isaac Mat cMat; 582266ad2231SToby Isaac PetscErrorCode ierr; 582366ad2231SToby Isaac 582466ad2231SToby Isaac PetscFunctionBegin; 582566ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5826a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 582766ad2231SToby Isaac if (anchorSection) { 5828e228b242SToby Isaac PetscDS ds; 5829e228b242SToby Isaac PetscInt nf; 5830e228b242SToby Isaac 5831f7c74593SToby Isaac ierr = DMGetDefaultSection(dm,§ion);CHKERRQ(ierr); 5832f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 5833f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 5834e228b242SToby Isaac ierr = DMGetDS(dm,&ds);CHKERRQ(ierr); 5835e228b242SToby Isaac ierr = PetscDSGetNumFields(ds,&nf); 5836e228b242SToby Isaac if (nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 583766ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 583866ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 583966ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 584066ad2231SToby Isaac } 584166ad2231SToby Isaac PetscFunctionReturn(0); 584266ad2231SToby Isaac } 5843