xref: /petsc/src/dm/impls/plex/plexgenerate.c (revision 2c4dacf2bcf83418e1486b771c34b1b8bd2c53b3)
1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
2d9deefdfSMatthew G. Knepley 
3d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexInvertCell_Internal(PetscInt dim, PetscInt numCorners, PetscInt cone[])
4d9deefdfSMatthew G. Knepley {
5d9deefdfSMatthew G. Knepley   int tmpc;
6d9deefdfSMatthew G. Knepley 
7d9deefdfSMatthew G. Knepley   PetscFunctionBegin;
8d9deefdfSMatthew G. Knepley   if (dim != 3) PetscFunctionReturn(0);
9d9deefdfSMatthew G. Knepley   switch (numCorners) {
10d9deefdfSMatthew G. Knepley   case 4:
11d9deefdfSMatthew G. Knepley     tmpc    = cone[0];
12d9deefdfSMatthew G. Knepley     cone[0] = cone[1];
13d9deefdfSMatthew G. Knepley     cone[1] = tmpc;
14d9deefdfSMatthew G. Knepley     break;
15d9deefdfSMatthew G. Knepley   case 8:
16d9deefdfSMatthew G. Knepley     tmpc    = cone[1];
17d9deefdfSMatthew G. Knepley     cone[1] = cone[3];
18d9deefdfSMatthew G. Knepley     cone[3] = tmpc;
19d9deefdfSMatthew G. Knepley     break;
20d9deefdfSMatthew G. Knepley   default: break;
21d9deefdfSMatthew G. Knepley   }
22d9deefdfSMatthew G. Knepley   PetscFunctionReturn(0);
23d9deefdfSMatthew G. Knepley }
24d9deefdfSMatthew G. Knepley 
25d9deefdfSMatthew G. Knepley /*@C
26d9deefdfSMatthew G. Knepley   DMPlexInvertCell - This flips tetrahedron and hexahedron orientation since Plex stores them internally with outward normals. Other cells are left untouched.
27d9deefdfSMatthew G. Knepley 
28d9deefdfSMatthew G. Knepley   Input Parameters:
29d9deefdfSMatthew G. Knepley + numCorners - The number of vertices in a cell
30d9deefdfSMatthew G. Knepley - cone - The incoming cone
31d9deefdfSMatthew G. Knepley 
32d9deefdfSMatthew G. Knepley   Output Parameter:
33d9deefdfSMatthew G. Knepley . cone - The inverted cone (in-place)
34d9deefdfSMatthew G. Knepley 
35d9deefdfSMatthew G. Knepley   Level: developer
36d9deefdfSMatthew G. Knepley 
37d9deefdfSMatthew G. Knepley .seealso: DMPlexGenerate()
38d9deefdfSMatthew G. Knepley @*/
39d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexInvertCell(PetscInt dim, PetscInt numCorners, int cone[])
40d9deefdfSMatthew G. Knepley {
41d9deefdfSMatthew G. Knepley   int tmpc;
42d9deefdfSMatthew G. Knepley 
43d9deefdfSMatthew G. Knepley   PetscFunctionBegin;
44d9deefdfSMatthew G. Knepley   if (dim != 3) PetscFunctionReturn(0);
45d9deefdfSMatthew G. Knepley   switch (numCorners) {
46d9deefdfSMatthew G. Knepley   case 4:
47d9deefdfSMatthew G. Knepley     tmpc    = cone[0];
48d9deefdfSMatthew G. Knepley     cone[0] = cone[1];
49d9deefdfSMatthew G. Knepley     cone[1] = tmpc;
50d9deefdfSMatthew G. Knepley     break;
51d9deefdfSMatthew G. Knepley   case 8:
52d9deefdfSMatthew G. Knepley     tmpc    = cone[1];
53d9deefdfSMatthew G. Knepley     cone[1] = cone[3];
54d9deefdfSMatthew G. Knepley     cone[3] = tmpc;
55d9deefdfSMatthew G. Knepley     break;
56d9deefdfSMatthew G. Knepley   default: break;
57d9deefdfSMatthew G. Knepley   }
58d9deefdfSMatthew G. Knepley   PetscFunctionReturn(0);
59d9deefdfSMatthew G. Knepley }
60d9deefdfSMatthew G. Knepley 
61d9deefdfSMatthew G. Knepley 
6294ef8ddeSSatish Balay /*@C
63d9deefdfSMatthew G. Knepley   DMPlexTriangleSetOptions - Set the options used for the Triangle mesh generator
64d9deefdfSMatthew G. Knepley 
65d9deefdfSMatthew G. Knepley   Not Collective
66d9deefdfSMatthew G. Knepley 
67d9deefdfSMatthew G. Knepley   Inputs Parameters:
68d9deefdfSMatthew G. Knepley + dm - The DMPlex object
69d9deefdfSMatthew G. Knepley - opts - The command line options
70d9deefdfSMatthew G. Knepley 
71d9deefdfSMatthew G. Knepley   Level: developer
72d9deefdfSMatthew G. Knepley 
73d9deefdfSMatthew G. Knepley .seealso: DMPlexTetgenSetOptions(), DMPlexGenerate()
74d9deefdfSMatthew G. Knepley @*/
75d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexTriangleSetOptions(DM dm, const char *opts)
76d9deefdfSMatthew G. Knepley {
77d9deefdfSMatthew G. Knepley   DM_Plex       *mesh = (DM_Plex*) dm->data;
78d9deefdfSMatthew G. Knepley   PetscErrorCode ierr;
79d9deefdfSMatthew G. Knepley 
80d9deefdfSMatthew G. Knepley   PetscFunctionBegin;
81d9deefdfSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
82d9deefdfSMatthew G. Knepley   PetscValidPointer(opts, 2);
83606ac3a5SMatthew G. Knepley   ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr);
84606ac3a5SMatthew G. Knepley   ierr = PetscStrallocpy(opts, &mesh->triangleOpts);CHKERRQ(ierr);
85d9deefdfSMatthew G. Knepley   PetscFunctionReturn(0);
86d9deefdfSMatthew G. Knepley }
87d9deefdfSMatthew G. Knepley 
8894ef8ddeSSatish Balay /*@C
89d9deefdfSMatthew G. Knepley   DMPlexTetgenSetOptions - Set the options used for the Tetgen mesh generator
90d9deefdfSMatthew G. Knepley 
91d9deefdfSMatthew G. Knepley   Not Collective
92d9deefdfSMatthew G. Knepley 
93d9deefdfSMatthew G. Knepley   Inputs Parameters:
94d9deefdfSMatthew G. Knepley + dm - The DMPlex object
95d9deefdfSMatthew G. Knepley - opts - The command line options
96d9deefdfSMatthew G. Knepley 
97d9deefdfSMatthew G. Knepley   Level: developer
98d9deefdfSMatthew G. Knepley 
99d9deefdfSMatthew G. Knepley .seealso: DMPlexTriangleSetOptions(), DMPlexGenerate()
100d9deefdfSMatthew G. Knepley @*/
101d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexTetgenSetOptions(DM dm, const char *opts)
102d9deefdfSMatthew G. Knepley {
103d9deefdfSMatthew G. Knepley   DM_Plex       *mesh = (DM_Plex*) dm->data;
104d9deefdfSMatthew G. Knepley   PetscErrorCode ierr;
105d9deefdfSMatthew G. Knepley 
106d9deefdfSMatthew G. Knepley   PetscFunctionBegin;
107d9deefdfSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
108d9deefdfSMatthew G. Knepley   PetscValidPointer(opts, 2);
109606ac3a5SMatthew G. Knepley   ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr);
110606ac3a5SMatthew G. Knepley   ierr = PetscStrallocpy(opts, &mesh->tetgenOpts);CHKERRQ(ierr);
111d9deefdfSMatthew G. Knepley   PetscFunctionReturn(0);
112d9deefdfSMatthew G. Knepley }
113d9deefdfSMatthew G. Knepley 
1143a074057SBarry Smith /*
1153a074057SBarry Smith    Contains the list of registered DMPlexGenerators routines
1163a074057SBarry Smith */
1173a074057SBarry Smith PetscFunctionList DMPlexGenerateList = NULL;
118d9deefdfSMatthew G. Knepley 
1193a074057SBarry Smith struct _n_PetscFunctionList {
1203a074057SBarry Smith   PetscErrorCode    (*generate)(DM, PetscBool, DM*);
1213a074057SBarry Smith   PetscErrorCode    (*refine)(DM,double*, DM*);
1223a074057SBarry Smith   char              *name;               /* string to identify routine */
1233a074057SBarry Smith   PetscInt          dim;
1243a074057SBarry Smith   PetscFunctionList next;                /* next pointer */
1253a074057SBarry Smith };
126d9deefdfSMatthew G. Knepley 
127d9deefdfSMatthew G. Knepley /*@C
128d9deefdfSMatthew G. Knepley   DMPlexGenerate - Generates a mesh.
129d9deefdfSMatthew G. Knepley 
130d9deefdfSMatthew G. Knepley   Not Collective
131d9deefdfSMatthew G. Knepley 
132d9deefdfSMatthew G. Knepley   Input Parameters:
133d9deefdfSMatthew G. Knepley + boundary - The DMPlex boundary object
134d9deefdfSMatthew G. Knepley . name - The mesh generation package name
135d9deefdfSMatthew G. Knepley - interpolate - Flag to create intermediate mesh elements
136d9deefdfSMatthew G. Knepley 
137d9deefdfSMatthew G. Knepley   Output Parameter:
138d9deefdfSMatthew G. Knepley . mesh - The DMPlex object
139d9deefdfSMatthew G. Knepley 
140*2c4dacf2SBarry Smith   Options Database:
141*2c4dacf2SBarry Smith +  -dm_plex_generate <name> - package to generate mesh, for example, triangle, ctetgen or tetgen
142*2c4dacf2SBarry Smith -  -dm_plex_generator <name> - package to generate mesh, for example, triangle, ctetgen or tetgen (deprecated)
143*2c4dacf2SBarry Smith 
144d9deefdfSMatthew G. Knepley   Level: intermediate
145d9deefdfSMatthew G. Knepley 
146d9deefdfSMatthew G. Knepley .seealso: DMPlexCreate(), DMRefine()
147d9deefdfSMatthew G. Knepley @*/
148d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh)
149d9deefdfSMatthew G. Knepley {
150d9deefdfSMatthew G. Knepley   PetscInt          dim;
151d9deefdfSMatthew G. Knepley   char              genname[1024];
1523a074057SBarry Smith   PetscBool         flg;
153d9deefdfSMatthew G. Knepley   PetscErrorCode    ierr;
1543a074057SBarry Smith   PetscFunctionList fl;
155*2c4dacf2SBarry Smith   const char*       suggestions;
156d9deefdfSMatthew G. Knepley 
157d9deefdfSMatthew G. Knepley   PetscFunctionBegin;
158d9deefdfSMatthew G. Knepley   PetscValidHeaderSpecific(boundary, DM_CLASSID, 1);
159d9deefdfSMatthew G. Knepley   PetscValidLogicalCollectiveBool(boundary, interpolate, 2);
160d9deefdfSMatthew G. Knepley   ierr = DMGetDimension(boundary, &dim);CHKERRQ(ierr);
161c5929fdfSBarry Smith   ierr = PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generator", genname, 1024, &flg);CHKERRQ(ierr);
162d9deefdfSMatthew G. Knepley   if (flg) name = genname;
163*2c4dacf2SBarry Smith   else {
164*2c4dacf2SBarry Smith     ierr = PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generate", genname, 1024, &flg);CHKERRQ(ierr);
165*2c4dacf2SBarry Smith     if (flg) name = genname;
166*2c4dacf2SBarry Smith   }
1673a074057SBarry Smith 
1683a074057SBarry Smith   fl = DMPlexGenerateList;
169d9deefdfSMatthew G. Knepley   if (name) {
1703a074057SBarry Smith     while (fl) {
1713a074057SBarry Smith       ierr = PetscStrcmp(fl->name,name,&flg);CHKERRQ(ierr);
1723a074057SBarry Smith       if (flg) {
173367003a6SStefano Zampini         ierr = (*fl->generate)(boundary,interpolate,mesh);CHKERRQ(ierr);
1743a074057SBarry Smith         PetscFunctionReturn(0);
175d9deefdfSMatthew G. Knepley       }
1763a074057SBarry Smith       fl = fl->next;
177d9deefdfSMatthew G. Knepley     }
178*2c4dacf2SBarry Smith     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);
1793a074057SBarry Smith   } else {
1803a074057SBarry Smith     while (fl) {
1813a074057SBarry Smith       if (boundary->dim == fl->dim) {
182367003a6SStefano Zampini         ierr = (*fl->generate)(boundary,interpolate,mesh);CHKERRQ(ierr);
1833a074057SBarry Smith         PetscFunctionReturn(0);
1843a074057SBarry Smith       }
1853a074057SBarry Smith       fl = fl->next;
1863a074057SBarry Smith     }
187*2c4dacf2SBarry Smith     suggestions = "";
188*2c4dacf2SBarry Smith     if (boundary->dim+1 == 2) suggestions = " You may need to add --download-triangle to your ./configure options";
189*2c4dacf2SBarry Smith     else if (boundary->dim+1 == 3) suggestions = " You may need to add --download-ctetgen or --download-tetgen in your ./configure options";
190*2c4dacf2SBarry Smith     SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"No grid generator of dimension %D registered%s",boundary->dim+1,suggestions);
1913a074057SBarry Smith   }
1923a074057SBarry Smith   PetscFunctionReturn(0);
1933a074057SBarry Smith }
1943a074057SBarry Smith 
1953a074057SBarry Smith /*@C
1963a074057SBarry Smith   DMPlexGenerateRegister -  Adds a grid generator to DMPlex
1973a074057SBarry Smith 
1983a074057SBarry Smith    Not Collective
1993a074057SBarry Smith 
2003a074057SBarry Smith    Input Parameters:
201cd921712SStefano Zampini +  name_solver - name of a new user-defined grid generator
2023a074057SBarry Smith .  fnc - generator function
2033a074057SBarry Smith .  rfnc - refinement function
2043a074057SBarry Smith -  dim - dimension of boundary of domain
2053a074057SBarry Smith 
2063a074057SBarry Smith    Notes:
2073a074057SBarry Smith    DMPlexGenerateRegister() may be called multiple times to add several user-defined solvers.
2083a074057SBarry Smith 
2093a074057SBarry Smith    Sample usage:
2103a074057SBarry Smith .vb
211cd921712SStefano Zampini    DMPlexGenerateRegister("my_generator",MyGeneratorCreate,MyGeneratorRefiner,dim);
2123a074057SBarry Smith .ve
2133a074057SBarry Smith 
2143a074057SBarry Smith    Then, your generator can be chosen with the procedural interface via
215cd921712SStefano Zampini $     DMPlexGenerate(dm,"my_generator",...)
2163a074057SBarry Smith    or at runtime via the option
217cd921712SStefano Zampini $     -dm_plex_generator my_generator
2183a074057SBarry Smith 
2193a074057SBarry Smith    Level: advanced
2203a074057SBarry Smith 
221cd921712SStefano Zampini .seealso: DMPlexGenerateRegisterAll(), DMPlexGenerate(), DMPlexGenerateRegisterDestroy()
2223a074057SBarry Smith 
2233a074057SBarry Smith @*/
2243a074057SBarry Smith PetscErrorCode  DMPlexGenerateRegister(const char sname[],PetscErrorCode (*fnc)(DM, PetscBool,DM*), PetscErrorCode (*rfnc)(DM, double*,DM*),PetscInt dim)
2253a074057SBarry Smith {
2263a074057SBarry Smith   PetscErrorCode    ierr;
2273a074057SBarry Smith   PetscFunctionList entry;
2283a074057SBarry Smith 
2293a074057SBarry Smith   PetscFunctionBegin;
2303a074057SBarry Smith   ierr            = PetscNew(&entry);CHKERRQ(ierr);
2313a074057SBarry Smith   ierr            = PetscStrallocpy(sname,&entry->name);CHKERRQ(ierr);
2323a074057SBarry Smith   entry->generate = fnc;
2333a074057SBarry Smith   entry->refine   = rfnc;
2343a074057SBarry Smith   entry->dim      = dim;
2353a074057SBarry Smith   entry->next     = NULL;
2363a074057SBarry Smith   if (!DMPlexGenerateList) DMPlexGenerateList = entry;
2373a074057SBarry Smith   else {
2383a074057SBarry Smith     PetscFunctionList fl = DMPlexGenerateList;
2393a074057SBarry Smith     while (fl->next) fl = fl->next;
2403a074057SBarry Smith     fl->next = entry;
2413a074057SBarry Smith   }
2423a074057SBarry Smith   PetscFunctionReturn(0);
2433a074057SBarry Smith }
2443a074057SBarry Smith 
2453a074057SBarry Smith extern PetscBool DMPlexGenerateRegisterAllCalled;
2463a074057SBarry Smith 
2473a074057SBarry Smith PetscErrorCode  DMPlexGenerateRegisterDestroy(void)
2483a074057SBarry Smith {
2493a074057SBarry Smith   PetscFunctionList next,fl;
2503a074057SBarry Smith   PetscErrorCode    ierr;
2513a074057SBarry Smith 
2523a074057SBarry Smith   PetscFunctionBegin;
2533a074057SBarry Smith   next = fl =  DMPlexGenerateList;
2543a074057SBarry Smith     while (next) {
2553a074057SBarry Smith     next = fl ? fl->next : NULL;
2563a074057SBarry Smith     if (fl) {ierr = PetscFree(fl->name);CHKERRQ(ierr);}
2573a074057SBarry Smith     ierr = PetscFree(fl);CHKERRQ(ierr);
2583a074057SBarry Smith     fl = next;
2593a074057SBarry Smith   }
2603a074057SBarry Smith   DMPlexGenerateList              = NULL;
2613a074057SBarry Smith   DMPlexGenerateRegisterAllCalled = PETSC_FALSE;
262d9deefdfSMatthew G. Knepley   PetscFunctionReturn(0);
263d9deefdfSMatthew G. Knepley }
264