/* This takes as input the coordinates for each vertex */ PetscErrorCode DMPlexBuildCoordinates_Private(DM dm, PetscInt spaceDim, PetscInt numCells, PetscInt numVertices, const double vertexCoords[]) { PetscSection coordSection; Vec coordinates; PetscScalar *coords; PetscInt coordSize, v, d; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, numCells, numCells + numVertices);CHKERRQ(ierr); for (v = numCells; v < numCells+numVertices; ++v) { ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); for (v = 0; v < numVertices; ++v) { for (d = 0; d < spaceDim; ++d) { coords[v*spaceDim+d] = vertexCoords[v*spaceDim+d]; } } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMPlexCopyCoordinates(DM dmA, DM dmB) { Vec coordinatesA, coordinatesB; PetscSection coordSectionA, coordSectionB; PetscScalar *coordsA, *coordsB; PetscInt spaceDim, vStartA, vStartB, vEndA, vEndB, coordSizeB, v, d; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMPlexGetDepthStratum(dmA, 0, &vStartA, &vEndA);CHKERRQ(ierr); ierr = DMPlexGetDepthStratum(dmB, 0, &vStartB, &vEndB);CHKERRQ(ierr); if ((vEndA-vStartA) != (vEndB-vStartB)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "The number of vertices in first DM %d != %d in the second DM", vEndA-vStartA, vEndB-vStartB); ierr = DMPlexGetCoordinateSection(dmA, &coordSectionA);CHKERRQ(ierr); ierr = DMPlexGetCoordinateSection(dmB, &coordSectionB);CHKERRQ(ierr); ierr = PetscSectionSetNumFields(coordSectionB, 1);CHKERRQ(ierr); ierr = PetscSectionGetFieldComponents(coordSectionA, 0, &spaceDim);CHKERRQ(ierr); ierr = PetscSectionSetFieldComponents(coordSectionB, 0, spaceDim);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSectionB, vStartB, vEndB);CHKERRQ(ierr); for (v = vStartB; v < vEndB; ++v) { ierr = PetscSectionSetDof(coordSectionB, v, spaceDim);CHKERRQ(ierr); ierr = PetscSectionSetFieldDof(coordSectionB, v, 0, spaceDim);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSectionB);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSectionB, &coordSizeB);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dmA, &coordinatesA);CHKERRQ(ierr); ierr = VecCreate(PetscObjectComm((PetscObject) dmB), &coordinatesB);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coordinatesB, "coordinates");CHKERRQ(ierr); ierr = VecSetSizes(coordinatesB, coordSizeB, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinatesB);CHKERRQ(ierr); ierr = VecGetArray(coordinatesA, &coordsA);CHKERRQ(ierr); ierr = VecGetArray(coordinatesB, &coordsB);CHKERRQ(ierr); for (v = 0; v < vEndB-vStartB; ++v) { for (d = 0; d < spaceDim; ++d) { coordsB[v*spaceDim+d] = coordsA[v*spaceDim+d]; } } ierr = VecRestoreArray(coordinatesA, &coordsA);CHKERRQ(ierr); ierr = VecRestoreArray(coordinatesB, &coordsB);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dmB, coordinatesB);CHKERRQ(ierr); ierr = VecDestroy(&coordinatesB);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* This takes as input the raw Hasse Diagram data */ PetscErrorCode DMPlexCreateFromDAG(DM dm, PetscInt depth, const PetscInt numPoints[], const PetscInt coneSize[], const PetscInt cones[], const PetscInt coneOrientations[], const PetscScalar vertexCoords[]) { Vec coordinates; PetscSection coordSection; PetscScalar *coords; PetscInt coordSize, firstVertex = numPoints[depth], pStart = 0, pEnd = 0, p, v, dim, d, off; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); for (d = 0; d <= depth; ++d) pEnd += numPoints[d]; ierr = DMPlexSetChart(dm, pStart, pEnd);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { ierr = DMPlexSetConeSize(dm, p, coneSize[p-pStart]);CHKERRQ(ierr); } ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ for (p = pStart, off = 0; p < pEnd; off += coneSize[p-pStart], ++p) { ierr = DMPlexSetCone(dm, p, &cones[off]);CHKERRQ(ierr); ierr = DMPlexSetConeOrientation(dm, p, &coneOrientations[off]);CHKERRQ(ierr); } ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); ierr = DMPlexStratify(dm);CHKERRQ(ierr); /* Build coordinates */ ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numPoints[0]);CHKERRQ(ierr); for (v = firstVertex; v < firstVertex+numPoints[0]; ++v) { ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); for (v = 0; v < numPoints[0]; ++v) { PetscInt off; ierr = PetscSectionGetOffset(coordSection, v+firstVertex, &off);CHKERRQ(ierr); for (d = 0; d < dim; ++d) { coords[off+d] = vertexCoords[v*dim+d]; } } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ChangeCoordinates(DM dm, PetscInt spaceDim, PetscScalar vertexCoords[]) { PetscSection coordSection; Vec coordinates; PetscScalar *coords; PetscInt vStart, vEnd, v, d, coordSize; PetscErrorCode ierr; PetscFunctionBegin; ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); ierr = PetscSectionSetFieldComponents(coordSection, 0, spaceDim);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, vStart, vEnd);CHKERRQ(ierr); for (v = vStart; v < vEnd; ++v) { ierr = PetscSectionSetDof(coordSection, v, spaceDim);CHKERRQ(ierr); ierr = PetscSectionSetFieldDof(coordSection, v, 0, spaceDim);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(PetscObjectComm((PetscObject) dm), &coordinates);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); for (v = vStart; v < vEnd; ++v) { PetscInt off; ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); for (d = 0; d < spaceDim; ++d) { coords[off+d] = vertexCoords[(v-vStart)*spaceDim+d]; } } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); ierr = DMSetFromOptions(dm);CHKERRQ(ierr); PetscFunctionReturn(0); }
void PETSC_STDCALL dmplexgetcoordinatesection_(DM dm,PetscSection *section, int *__ierr ){ *__ierr = DMPlexGetCoordinateSection( (DM)PetscToPointer((dm) ),section); }
/* Simple square boundary: 18--5-17--4--16 | | | 6 10 3 | | | 19-11-20--9--15 | | | 7 8 2 | | | 12--0-13--1--14 */ PetscErrorCode DMPlexCreateSquareBoundary(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) { PetscInt numVertices = (edges[0]+1)*(edges[1]+1); PetscInt numEdges = edges[0]*(edges[1]+1) + (edges[0]+1)*edges[1]; PetscInt markerTop = 1; PetscInt markerBottom = 1; PetscInt markerRight = 1; PetscInt markerLeft = 1; PetscBool markerSeparate = PETSC_FALSE; Vec coordinates; PetscSection coordSection; PetscScalar *coords; PetscInt coordSize; PetscMPIInt rank; PetscInt v, vx, vy; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscOptionsGetBool(((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); if (markerSeparate) { markerTop = 1; markerBottom = 0; markerRight = 0; markerLeft = 0; } ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); if (!rank) { PetscInt e, ex, ey; ierr = DMPlexSetChart(dm, 0, numEdges+numVertices);CHKERRQ(ierr); for (e = 0; e < numEdges; ++e) { ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); } ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ for (vx = 0; vx <= edges[0]; vx++) { for (ey = 0; ey < edges[1]; ey++) { PetscInt edge = vx*edges[1] + ey + edges[0]*(edges[1]+1); PetscInt vertex = ey*(edges[0]+1) + vx + numEdges; PetscInt cone[2]; cone[0] = vertex; cone[1] = vertex+edges[0]+1; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); if (vx == edges[0]) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); if (ey == edges[1]-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); } } else if (vx == 0) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); if (ey == edges[1]-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); } } } } for (vy = 0; vy <= edges[1]; vy++) { for (ex = 0; ex < edges[0]; ex++) { PetscInt edge = vy*edges[0] + ex; PetscInt vertex = vy*(edges[0]+1) + ex + numEdges; PetscInt cone[2]; cone[0] = vertex; cone[1] = vertex+1; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); if (vy == edges[1]) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); if (ex == edges[0]-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); } } else if (vy == 0) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); if (ex == edges[0]-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); } } } } } ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); ierr = DMPlexStratify(dm);CHKERRQ(ierr); /* Build coordinates */ ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, numEdges, numEdges + numVertices);CHKERRQ(ierr); for (v = numEdges; v < numEdges+numVertices; ++v) { ierr = PetscSectionSetDof(coordSection, v, 2);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); for (vy = 0; vy <= edges[1]; ++vy) { for (vx = 0; vx <= edges[0]; ++vx) { coords[(vy*(edges[0]+1)+vx)*2+0] = lower[0] + ((upper[0] - lower[0])/edges[0])*vx; coords[(vy*(edges[0]+1)+vx)*2+1] = lower[1] + ((upper[1] - lower[1])/edges[1])*vy; } } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Simple square mesh: 22--8-23--9--24 | | | 13 2 14 3 15 | | | 19--6-20--7--21 | | | 10 0 11 1 12 | | | 16--4-17--5--18 */ PetscErrorCode DMPlexCreateSquareMesh(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt edges[]) { PetscInt markerTop = 1; PetscInt markerBottom = 1; PetscInt markerRight = 1; PetscInt markerLeft = 1; PetscBool markerSeparate = PETSC_FALSE; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); ierr = PetscOptionsGetBool(((PetscObject) dm)->prefix, "-dm_plex_separate_marker", &markerSeparate, NULL);CHKERRQ(ierr); if (markerSeparate) { markerTop = 3; markerBottom = 1; markerRight = 2; markerLeft = 4; } { const PetscInt numXEdges = !rank ? edges[0] : 0; const PetscInt numYEdges = !rank ? edges[1] : 0; const PetscInt numXVertices = !rank ? edges[0]+1 : 0; const PetscInt numYVertices = !rank ? edges[1]+1 : 0; const PetscInt numTotXEdges = numXEdges*numYVertices; const PetscInt numTotYEdges = numYEdges*numXVertices; const PetscInt numVertices = numXVertices*numYVertices; const PetscInt numEdges = numTotXEdges + numTotYEdges; const PetscInt numFaces = numXEdges*numYEdges; const PetscInt firstVertex = numFaces; const PetscInt firstXEdge = numFaces + numVertices; const PetscInt firstYEdge = numFaces + numVertices + numTotXEdges; Vec coordinates; PetscSection coordSection; PetscScalar *coords; PetscInt coordSize; PetscInt v, vx, vy; PetscInt f, fx, fy, e, ex, ey; ierr = DMPlexSetChart(dm, 0, numFaces+numEdges+numVertices);CHKERRQ(ierr); for (f = 0; f < numFaces; ++f) { ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); } for (e = firstXEdge; e < firstXEdge+numEdges; ++e) { ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); } ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ /* Build faces */ for (fy = 0; fy < numYEdges; fy++) { for (fx = 0; fx < numXEdges; fx++) { const PetscInt face = fy*numXEdges + fx; const PetscInt edgeL = firstYEdge + fx*numYEdges + fy; const PetscInt edgeB = firstXEdge + fy*numXEdges + fx; const PetscInt ornt[4] = {0, 0, -2, -2}; PetscInt cone[4]; cone[0] = edgeB; cone[1] = edgeL+numYEdges; cone[2] = edgeB+numXEdges; cone[3] = edgeL; ierr = DMPlexSetCone(dm, face, cone);CHKERRQ(ierr); ierr = DMPlexSetConeOrientation(dm, face, ornt);CHKERRQ(ierr); } } /* Build Y edges*/ for (vx = 0; vx < numXVertices; vx++) { for (ey = 0; ey < numYEdges; ey++) { const PetscInt edge = firstYEdge + vx*numYEdges + ey; const PetscInt vertex = firstVertex + ey*numXVertices + vx; PetscInt cone[2]; cone[0] = vertex; cone[1] = vertex+numXVertices; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); if (vx == numXVertices-1) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerRight);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerRight);CHKERRQ(ierr); if (ey == numYEdges-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerRight);CHKERRQ(ierr); } } else if (vx == 0) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerLeft);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerLeft);CHKERRQ(ierr); if (ey == numYEdges-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerLeft);CHKERRQ(ierr); } } } } /* Build X edges*/ for (vy = 0; vy < numYVertices; vy++) { for (ex = 0; ex < numXEdges; ex++) { const PetscInt edge = firstXEdge + vy*numXEdges + ex; const PetscInt vertex = firstVertex + vy*numXVertices + ex; PetscInt cone[2]; cone[0] = vertex; cone[1] = vertex+1; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); if (vy == numYVertices-1) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerTop);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerTop);CHKERRQ(ierr); if (ex == numXEdges-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerTop);CHKERRQ(ierr); } } else if (vy == 0) { ierr = DMPlexSetLabelValue(dm, "marker", edge, markerBottom);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", cone[0], markerBottom);CHKERRQ(ierr); if (ex == numXEdges-1) { ierr = DMPlexSetLabelValue(dm, "marker", cone[1], markerBottom);CHKERRQ(ierr); } } } } ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); ierr = DMPlexStratify(dm);CHKERRQ(ierr); /* Build coordinates */ ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVertices);CHKERRQ(ierr); for (v = firstVertex; v < firstVertex+numVertices; ++v) { ierr = PetscSectionSetDof(coordSection, v, 2);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); for (vy = 0; vy < numYVertices; ++vy) { for (vx = 0; vx < numXVertices; ++vx) { coords[(vy*numXVertices+vx)*2+0] = lower[0] + ((upper[0] - lower[0])/numXEdges)*vx; coords[(vy*numXVertices+vx)*2+1] = lower[1] + ((upper[1] - lower[1])/numYEdges)*vy; } } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/* Simple cubic boundary: 2-------3 /| /| 6-------7 | | | | | | 0-----|-1 |/ |/ 4-------5 */ PetscErrorCode DMPlexCreateCubeBoundary(DM dm, const PetscReal lower[], const PetscReal upper[], const PetscInt faces[]) { PetscInt numVertices = (faces[0]+1)*(faces[1]+1)*(faces[2]+1); PetscInt numFaces = 6; Vec coordinates; PetscSection coordSection; PetscScalar *coords; PetscInt coordSize; PetscMPIInt rank; PetscInt v, vx, vy, vz; PetscErrorCode ierr; PetscFunctionBegin; if ((faces[0] < 1) || (faces[1] < 1) || (faces[2] < 1)) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Must have at least 1 face per side"); if ((faces[0] > 1) || (faces[1] > 1) || (faces[2] > 1)) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Currently can't handle more than 1 face per side"); ierr = PetscMalloc(numVertices*2 * sizeof(PetscReal), &coords);CHKERRQ(ierr); ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); if (!rank) { PetscInt f; ierr = DMPlexSetChart(dm, 0, numFaces+numVertices);CHKERRQ(ierr); for (f = 0; f < numFaces; ++f) { ierr = DMPlexSetConeSize(dm, f, 4);CHKERRQ(ierr); } ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ for (v = 0; v < numFaces+numVertices; ++v) { ierr = DMPlexSetLabelValue(dm, "marker", v, 1);CHKERRQ(ierr); } { /* Side 0 (Front) */ PetscInt cone[4]; cone[0] = numFaces+4; cone[1] = numFaces+5; cone[2] = numFaces+7; cone[3] = numFaces+6; ierr = DMPlexSetCone(dm, 0, cone);CHKERRQ(ierr); } { /* Side 1 (Back) */ PetscInt cone[4]; cone[0] = numFaces+1; cone[1] = numFaces+0; cone[2] = numFaces+2; cone[3] = numFaces+3; ierr = DMPlexSetCone(dm, 1, cone);CHKERRQ(ierr); } { /* Side 2 (Bottom) */ PetscInt cone[4]; cone[0] = numFaces+0; cone[1] = numFaces+1; cone[2] = numFaces+5; cone[3] = numFaces+4; ierr = DMPlexSetCone(dm, 2, cone);CHKERRQ(ierr); } { /* Side 3 (Top) */ PetscInt cone[4]; cone[0] = numFaces+6; cone[1] = numFaces+7; cone[2] = numFaces+3; cone[3] = numFaces+2; ierr = DMPlexSetCone(dm, 3, cone);CHKERRQ(ierr); } { /* Side 4 (Left) */ PetscInt cone[4]; cone[0] = numFaces+0; cone[1] = numFaces+4; cone[2] = numFaces+6; cone[3] = numFaces+2; ierr = DMPlexSetCone(dm, 4, cone);CHKERRQ(ierr); } { /* Side 5 (Right) */ PetscInt cone[4]; cone[0] = numFaces+5; cone[1] = numFaces+1; cone[2] = numFaces+3; cone[3] = numFaces+7; ierr = DMPlexSetCone(dm, 5, cone);CHKERRQ(ierr); } } ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); ierr = DMPlexStratify(dm);CHKERRQ(ierr); /* Build coordinates */ ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, numFaces, numFaces + numVertices);CHKERRQ(ierr); for (v = numFaces; v < numFaces+numVertices; ++v) { ierr = PetscSectionSetDof(coordSection, v, 3);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinates);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); for (vz = 0; vz <= faces[2]; ++vz) { for (vy = 0; vy <= faces[1]; ++vy) { for (vx = 0; vx <= faces[0]; ++vx) { coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+0] = lower[0] + ((upper[0] - lower[0])/faces[0])*vx; coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+1] = lower[1] + ((upper[1] - lower[1])/faces[1])*vy; coords[((vz*(faces[1]+1)+vy)*(faces[0]+1)+vx)*3+2] = lower[2] + ((upper[2] - lower[2])/faces[2])*vz; } } } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Two triangles separated by a zero-volume cell with 6 vertices 5--16--8 / | | \ 11 | | 12 / | | \ 3 0 10 2 14 1 6 \ | | / 9 | | 13 \ | | / 4--15--7 */ PetscErrorCode CreateSimplexHybrid_2D(MPI_Comm comm, DM dm) { Vec coordinates; PetscSection coordSection; PetscScalar *coords; PetscInt numVertices = 0, numEdges = 0, numCells = 0, cMax = PETSC_DETERMINE, fMax = PETSC_DETERMINE; PetscInt firstVertex, firstEdge, coordSize; PetscInt v, e; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); if (!rank) { numVertices = 3 + 3; numEdges = 6 + 2; numCells = 3; cMax = 2; fMax = 15; } firstVertex = numCells; firstEdge = numCells + numVertices; ierr = DMPlexSetChart(dm, 0, numCells+numEdges+numVertices);CHKERRQ(ierr); if (numCells) { ierr = DMPlexSetConeSize(dm, 0, 3);CHKERRQ(ierr); ierr = DMPlexSetConeSize(dm, 1, 3);CHKERRQ(ierr); ierr = DMPlexSetConeSize(dm, 2, 4);CHKERRQ(ierr); } for(e = firstEdge; e < firstEdge+numEdges; ++e) { ierr = DMPlexSetConeSize(dm, e, 2);CHKERRQ(ierr); } ierr = DMSetUp(dm);CHKERRQ(ierr); /* Allocate space for cones */ ierr = DMPlexSetHybridBounds(dm, cMax, PETSC_DETERMINE, fMax, PETSC_DETERMINE);CHKERRQ(ierr); /* Indicate a hybrid mesh */ /* Build cells */ if (numCells > 0) { const PetscInt cone[3] = {9, 10, 11}; const PetscInt ornt[3] = {0, 0, 0}; const PetscInt cell = 0; ierr = DMPlexSetCone(dm, cell, cone);CHKERRQ(ierr); ierr = DMPlexSetConeOrientation(dm, cell, ornt);CHKERRQ(ierr); } if (numCells > 1) { const PetscInt cone[3] = {12, 14, 13}; const PetscInt ornt[3] = { 0, -2, 0}; const PetscInt cell = 1; ierr = DMPlexSetCone(dm, cell, cone);CHKERRQ(ierr); ierr = DMPlexSetConeOrientation(dm, cell, ornt);CHKERRQ(ierr); } if (numCells > 2) { const PetscInt cone[4] = {10, 14, 15, 16}; const PetscInt ornt[4] = { 0, 0, 0, 0}; const PetscInt cell = 2; ierr = DMPlexSetCone(dm, cell, cone);CHKERRQ(ierr); ierr = DMPlexSetConeOrientation(dm, cell, ornt);CHKERRQ(ierr); } /* Build edges*/ if (numEdges > 0) { const PetscInt cone[2] = {3, 4}; const PetscInt edge = 9; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", edge, 1);CHKERRQ(ierr); } if (numEdges > 1) { const PetscInt cone[2] = {4, 5}; const PetscInt edge = 10; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); } if (numEdges > 2) { const PetscInt cone[2] = {5, 3}; const PetscInt edge = 11; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", edge, 1);CHKERRQ(ierr); } if (numEdges > 3) { const PetscInt cone[2] = {6, 8}; const PetscInt edge = 12; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", edge, 1);CHKERRQ(ierr); } if (numEdges > 4) { const PetscInt cone[2] = {7, 6}; const PetscInt edge = 13; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); ierr = DMPlexSetLabelValue(dm, "marker", edge, 1);CHKERRQ(ierr); } if (numEdges > 5) { const PetscInt cone[2] = {7, 8}; const PetscInt edge = 14; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); } if (numEdges > 6) { const PetscInt cone[2] = {4, 7}; const PetscInt edge = 15; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); } if (numEdges > 7) { const PetscInt cone[2] = {5, 8}; const PetscInt edge = 16; ierr = DMPlexSetCone(dm, edge, cone);CHKERRQ(ierr); } ierr = DMPlexSymmetrize(dm);CHKERRQ(ierr); ierr = DMPlexStratify(dm);CHKERRQ(ierr); /* Build coordinates */ ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionSetChart(coordSection, firstVertex, firstVertex+numVertices);CHKERRQ(ierr); for(v = firstVertex; v < firstVertex+numVertices; ++v) { ierr = PetscSectionSetDof(coordSection, v, 2);CHKERRQ(ierr); } ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); ierr = VecCreate(((PetscObject) dm)->comm, &coordinates);CHKERRQ(ierr); ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(coordinates);CHKERRQ(ierr); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); if (numVertices) { coords[0] = -0.5; coords[1] = 0.5; coords[2] = -0.2; coords[3] = 0.0; coords[4] = -0.2; coords[5] = 1.0; coords[6] = 0.5; coords[7] = 0.5; coords[8] = 0.2; coords[9] = 0.0; coords[10] = 0.2; coords[11] = 1.0; } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm, coordinates);CHKERRQ(ierr); ierr = VecDestroy(&coordinates);CHKERRQ(ierr); PetscFunctionReturn(0); }