Actual source code: ex1.c
petsc-3.4.2 2013-07-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: #if defined(PETSC_HAVE_CGNS)
     72:     int cgid = -1;

     74:     if (!rank) {
     75:       cg_open(filename, CG_MODE_READ, &cgid);
     76:       if (cgid <= 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "cg_open(\"%s\",...) did not return a valid file ID", filename);
     77:     }
     78:     DMPlexCreateCGNS(comm, cgid, interpolate, dm);
     79:     if (!rank) {cg_close(cgid);}
     80: #else
     81:     SETERRQ(comm, PETSC_ERR_SUP, "Loading meshes requires CGNS support. Reconfigure using --with-cgns-dir");
     82: #endif
     83:   } else if (cellSimplex) {
     84:     DMPlexCreateBoxMesh(comm, dim, interpolate, dm);
     85:   } else {
     86:     const PetscInt cells[3] = {2, 2, 2};

     88:     DMPlexCreateHexBoxMesh(comm, dim, cells, dm);
     89:   }
     90:   {
     91:     DM refinedMesh     = NULL;
     92:     DM distributedMesh = NULL;

     94:     /* Refine mesh using a volume constraint */
     95:     DMPlexSetRefinementUniform(*dm, PETSC_FALSE);
     96:     DMPlexSetRefinementLimit(*dm, refinementLimit);
     97:     DMRefine(*dm, comm, &refinedMesh);
     98:     if (refinedMesh) {
     99:       DMDestroy(dm);
    100:       *dm  = refinedMesh;
    101:     }
    102:     /* Distribute mesh over processes */
    103:     DMPlexDistribute(*dm, partitioner, 0, &distributedMesh);
    104:     if (distributedMesh) {
    105:       DMDestroy(dm);
    106:       *dm  = distributedMesh;
    107:     }
    108:     if (refinementUniform) {
    109:       DMPlexSetRefinementUniform(*dm, refinementUniform);
    110:       DMRefine(*dm, comm, &refinedMesh);
    111:       if (refinedMesh) {
    112:         DMDestroy(dm);
    113:         *dm  = refinedMesh;
    114:       }
    115:     }
    116:   }
    117:   PetscObjectSetName((PetscObject) *dm, "Simplical Mesh");
    118:   DMSetFromOptions(*dm);
    119:   PetscLogEventEnd(user->createMeshEvent,0,0,0,0);
    120:   user->dm = *dm;
    121:   return(0);
    122: }

    126: int main(int argc, char **argv)
    127: {
    128:   AppCtx         user;                 /* user-defined work context */

    131:   PetscInitialize(&argc, &argv, NULL, help);
    132:   ProcessOptions(PETSC_COMM_WORLD, &user);
    133:   CreateMesh(PETSC_COMM_WORLD, &user, &user.dm);
    134:   DMDestroy(&user.dm);
    135:   PetscFinalize();
    136:   return 0;
    137: }