Actual source code: plexgenerate.c
petsc-3.13.6 2020-09-29
1: #include <petsc/private/dmpleximpl.h>
3: /*@C
4: DMPlexInvertCell - Flips cell orientations since Plex 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: 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)
28: switch (cellType) {
29: case DM_POLYTOPE_POINT: break;
30: case DM_POLYTOPE_SEGMENT: break;
31: case DM_POLYTOPE_POINT_PRISM_TENSOR: break;
32: case DM_POLYTOPE_TRIANGLE: break;
33: case DM_POLYTOPE_QUADRILATERAL: break;
34: case DM_POLYTOPE_SEG_PRISM_TENSOR: SWAPCONE(cone,2,3); break;
35: case DM_POLYTOPE_TETRAHEDRON: SWAPCONE(cone,0,1); break;
36: case DM_POLYTOPE_HEXAHEDRON: SWAPCONE(cone,1,3); break;
37: case DM_POLYTOPE_TRI_PRISM: SWAPCONE(cone,1,2); break;
38: case DM_POLYTOPE_TRI_PRISM_TENSOR: break;
39: case DM_POLYTOPE_QUAD_PRISM_TENSOR: break;
40: default: break;
41: }
42: return(0);
43: #undef SWAPCONE
44: }
46: /*@C
47: DMPlexReorderCell - Flips cell orientations since Plex stores some of them internally with outward normals.
49: Input Parameters:
50: + dm - The DMPlex object
51: . cell - The cell
52: - cone - The incoming cone
54: Output Parameter:
55: . cone - The reordered cone (in-place)
57: Level: developer
59: .seealso: DMPlexGenerate()
60: @*/
61: PetscErrorCode DMPlexReorderCell(DM dm, PetscInt cell, PetscInt cone[])
62: {
63: DMPolytopeType cellType;
67: DMPlexGetCellType(dm, cell, &cellType);
68: DMPlexInvertCell(cellType, cone);
69: return(0);
70: }
73: /*@C
74: DMPlexTriangleSetOptions - Set the options used for the Triangle mesh generator
76: Not Collective
78: Inputs Parameters:
79: + dm - The DMPlex object
80: - opts - The command line options
82: Level: developer
84: .seealso: DMPlexTetgenSetOptions(), DMPlexGenerate()
85: @*/
86: PetscErrorCode DMPlexTriangleSetOptions(DM dm, const char *opts)
87: {
88: DM_Plex *mesh = (DM_Plex*) dm->data;
94: PetscFree(mesh->triangleOpts);
95: PetscStrallocpy(opts, &mesh->triangleOpts);
96: return(0);
97: }
99: /*@C
100: DMPlexTetgenSetOptions - Set the options used for the Tetgen mesh generator
102: Not Collective
104: Inputs Parameters:
105: + dm - The DMPlex object
106: - opts - The command line options
108: Level: developer
110: .seealso: DMPlexTriangleSetOptions(), DMPlexGenerate()
111: @*/
112: PetscErrorCode DMPlexTetgenSetOptions(DM dm, const char *opts)
113: {
114: DM_Plex *mesh = (DM_Plex*) dm->data;
120: PetscFree(mesh->tetgenOpts);
121: PetscStrallocpy(opts, &mesh->tetgenOpts);
122: return(0);
123: }
125: /*
126: Contains the list of registered DMPlexGenerators routines
127: */
128: PetscFunctionList DMPlexGenerateList = NULL;
130: struct _n_PetscFunctionList {
131: PetscErrorCode (*generate)(DM, PetscBool, DM*);
132: PetscErrorCode (*refine)(DM,double*, DM*);
133: char *name; /* string to identify routine */
134: PetscInt dim;
135: PetscFunctionList next; /* next pointer */
136: };
138: /*@C
139: DMPlexGenerate - Generates a mesh.
141: Not Collective
143: Input Parameters:
144: + boundary - The DMPlex boundary object
145: . name - The mesh generation package name
146: - interpolate - Flag to create intermediate mesh elements
148: Output Parameter:
149: . mesh - The DMPlex object
151: Options Database:
152: + -dm_plex_generate <name> - package to generate mesh, for example, triangle, ctetgen or tetgen
153: - -dm_plex_generator <name> - package to generate mesh, for example, triangle, ctetgen or tetgen (deprecated)
155: Level: intermediate
157: .seealso: DMPlexCreate(), DMRefine()
158: @*/
159: PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh)
160: {
161: PetscInt dim;
162: char genname[1024];
163: PetscBool flg;
164: PetscErrorCode ierr;
165: PetscFunctionList fl;
166: const char* suggestions;
171: DMGetDimension(boundary, &dim);
172: PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generator", genname, 1024, &flg);
173: if (flg) name = genname;
174: else {
175: PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generate", genname, 1024, &flg);
176: if (flg) name = genname;
177: }
179: fl = DMPlexGenerateList;
180: if (name) {
181: while (fl) {
182: PetscStrcmp(fl->name,name,&flg);
183: if (flg) {
184: (*fl->generate)(boundary,interpolate,mesh);
185: return(0);
186: }
187: fl = fl->next;
188: }
189: SETERRQ2(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);
190: } else {
191: while (fl) {
192: if (boundary->dim == fl->dim) {
193: (*fl->generate)(boundary,interpolate,mesh);
194: return(0);
195: }
196: fl = fl->next;
197: }
198: suggestions = "";
199: if (boundary->dim+1 == 2) suggestions = " You may need to add --download-triangle to your ./configure options";
200: else if (boundary->dim+1 == 3) suggestions = " You may need to add --download-ctetgen or --download-tetgen in your ./configure options";
201: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"No grid generator of dimension %D registered%s",boundary->dim+1,suggestions);
202: }
203: return(0);
204: }
206: /*@C
207: DMPlexGenerateRegister - Adds a grid generator to DMPlex
209: Not Collective
211: Input Parameters:
212: + name_solver - name of a new user-defined grid generator
213: . fnc - generator function
214: . rfnc - refinement function
215: - dim - dimension of boundary of domain
217: Notes:
218: DMPlexGenerateRegister() may be called multiple times to add several user-defined solvers.
220: Sample usage:
221: .vb
222: DMPlexGenerateRegister("my_generator",MyGeneratorCreate,MyGeneratorRefiner,dim);
223: .ve
225: Then, your generator can be chosen with the procedural interface via
226: $ DMPlexGenerate(dm,"my_generator",...)
227: or at runtime via the option
228: $ -dm_plex_generator my_generator
230: Level: advanced
232: .seealso: DMPlexGenerateRegisterAll(), DMPlexGenerate(), DMPlexGenerateRegisterDestroy()
234: @*/
235: PetscErrorCode DMPlexGenerateRegister(const char sname[],PetscErrorCode (*fnc)(DM, PetscBool,DM*), PetscErrorCode (*rfnc)(DM, double*,DM*),PetscInt dim)
236: {
237: PetscErrorCode ierr;
238: PetscFunctionList entry;
241: PetscNew(&entry);
242: PetscStrallocpy(sname,&entry->name);
243: entry->generate = fnc;
244: entry->refine = rfnc;
245: entry->dim = dim;
246: entry->next = NULL;
247: if (!DMPlexGenerateList) DMPlexGenerateList = entry;
248: else {
249: PetscFunctionList fl = DMPlexGenerateList;
250: while (fl->next) fl = fl->next;
251: fl->next = entry;
252: }
253: return(0);
254: }
256: extern PetscBool DMPlexGenerateRegisterAllCalled;
258: PetscErrorCode DMPlexGenerateRegisterDestroy(void)
259: {
260: PetscFunctionList next,fl;
261: PetscErrorCode ierr;
264: next = fl = DMPlexGenerateList;
265: while (next) {
266: next = fl ? fl->next : NULL;
267: if (fl) {PetscFree(fl->name);}
268: PetscFree(fl);
269: fl = next;
270: }
271: DMPlexGenerateList = NULL;
272: DMPlexGenerateRegisterAllCalled = PETSC_FALSE;
273: return(0);
274: }