Actual source code: ex1.c

petsc-dev 2014-02-02
Report Typos and Errors
  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: }