Actual source code: plexextrude.c
1: #include <petsc/private/dmpleximpl.h>
2: #include <petscdmplextransform.h>
4: /*@C
5: DMPlexExtrude - Extrude a volumetric mesh from the input surface mesh
7: Input Parameters:
8: + dm - The surface mesh
9: . layers - The number of extruded layers
10: . thickness - The total thickness of the extruded layers, or PETSC_DETERMINE
11: . tensor - Flag to create tensor produt cells
12: . symmetric - Flag to extrude symmetrically about the surface
13: . normal - Surface normal vector, or NULL
14: - thicknesses - Thickness of each layer, or NULL
16: Output Parameter:
17: . edm - The volumetric mesh
19: Notes:
20: Extrusion is implemented as a DMPlexTransform, so that new mesh points are produced from old mesh points. In the exmaple below,
21: 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,
22: 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
23: 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
24: would v1, v2, e1 and e2.
26: $ v2----- e6 -----v5
27: $ | |
28: $ e2 face2 e4
29: $ | |
30: $ v1----- e5 -----v4
31: $ | |
32: $ e1 face1 e3
33: $ | |
34: $ v0--- original ----v3
36: Options Database:
37: + -dm_plex_transform_extrude_thickness <t> - The total thickness of extruded layers
38: . -dm_plex_transform_extrude_use_tensor <bool> - Use tensor cells when extruding
39: . -dm_plex_transform_extrude_symmetric <bool> - Extrude layers symmetrically about the surface
40: . -dm_plex_transform_extrude_normal <n0,...,nd> - Specify the extrusion direction
41: - -dm_plex_transform_extrude_thicknesses <t0,...,tl> - Specify thickness of each layer
43: Level: intermediate
45: .seealso: `DMExtrude()`, `DMPlexTransform`, `DMPlexTransformExtrudeSetThickness()`, `DMPlexTransformExtrudeSetTensor()`
46: @*/
47: PetscErrorCode DMPlexExtrude(DM dm, PetscInt layers, PetscReal thickness, PetscBool tensor, PetscBool symmetric, const PetscReal normal[], const PetscReal thicknesses[], DM *edm)
48: {
49: DMPlexTransform tr;
50: DM cdm, ecdm;
51: const char *prefix;
52: PetscOptions options;
54: DMPlexTransformCreate(PetscObjectComm((PetscObject)dm), &tr);
55: DMPlexTransformSetDM(tr, dm);
56: DMPlexTransformSetType(tr, DMPLEXEXTRUDE);
57: PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix);
58: PetscObjectSetOptionsPrefix((PetscObject)tr, prefix);
59: PetscObjectGetOptions((PetscObject)dm, &options);
60: PetscObjectSetOptions((PetscObject)tr, options);
61: DMPlexTransformExtrudeSetLayers(tr, layers);
62: if (thickness > 0.) DMPlexTransformExtrudeSetThickness(tr, thickness);
63: DMPlexTransformExtrudeSetTensor(tr, tensor);
64: DMPlexTransformExtrudeSetSymmetric(tr, symmetric);
65: if (normal) DMPlexTransformExtrudeSetNormal(tr, normal);
66: if (thicknesses) DMPlexTransformExtrudeSetThicknesses(tr, layers, thicknesses);
67: DMPlexTransformSetFromOptions(tr);
68: PetscObjectSetOptions((PetscObject)tr, NULL);
69: DMPlexTransformSetUp(tr);
70: PetscObjectViewFromOptions((PetscObject)tr, NULL, "-dm_plex_transform_view");
71: DMPlexTransformApply(tr, dm, edm);
72: DMCopyDisc(dm, *edm);
73: DMGetCoordinateDM(dm, &cdm);
74: DMGetCoordinateDM(*edm, &ecdm);
75: DMCopyDisc(cdm, ecdm);
76: DMPlexTransformCreateDiscLabels(tr, *edm);
77: DMPlexTransformDestroy(&tr);
78: if (*edm) {
79: ((DM_Plex *)(*edm)->data)->printFEM = ((DM_Plex *)dm->data)->printFEM;
80: ((DM_Plex *)(*edm)->data)->printL2 = ((DM_Plex *)dm->data)->printL2;
81: }
82: return 0;
83: }
85: PetscErrorCode DMExtrude_Plex(DM dm, PetscInt layers, DM *edm)
86: {
87: DMPlexExtrude(dm, layers, PETSC_DETERMINE, PETSC_TRUE, PETSC_FALSE, NULL, NULL, edm);
88: DMViewFromOptions(*edm, NULL, "-check_extrude");
89: return 0;
90: }