1d410b0cfSMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/
2d410b0cfSMatthew G. Knepley #include <petscdmplextransform.h>
3d410b0cfSMatthew G. Knepley
4cc4c1da9SBarry Smith /*@
59695643eSMatthew G. Knepley DMPlexExtrude - Extrude a volumetric mesh from the input surface mesh
69695643eSMatthew G. Knepley
79695643eSMatthew G. Knepley Input Parameters:
89695643eSMatthew G. Knepley + dm - The surface mesh
99695643eSMatthew G. Knepley . layers - The number of extruded layers
10a1cb98faSBarry Smith . thickness - The total thickness of the extruded layers, or `PETSC_DETERMINE`
11*29e6a8b2SPierre Jolivet . tensor - Flag to create tensor product cells
129695643eSMatthew G. Knepley . symmetric - Flag to extrude symmetrically about the surface
131fcf445aSMatthew G. Knepley . periodic - Flag to extrude periodically
14a3b724e8SBarry Smith . normal - Surface normal vector, or `NULL`
15658b9581SMatthew G. Knepley . thicknesses - Thickness of each layer, or `NULL`
16658b9581SMatthew G. Knepley - activeLabel - `DMLabel` to extrude from, or `NULL` to extrude entire mesh
179695643eSMatthew G. Knepley
189695643eSMatthew G. Knepley Output Parameter:
199695643eSMatthew G. Knepley . edm - The volumetric mesh
209695643eSMatthew G. Knepley
21a1cb98faSBarry Smith Options Database Keys:
229695643eSMatthew G. Knepley + -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers
239695643eSMatthew G. Knepley . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding
249695643eSMatthew G. Knepley . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface
251fcf445aSMatthew G. Knepley . -dm_plex_transform_extrude_periodic <bool> - Extrude layers periodically
269695643eSMatthew G. Knepley . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction
279695643eSMatthew G. Knepley - -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer
289695643eSMatthew G. Knepley
299695643eSMatthew G. Knepley Level: intermediate
309695643eSMatthew G. Knepley
31a1cb98faSBarry Smith Notes:
32da81f932SPierre Jolivet Extrusion is implemented as a `DMPlexTransform`, so that new mesh points are produced from old mesh points. In the example below,
33a1cb98faSBarry Smith we begin with an edge (v0, v3). It is extruded for two layers. The original vertex v0 produces two edges, e1 and e2, and three vertices,
34a1cb98faSBarry Smith v0, v2, and v2. Similarly, vertex v3 produces e3, e4, v3, v4, and v5. The original edge produces itself, e5 and e6, as well as face1 and
35a1cb98faSBarry Smith face2. The new mesh points are given the same labels as the original points which produced them. Thus, if v0 had a label value 1, then so
36a1cb98faSBarry Smith would v1, v2, e1 and e2.
37a1cb98faSBarry Smith
38a1cb98faSBarry Smith .vb
39a1cb98faSBarry Smith v2----- e6 -----v5
40a1cb98faSBarry Smith | |
41a1cb98faSBarry Smith e2 face2 e4
42a1cb98faSBarry Smith | |
43a1cb98faSBarry Smith v1----- e5 -----v4
44a1cb98faSBarry Smith | |
45a1cb98faSBarry Smith e1 face1 e3
46a1cb98faSBarry Smith | |
47a1cb98faSBarry Smith v0--- original ----v3
48a1cb98faSBarry Smith .ve
49a1cb98faSBarry Smith
501cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMExtrude()`, `DMPlexTransform`, `DMPlexTransformExtrudeSetThickness()`, `DMPlexTransformExtrudeSetTensor()`
519695643eSMatthew G. Knepley @*/
DMPlexExtrude(DM dm,PetscInt layers,PetscReal thickness,PetscBool tensor,PetscBool symmetric,PetscBool periodic,const PetscReal normal[],const PetscReal thicknesses[],DMLabel activeLabel,DM * edm)52658b9581SMatthew G. Knepley PetscErrorCode DMPlexExtrude(DM dm, PetscInt layers, PetscReal thickness, PetscBool tensor, PetscBool symmetric, PetscBool periodic, const PetscReal normal[], const PetscReal thicknesses[], DMLabel activeLabel, DM *edm)
53d71ae5a4SJacob Faibussowitsch {
54d410b0cfSMatthew G. Knepley DMPlexTransform tr;
551a55e319SMatthew G. Knepley DM cdm;
561a55e319SMatthew G. Knepley PetscObject disc;
571a55e319SMatthew G. Knepley PetscClassId id;
58d410b0cfSMatthew G. Knepley const char *prefix;
59d410b0cfSMatthew G. Knepley PetscOptions options;
60afdb71dcSMatthew G. Knepley PetscBool cutMarker = PETSC_FALSE;
61d410b0cfSMatthew G. Knepley
62d410b0cfSMatthew G. Knepley PetscFunctionBegin;
639566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject)dm), &tr));
64fd3f191cSMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)tr, "Extrusion Transform"));
659566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetDM(tr, dm));
66ce78bad3SBarry Smith PetscCall(DMPlexTransformSetType(tr, DMPLEXEXTRUDETYPE));
679566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
689566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)tr, prefix));
699566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptions((PetscObject)dm, &options));
709566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)tr, options));
71658b9581SMatthew G. Knepley if (activeLabel) PetscCall(DMPlexTransformSetActive(tr, activeLabel));
729566063dSJacob Faibussowitsch PetscCall(DMPlexTransformExtrudeSetLayers(tr, layers));
739566063dSJacob Faibussowitsch if (thickness > 0.) PetscCall(DMPlexTransformExtrudeSetThickness(tr, thickness));
749566063dSJacob Faibussowitsch PetscCall(DMPlexTransformExtrudeSetTensor(tr, tensor));
759566063dSJacob Faibussowitsch PetscCall(DMPlexTransformExtrudeSetSymmetric(tr, symmetric));
7680cd373eSmarkadams4 PetscCall(DMPlexTransformExtrudeSetPeriodic(tr, periodic));
779566063dSJacob Faibussowitsch if (normal) PetscCall(DMPlexTransformExtrudeSetNormal(tr, normal));
789566063dSJacob Faibussowitsch if (thicknesses) PetscCall(DMPlexTransformExtrudeSetThicknesses(tr, layers, thicknesses));
799566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetFromOptions(tr));
809566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)tr, NULL));
819566063dSJacob Faibussowitsch PetscCall(DMPlexTransformSetUp(tr));
829566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)tr, NULL, "-dm_plex_transform_view"));
839566063dSJacob Faibussowitsch PetscCall(DMPlexTransformApply(tr, dm, edm));
849566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, *edm));
85afdb71dcSMatthew G. Knepley // Handle periodic viewing
86afdb71dcSMatthew G. Knepley PetscCall(PetscOptionsGetBool(options, ((PetscObject)dm)->prefix, "-dm_plex_periodic_cut", &cutMarker, NULL));
87afdb71dcSMatthew G. Knepley PetscCall(DMPlexTransformExtrudeGetPeriodic(tr, &periodic));
88afdb71dcSMatthew G. Knepley if (periodic && cutMarker) {
89afdb71dcSMatthew G. Knepley DMLabel cutLabel;
90afdb71dcSMatthew G. Knepley PetscInt dim, pStart, pEnd;
91afdb71dcSMatthew G. Knepley
92afdb71dcSMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim));
93afdb71dcSMatthew G. Knepley PetscCall(DMCreateLabel(*edm, "periodic_cut"));
94afdb71dcSMatthew G. Knepley PetscCall(DMGetLabel(*edm, "periodic_cut", &cutLabel));
95afdb71dcSMatthew G. Knepley PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
96afdb71dcSMatthew G. Knepley for (PetscInt p = pStart; p < pEnd; ++p) {
97afdb71dcSMatthew G. Knepley DMPolytopeType ct;
98afdb71dcSMatthew G. Knepley DMPolytopeType *rct;
99afdb71dcSMatthew G. Knepley PetscInt *rsize, *rcone, *rornt;
100afdb71dcSMatthew G. Knepley PetscInt Nct;
101afdb71dcSMatthew G. Knepley
102afdb71dcSMatthew G. Knepley PetscCall(DMPlexGetCellType(dm, p, &ct));
103afdb71dcSMatthew G. Knepley PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
104afdb71dcSMatthew G. Knepley for (PetscInt n = 0; n < Nct; ++n) {
105afdb71dcSMatthew G. Knepley PetscInt pNew, pdim = DMPolytopeTypeGetDim(rct[n]);
106afdb71dcSMatthew G. Knepley
107afdb71dcSMatthew G. Knepley if (ct == rct[n] || pdim > dim) {
108afdb71dcSMatthew G. Knepley PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], p, 0, &pNew));
109afdb71dcSMatthew G. Knepley PetscCall(DMLabelSetValue(cutLabel, pNew, !pdim ? 1 : 2));
110afdb71dcSMatthew G. Knepley }
111afdb71dcSMatthew G. Knepley }
112afdb71dcSMatthew G. Knepley }
113afdb71dcSMatthew G. Knepley }
1141a55e319SMatthew G. Knepley // It is too hard to raise the dimension of a discretization, so just remake it
1159566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dm, &cdm));
1161a55e319SMatthew G. Knepley PetscCall(DMGetField(cdm, 0, NULL, &disc));
1171a55e319SMatthew G. Knepley PetscCall(PetscObjectGetClassId(disc, &id));
1181a55e319SMatthew G. Knepley if (id == PETSCFE_CLASSID) {
1191a55e319SMatthew G. Knepley PetscSpace sp;
1201a55e319SMatthew G. Knepley PetscInt deg;
1211a55e319SMatthew G. Knepley
1221a55e319SMatthew G. Knepley PetscCall(PetscFEGetBasisSpace((PetscFE)disc, &sp));
1231a55e319SMatthew G. Knepley PetscCall(PetscSpaceGetDegree(sp, °, NULL));
124e65c294aSksagiyam PetscCall(DMPlexCreateCoordinateSpace(*edm, deg, PETSC_FALSE, PETSC_TRUE));
1251a55e319SMatthew G. Knepley }
1269566063dSJacob Faibussowitsch PetscCall(DMPlexTransformCreateDiscLabels(tr, *edm));
1279566063dSJacob Faibussowitsch PetscCall(DMPlexTransformDestroy(&tr));
128a77a5016SMatthew G. Knepley PetscCall(DMPlexCopy_Internal(dm, PETSC_FALSE, PETSC_FALSE, *edm));
1293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
130d410b0cfSMatthew G. Knepley }
131d410b0cfSMatthew G. Knepley
DMExtrude_Plex(DM dm,PetscInt layers,DM * edm)132d71ae5a4SJacob Faibussowitsch PetscErrorCode DMExtrude_Plex(DM dm, PetscInt layers, DM *edm)
133d71ae5a4SJacob Faibussowitsch {
134d410b0cfSMatthew G. Knepley PetscFunctionBegin;
135658b9581SMatthew G. Knepley PetscCall(DMPlexExtrude(dm, layers, PETSC_DETERMINE, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, NULL, NULL, NULL, edm));
136f4f49eeaSPierre Jolivet PetscCall(DMSetMatType(*edm, dm->mattype));
1379566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*edm, NULL, "-check_extrude"));
1383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
139d410b0cfSMatthew G. Knepley }
140