Actual source code: plexgenerate.c
petsc-3.11.4 2019-09-28
1: #include <petsc/private/dmpleximpl.h>
3: PetscErrorCode DMPlexInvertCell_Internal(PetscInt dim, PetscInt numCorners, PetscInt cone[])
4: {
5: int tmpc;
8: if (dim != 3) return(0);
9: switch (numCorners) {
10: case 4:
11: tmpc = cone[0];
12: cone[0] = cone[1];
13: cone[1] = tmpc;
14: break;
15: case 8:
16: tmpc = cone[1];
17: cone[1] = cone[3];
18: cone[3] = tmpc;
19: break;
20: default: break;
21: }
22: return(0);
23: }
25: /*@C
26: DMPlexInvertCell - This flips tetrahedron and hexahedron orientation since Plex stores them internally with outward normals. Other cells are left untouched.
28: Input Parameters:
29: + numCorners - The number of vertices in a cell
30: - cone - The incoming cone
32: Output Parameter:
33: . cone - The inverted cone (in-place)
35: Level: developer
37: .seealso: DMPlexGenerate()
38: @*/
39: PetscErrorCode DMPlexInvertCell(PetscInt dim, PetscInt numCorners, int cone[])
40: {
41: int tmpc;
44: if (dim != 3) return(0);
45: switch (numCorners) {
46: case 4:
47: tmpc = cone[0];
48: cone[0] = cone[1];
49: cone[1] = tmpc;
50: break;
51: case 8:
52: tmpc = cone[1];
53: cone[1] = cone[3];
54: cone[3] = tmpc;
55: break;
56: default: break;
57: }
58: return(0);
59: }
62: /*@C
63: DMPlexTriangleSetOptions - Set the options used for the Triangle mesh generator
65: Not Collective
67: Inputs Parameters:
68: + dm - The DMPlex object
69: - opts - The command line options
71: Level: developer
73: .keywords: mesh, points
74: .seealso: DMPlexTetgenSetOptions(), DMPlexGenerate()
75: @*/
76: PetscErrorCode DMPlexTriangleSetOptions(DM dm, const char *opts)
77: {
78: DM_Plex *mesh = (DM_Plex*) dm->data;
84: PetscFree(mesh->triangleOpts);
85: PetscStrallocpy(opts, &mesh->triangleOpts);
86: return(0);
87: }
89: /*@C
90: DMPlexTetgenSetOptions - Set the options used for the Tetgen mesh generator
92: Not Collective
94: Inputs Parameters:
95: + dm - The DMPlex object
96: - opts - The command line options
98: Level: developer
100: .keywords: mesh, points
101: .seealso: DMPlexTriangleSetOptions(), DMPlexGenerate()
102: @*/
103: PetscErrorCode DMPlexTetgenSetOptions(DM dm, const char *opts)
104: {
105: DM_Plex *mesh = (DM_Plex*) dm->data;
111: PetscFree(mesh->tetgenOpts);
112: PetscStrallocpy(opts, &mesh->tetgenOpts);
113: return(0);
114: }
116: /*
117: Contains the list of registered DMPlexGenerators routines
118: */
119: PetscFunctionList DMPlexGenerateList = NULL;
121: struct _n_PetscFunctionList {
122: PetscErrorCode (*generate)(DM, PetscBool, DM*);
123: PetscErrorCode (*refine)(DM,double*, DM*);
124: char *name; /* string to identify routine */
125: PetscInt dim;
126: PetscFunctionList next; /* next pointer */
127: };
129: /*@C
130: DMPlexGenerate - Generates a mesh.
132: Not Collective
134: Input Parameters:
135: + boundary - The DMPlex boundary object
136: . name - The mesh generation package name
137: - interpolate - Flag to create intermediate mesh elements
139: Output Parameter:
140: . mesh - The DMPlex object
142: Level: intermediate
144: .keywords: mesh, elements
145: .seealso: DMPlexCreate(), DMRefine()
146: @*/
147: PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh)
148: {
149: PetscInt dim;
150: char genname[1024];
151: PetscBool flg;
152: PetscErrorCode ierr;
153: PetscFunctionList fl;
158: DMGetDimension(boundary, &dim);
159: PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generator", genname, 1024, &flg);
160: if (flg) name = genname;
162: fl = DMPlexGenerateList;
163: if (name) {
164: while (fl) {
165: PetscStrcmp(fl->name,name,&flg);
166: if (flg) {
167: (*fl->generate)(boundary,interpolate,mesh);
168: return(0);
169: }
170: fl = fl->next;
171: }
172: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Grid generator %g not registered",name);
173: } else {
174: while (fl) {
175: if (boundary->dim == fl->dim) {
176: (*fl->generate)(boundary,interpolate,mesh);
177: return(0);
178: }
179: fl = fl->next;
180: }
181: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"No grid generator of dimension %D registered",boundary->dim);
182: }
183: return(0);
184: }
186: /*@C
187: DMPlexGenerateRegister - Adds a grid generator to DMPlex
189: Not Collective
191: Input Parameters:
192: + name_solver - name of a new user-defined grid generator
193: . fnc - generator function
194: . rfnc - refinement function
195: - dim - dimension of boundary of domain
197: Notes:
198: DMPlexGenerateRegister() may be called multiple times to add several user-defined solvers.
200: Sample usage:
201: .vb
202: DMPlexGenerateRegister("my_generator",MyGeneratorCreate,MyGeneratorRefiner,dim);
203: .ve
205: Then, your generator can be chosen with the procedural interface via
206: $ DMPlexGenerate(dm,"my_generator",...)
207: or at runtime via the option
208: $ -dm_plex_generator my_generator
210: Level: advanced
212: .keywords: DMPlexGenerate, register
214: .seealso: DMPlexGenerateRegisterAll(), DMPlexGenerate(), DMPlexGenerateRegisterDestroy()
216: @*/
217: PetscErrorCode DMPlexGenerateRegister(const char sname[],PetscErrorCode (*fnc)(DM, PetscBool,DM*), PetscErrorCode (*rfnc)(DM, double*,DM*),PetscInt dim)
218: {
219: PetscErrorCode ierr;
220: PetscFunctionList entry;
223: PetscNew(&entry);
224: PetscStrallocpy(sname,&entry->name);
225: entry->generate = fnc;
226: entry->refine = rfnc;
227: entry->dim = dim;
228: entry->next = NULL;
229: if (!DMPlexGenerateList) DMPlexGenerateList = entry;
230: else {
231: PetscFunctionList fl = DMPlexGenerateList;
232: while (fl->next) fl = fl->next;
233: fl->next = entry;
234: }
235: return(0);
236: }
238: extern PetscBool DMPlexGenerateRegisterAllCalled;
240: PetscErrorCode DMPlexGenerateRegisterDestroy(void)
241: {
242: PetscFunctionList next,fl;
243: PetscErrorCode ierr;
246: next = fl = DMPlexGenerateList;
247: while (next) {
248: next = fl ? fl->next : NULL;
249: if (fl) {PetscFree(fl->name);}
250: PetscFree(fl);
251: fl = next;
252: }
253: DMPlexGenerateList = NULL;
254: DMPlexGenerateRegisterAllCalled = PETSC_FALSE;
255: return(0);
256: }