Actual source code: ex1.c
petsc-dev 2014-02-02
1: static char help[] = "Run C version of TetGen to construct and refine a mesh\n\n";
3: #include <petscdmplex.h>
5: #if defined(PETSC_HAVE_CGNS)
6: #include <cgnslib.h>
7: #endif
9: typedef struct {
10: DM dm; /* REQUIRED in order to use SNES evaluation functions */
11: PetscInt debug; /* The debugging level */
12: PetscLogEvent createMeshEvent;
13: /* Domain and mesh definition */
14: PetscInt dim; /* The topological mesh dimension */
15: PetscBool interpolate; /* Generate intermediate mesh elements */
16: PetscBool refinementUniform; /* Uniformly refine the mesh */
17: PetscReal refinementLimit; /* The largest allowable cell volume */
18: PetscBool cellSimplex; /* Use simplices or hexes */
19: char filename[PETSC_MAX_PATH_LEN]; /* Import mesh from file */
20: } AppCtx;
24: PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
25: {
29: options->debug = 0;
30: options->dim = 2;
31: options->interpolate = PETSC_FALSE;
32: options->refinementUniform = PETSC_FALSE;
33: options->refinementLimit = 0.0;
34: options->cellSimplex = PETSC_TRUE;
35: options->filename[0] = '\0';
37: PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");
38: PetscOptionsInt("-debug", "The debugging level", "ex1.c", options->debug, &options->debug, NULL);
39: PetscOptionsInt("-dim", "The topological mesh dimension", "ex1.c", options->dim, &options->dim, NULL);
40: PetscOptionsBool("-interpolate", "Generate intermediate mesh elements", "ex1.c", options->interpolate, &options->interpolate, NULL);
41: PetscOptionsBool("-refinement_uniform", "Uniformly refine the mesh", "ex1.c", options->refinementUniform, &options->refinementUniform, NULL);
42: PetscOptionsReal("-refinement_limit", "The largest allowable cell volume", "ex1.c", options->refinementLimit, &options->refinementLimit, NULL);
43: PetscOptionsBool("-cell_simplex", "Use simplices if true, otherwise hexes", "ex1.c", options->cellSimplex, &options->cellSimplex, NULL);
44: PetscOptionsString("-filename", "The mesh file", "ex7.c", options->filename, options->filename, PETSC_MAX_PATH_LEN, NULL);
45: PetscOptionsEnd();
47: PetscLogEventRegister("CreateMesh", DM_CLASSID, &options->createMeshEvent);
48: return(0);
49: };
53: PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
54: {
55: PetscInt dim = user->dim;
56: PetscBool interpolate = user->interpolate;
57: PetscBool refinementUniform = user->refinementUniform;
58: PetscReal refinementLimit = user->refinementLimit;
59: PetscBool cellSimplex = user->cellSimplex;
60: const char *filename = user->filename;
61: const char *partitioner = "chaco";
62: size_t len;
63: PetscMPIInt rank;
67: PetscLogEventBegin(user->createMeshEvent,0,0,0,0);
68: MPI_Comm_rank(comm, &rank);
69: PetscStrlen(filename, &len);
70: if (len) {
71: const char *extGmsh = ".msh";
72: size_t slen;
73: PetscBool isGmsh;
75: PetscStrncmp(&filename[PetscMax(0,len-4)], extGmsh, 4, &isGmsh);
76: if (isGmsh) {
77: PetscViewer viewer;
79: PetscViewerCreate(comm, &viewer);
80: PetscViewerSetType(viewer, PETSCVIEWERASCII);
81: PetscViewerFileSetMode(viewer, FILE_MODE_READ);
82: PetscViewerFileSetName(viewer, filename);
83: DMPlexCreateGmsh(comm, viewer, interpolate, dm);
84: PetscViewerDestroy(&viewer);
85: } else {
86: #if defined(PETSC_HAVE_CGNS)
87: int cgid = -1;
89: if (!rank) {
90: cg_open(filename, CG_MODE_READ, &cgid);
91: if (cgid <= 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "cg_open(\"%s\",...) did not return a valid file ID", filename);
92: }
93: DMPlexCreateCGNS(comm, cgid, interpolate, dm);
94: if (!rank) {cg_close(cgid);}
95: #else
96: SETERRQ(comm, PETSC_ERR_SUP, "Loading meshes requires CGNS support. Reconfigure using --with-cgns-dir");
97: #endif
98: }
99: } else if (cellSimplex) {
100: DMPlexCreateBoxMesh(comm, dim, interpolate, dm);
101: } else {
102: const PetscInt cells[3] = {2, 2, 2};
104: DMPlexCreateHexBoxMesh(comm, dim, cells, dm);
105: }
106: {
107: DM refinedMesh = NULL;
108: DM distributedMesh = NULL;
110: /* Refine mesh using a volume constraint */
111: DMPlexSetRefinementUniform(*dm, PETSC_FALSE);
112: DMPlexSetRefinementLimit(*dm, refinementLimit);
113: DMRefine(*dm, comm, &refinedMesh);
114: if (refinedMesh) {
115: DMDestroy(dm);
116: *dm = refinedMesh;
117: }
118: /* Distribute mesh over processes */
119: DMPlexDistribute(*dm, partitioner, 0, NULL, &distributedMesh);
120: if (distributedMesh) {
121: DMViewFromOptions(distributedMesh, NULL, "-dm_view");
122: DMDestroy(dm);
123: *dm = distributedMesh;
124: }
125: if (refinementUniform) {
126: DMPlexSetRefinementUniform(*dm, refinementUniform);
127: DMRefine(*dm, comm, &refinedMesh);
128: if (refinedMesh) {
129: DMDestroy(dm);
130: *dm = refinedMesh;
131: }
132: }
133: }
134: PetscObjectSetName((PetscObject) *dm, "Simplical Mesh");
135: DMViewFromOptions(*dm, NULL, "-dm_view");
136: PetscLogEventEnd(user->createMeshEvent,0,0,0,0);
137: user->dm = *dm;
138: return(0);
139: }
143: int main(int argc, char **argv)
144: {
145: AppCtx user; /* user-defined work context */
148: PetscInitialize(&argc, &argv, NULL, help);
149: ProcessOptions(PETSC_COMM_WORLD, &user);
150: CreateMesh(PETSC_COMM_WORLD, &user, &user.dm);
151: DMDestroy(&user.dm);
152: PetscFinalize();
153: return 0;
154: }