Actual source code: plexgenerate.c

  1: #include <petsc/private/dmpleximpl.h>

  3: /*@
  4:   DMPlexInvertCell - Flips cell orientations since `DMPLEX` stores some of them internally with outward normals.

  6:   Input Parameters:
  7: + cellType - The cell type
  8: - cone     - The incoming cone

 10:   Output Parameter:
 11: . cone - The inverted cone (in-place)

 13:   Level: developer

 15: .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPolytopeType`, `DMPlexGenerate()`
 16: @*/
 17: PetscErrorCode DMPlexInvertCell(DMPolytopeType cellType, PetscInt cone[])
 18: {
 19: #define SWAPCONE(cone, i, j) \
 20:   do { \
 21:     PetscInt _cone_tmp; \
 22:     _cone_tmp = (cone)[i]; \
 23:     (cone)[i] = (cone)[j]; \
 24:     (cone)[j] = _cone_tmp; \
 25:   } while (0)

 27:   PetscFunctionBegin;
 28:   switch (cellType) {
 29:   case DM_POLYTOPE_POINT:
 30:     break;
 31:   case DM_POLYTOPE_SEGMENT:
 32:     break;
 33:   case DM_POLYTOPE_POINT_PRISM_TENSOR:
 34:     break;
 35:   case DM_POLYTOPE_TRIANGLE:
 36:     break;
 37:   case DM_POLYTOPE_QUADRILATERAL:
 38:     break;
 39:   case DM_POLYTOPE_SEG_PRISM_TENSOR:
 40:     SWAPCONE(cone, 2, 3);
 41:     break;
 42:   case DM_POLYTOPE_TETRAHEDRON:
 43:     SWAPCONE(cone, 0, 1);
 44:     break;
 45:   case DM_POLYTOPE_HEXAHEDRON:
 46:     SWAPCONE(cone, 1, 3);
 47:     break;
 48:   case DM_POLYTOPE_TRI_PRISM:
 49:     SWAPCONE(cone, 1, 2);
 50:     break;
 51:   case DM_POLYTOPE_TRI_PRISM_TENSOR:
 52:     break;
 53:   case DM_POLYTOPE_QUAD_PRISM_TENSOR:
 54:     break;
 55:   case DM_POLYTOPE_PYRAMID:
 56:     SWAPCONE(cone, 1, 3);
 57:     break;
 58:   default:
 59:     break;
 60:   }
 61:   PetscFunctionReturn(PETSC_SUCCESS);
 62: #undef SWAPCONE
 63: }

 65: /*@
 66:   DMPlexReorderCell - Flips cell orientations since `DMPLEX` stores some of them internally with outward normals.

 68:   Input Parameters:
 69: + dm   - The `DMPLEX` object
 70: . cell - The cell
 71: - cone - The incoming cone

 73:   Output Parameter:
 74: . cone - The reordered cone (in-place)

 76:   Level: developer

 78: .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPolytopeType`, `DMPlexGenerate()`
 79: @*/
 80: PetscErrorCode DMPlexReorderCell(DM dm, PetscInt cell, PetscInt cone[])
 81: {
 82:   DMPolytopeType cellType;

 84:   PetscFunctionBegin;
 85:   PetscCall(DMPlexGetCellType(dm, cell, &cellType));
 86:   PetscCall(DMPlexInvertCell(cellType, cone));
 87:   PetscFunctionReturn(PETSC_SUCCESS);
 88: }

 90: /*@C
 91:   DMPlexTriangleSetOptions - Set the options used for the Triangle mesh generator

 93:   Not Collective

 95:   Input Parameters:
 96: + dm   - The `DMPLEX` object
 97: - opts - The command line options

 99:   Level: developer

101: .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTetgenSetOptions()`, `DMPlexGenerate()`
102: @*/
103: PetscErrorCode DMPlexTriangleSetOptions(DM dm, const char *opts)
104: {
105:   DM_Plex *mesh = (DM_Plex *)dm->data;

107:   PetscFunctionBegin;
109:   PetscAssertPointer(opts, 2);
110:   PetscCall(PetscFree(mesh->triangleOpts));
111:   PetscCall(PetscStrallocpy(opts, &mesh->triangleOpts));
112:   PetscFunctionReturn(PETSC_SUCCESS);
113: }

