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: }