Actual source code: ex1.c

petsc-3.6.1 2015-08-06
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: typedef struct {
  6:   DM            dm;                /* REQUIRED in order to use SNES evaluation functions */
  7:   PetscInt      debug;             /* The debugging level */
  8:   PetscLogEvent createMeshEvent;
  9:   /* Domain and mesh definition */
 10:   PetscInt      dim;                          /* The topological mesh dimension */
 11:   PetscBool     interpolate;                  /* Generate intermediate mesh elements */
 12:   PetscReal     refinementLimit;              /* The largest allowable cell volume */
 13:   PetscBool     cellSimplex;                  /* Use simplices or hexes */
 14:   char          filename[PETSC_MAX_PATH_LEN]; /* Import mesh from file */
 15:   PetscBool     testPartition;                /* Use a fixed partitioning for testing */
 16:   PetscInt      overlap;                      /* The cell overlap to use during partitioning */
 17: } AppCtx;

 21: PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
 22: {

 26:   options->debug             = 0;
 27:   options->dim               = 2;
 28:   options->interpolate       = PETSC_FALSE;
 29:   options->refinementLimit   = 0.0;
 30:   options->cellSimplex       = PETSC_TRUE;
 31:   options->filename[0]       = '\0';
 32:   options->testPartition     = PETSC_FALSE;
 33:   options->overlap           = PETSC_FALSE;

 35:   PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");
 36:   PetscOptionsInt("-debug", "The debugging level", "ex1.c", options->debug, &options->debug, NULL);
 37:   PetscOptionsInt("-dim", "The topological mesh dimension", "ex1.c", options->dim, &options->dim, NULL);
 38:   PetscOptionsBool("-interpolate", "Generate intermediate mesh elements", "ex1.c", options->interpolate, &options->interpolate, NULL);
 39:   PetscOptionsReal("-refinement_limit", "The largest allowable cell volume", "ex1.c", options->refinementLimit, &options->refinementLimit, NULL);
 40:   PetscOptionsBool("-cell_simplex", "Use simplices if true, otherwise hexes", "ex1.c", options->cellSimplex, &options->cellSimplex, NULL);
 41:   PetscOptionsString("-filename", "The mesh file", "ex1.c", options->filename, options->filename, PETSC_MAX_PATH_LEN, NULL);
 42:   PetscOptionsBool("-test_partition", "Use a fixed partition for testing", "ex1.c", options->testPartition, &options->testPartition, NULL);
 43:   PetscOptionsInt("-overlap", "The cell overlap for partitioning", "ex1.c", options->overlap, &options->overlap, NULL);
 44:   PetscOptionsEnd();

 46:   PetscLogEventRegister("CreateMesh",          DM_CLASSID,   &options->createMeshEvent);
 47:   return(0);
 48: };

 52: PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
 53: {
 54:   PetscInt       dim             = user->dim;
 55:   PetscBool      interpolate     = user->interpolate;
 56:   PetscReal      refinementLimit = user->refinementLimit;
 57:   PetscBool      cellSimplex     = user->cellSimplex;
 58:   const char    *filename        = user->filename;
 59:   PetscInt       triSizes_n2[2]  = {4, 4};
 60:   PetscInt       triPoints_n2[8] = {3, 5, 6, 7, 0, 1, 2, 4};
 61:   PetscInt       triSizes_n8[8]  = {1, 1, 1, 1, 1, 1, 1, 1};
 62:   PetscInt       triPoints_n8[8] = {0, 1, 2, 3, 4, 5, 6, 7};
 63:   PetscInt       quadSizes[2]    = {2, 2};
 64:   PetscInt       quadPoints[4]   = {2, 3, 0, 1};
 65:   const PetscInt cells[3]        = {2, 2, 2};
 66:   size_t         len;
 67:   PetscMPIInt    rank, numProcs;

 71:   PetscLogEventBegin(user->createMeshEvent,0,0,0,0);
 72:   MPI_Comm_rank(comm, &rank);
 73:   MPI_Comm_size(comm, &numProcs);
 74:   PetscStrlen(filename, &len);
 75:   if (len)              {DMPlexCreateFromFile(comm, filename, interpolate, dm);}
 76:   else if (cellSimplex) {DMPlexCreateBoxMesh(comm, dim, interpolate, dm);}
 77:   else                  {DMPlexCreateHexBoxMesh(comm, dim, cells, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, dm);}
 78:   {
 79:     DM refinedMesh     = NULL;
 80:     DM distributedMesh = NULL;

 82:     if (user->testPartition) {
 83:       const PetscInt  *sizes = NULL;
 84:       const PetscInt  *points = NULL;
 85:       PetscPartitioner part;

 87:       if (!rank) {
 88:         if (dim == 2 && cellSimplex && numProcs == 2) {
 89:            sizes = triSizes_n2; points = triPoints_n2;
 90:         } else if (dim == 2 && cellSimplex && numProcs == 8) {
 91:           sizes = triSizes_n8; points = triPoints_n8;
 92:         } else if (dim == 2 && !cellSimplex && numProcs == 2) {
 93:           sizes = quadSizes; points = quadPoints;
 94:         }
 95:       }
 96:       DMPlexGetPartitioner(*dm, &part);
 97:       PetscPartitionerSetType(part, PETSCPARTITIONERSHELL);
 98:       PetscPartitionerShellSetPartition(part, numProcs, sizes, points);
 99:     }
100:     /* Distribute mesh over processes */
101:     DMPlexDistribute(*dm, 0, NULL, &distributedMesh);
102:     if (distributedMesh) {
103:       DMDestroy(dm);
104:       *dm  = distributedMesh;
105:     }
106:     /* Refine mesh using a volume constraint */
107:     DMPlexSetRefinementUniform(*dm, PETSC_FALSE);
108:     DMPlexSetRefinementLimit(*dm, refinementLimit);
109:     DMRefine(*dm, comm, &refinedMesh);
110:     if (refinedMesh) {
111:       DMDestroy(dm);
112:       *dm  = refinedMesh;
113:     }
114:   }
115:   DMSetFromOptions(*dm);
116:   if (user->overlap) {
117:     DM overlapMesh = NULL;
118:     /* Add the level-1 overlap to refined mesh */
119:     DMPlexDistributeOverlap(*dm, 1, NULL, &overlapMesh);
120:     if (overlapMesh) {
121:       DMView(overlapMesh, PETSC_VIEWER_STDOUT_WORLD);
122:       DMDestroy(dm);
123:       *dm = overlapMesh;
124:     }
125:   }
126:   PetscObjectSetName((PetscObject) *dm, "Simplicial Mesh");
127:   DMViewFromOptions(*dm, NULL, "-dm_view");
128:   PetscLogEventEnd(user->createMeshEvent,0,0,0,0);
129:   user->dm = *dm;
130:   return(0);
131: }

135: int main(int argc, char **argv)
136: {
137:   AppCtx         user;                 /* user-defined work context */

140:   PetscInitialize(&argc, &argv, NULL, help);
141:   ProcessOptions(PETSC_COMM_WORLD, &user);
142:   CreateMesh(PETSC_COMM_WORLD, &user, &user.dm);
143:   DMDestroy(&user.dm);
144:   PetscFinalize();
145:   return 0;
146: }