115: /*@C
116:   DMPlexTetgenSetOptions - Set the options used for the Tetgen mesh generator

118:   Not Collective

120:   Input Parameters:
121: + dm   - The `DMPLEX` object
122: - opts - The command line options

124:   Level: developer

126: .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTriangleSetOptions()`, `DMPlexGenerate()`
127: @*/
128: PetscErrorCode DMPlexTetgenSetOptions(DM dm, const char *opts)
129: {
130:   DM_Plex *mesh = (DM_Plex *)dm->data;

132:   PetscFunctionBegin;
134:   PetscAssertPointer(opts, 2);
135:   PetscCall(PetscFree(mesh->tetgenOpts));
136:   PetscCall(PetscStrallocpy(opts, &mesh->tetgenOpts));
137:   PetscFunctionReturn(PETSC_SUCCESS);
138: }

140: /*@
141:   DMPlexGenerate - Generates a mesh.

143:   Not Collective

145:   Input Parameters:
146: + boundary    - The `DMPLEX` boundary object
147: . name        - The mesh generation package name
148: - interpolate - Flag to create intermediate mesh elements

150:   Output Parameter:
151: . mesh - The `DMPLEX` object

153:   Options Database Keys:
154: + -dm_plex_generate <name> - package to generate mesh, for example, triangle, ctetgen or tetgen
155: - -dm_generator <name>     - package to generate mesh, for example, triangle, ctetgen or tetgen

157:   Level: intermediate

159: .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexCreate()`, `DMRefine()`
160: @*/
161: PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh)
162: {
163:   DMGeneratorFunctionList fl;
164:   char                    genname[PETSC_MAX_PATH_LEN];
165:   const char             *suggestions;
166:   PetscInt                dim;
167:   PetscBool               flg;

169:   PetscFunctionBegin;
172:   PetscCall(DMGetDimension(boundary, &dim));
173:   PetscCall(PetscOptionsGetString(((PetscObject)boundary)->options, ((PetscObject)boundary)->prefix, "-dm_generator", genname, sizeof(genname), &flg));
174:   if (flg) name = genname;
175:   else {
176:     PetscCall(PetscOptionsGetString(((PetscObject)boundary)->options, ((PetscObject)boundary)->prefix, "-dm_plex_generate", genname, sizeof(genname), &flg));
177:     if (flg) name = genname;
178:   }

180:   fl = DMGenerateList;
181:   if (name) {
182:     while (fl) {
183:       PetscCall(PetscStrcmp(fl->name, name, &flg));
184:       if (flg) {
185:         PetscCall((*fl->generate)(boundary, interpolate, mesh));
186:         PetscFunctionReturn(PETSC_SUCCESS);
187:       }
188:       fl = fl->next;
189:     }
190:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Grid generator %s not registered; you may need to add --download-%s to your ./configure options", name, name);
191:   } else {
192:     while (fl) {
193:       if (boundary->dim == fl->dim) {
194:         PetscCall((*fl->generate)(boundary, interpolate, mesh));
195:         PetscFunctionReturn(PETSC_SUCCESS);
196:       }
197:       fl = fl->next;
198:     }
199:     suggestions = "";
200:     if (boundary->dim + 1 == 2) suggestions = " You may need to add --download-triangle to your ./configure options";
201:     else if (boundary->dim + 1 == 3) suggestions = " You may need to add --download-ctetgen or --download-tetgen in your ./configure options";
202:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No grid generator of dimension %" PetscInt_FMT " registered%s", boundary->dim + 1, suggestions);
203:   }
204: }