Actual source code: unstructured_2d.c

  1: #ifdef PETSC_RCS_HEADER
  2: static char vcid[] = "$Id: unstructured_2d.c,v 1.5 2000/02/01 17:02:51 knepley Exp $";
  3: #endif

  5: static char help[] = "This example deals with 2D unstructured meshes.\n\n";

  7: #include "unstructured_2d.h"

  9: /*
 10:   Here we will create a series of refined 2D unstructured meshes.
 11: */
 12: #undef  __FUNCT__
 14: int main(int argc, char **args)
 15: {
 16:   MeshContext ctx; /* Holds problem specific information */
 17:   int         ierr;

 20:   PetscInitialize(&argc, &args, 0, help);                                    CHKERRABORT(PETSC_COMM_WORLD, ierr);

 22:   MeshContextCreate(PETSC_COMM_WORLD, &ctx);                                 CHKERRABORT(PETSC_COMM_WORLD, ierr);
 23:   MeshContextRun(ctx);                                                       CHKERRABORT(PETSC_COMM_WORLD, ierr);
 24:   MeshContextDestroy(ctx);                                                   CHKERRABORT(PETSC_COMM_WORLD, ierr);

 26:   CHKMEMQ;
 27:   PetscFinalize();
 28:   return(0);
 29: }

 31: /*--------------------------------------------- MeshContext Creation -------------------------------------------------*/
 32: #undef  __FUNCT__
 34: /*@
 35:   MeshContextCreate - This function initializes the Mesh context.

 37:   Collective on MPI_Comm

 39:   Input Parameter:
 40: . comm - The communicator

 42:   Output Parameter:
 43: . mCtx - The MeshContext

 45:   Level: beginner

 47: .keywords: Mesh, context, create
 48: .seealso: MeshContextDestroy(), MeshContextPrint(), MeshContextSetup()
 49: @*/
 50: int MeshContextCreate(MPI_Comm comm, MeshContext *mCtx)
 51: {
 52:   MeshContext ctx;

 55:   /* Setup context */
 56:   PetscHeaderCreate(ctx, _MeshContext, int, PETSC_VIEWER_COOKIE, -1, "context", comm, 0, 0);
 57:   PetscLogObjectCreate(ctx);
 58:   PetscLogObjectMemory(ctx, sizeof(struct _MeshContext));

 60:   /* Initialize subobjects */
 61:   ctx->mesh = PETSC_NULL;
 62:   /* Set for vertices only */
 63:   ctx->numLocalNodes = 3;
 64:   /* Setup domain */
 65:   ctx->geometryCtx.size[0]  = 2.0;
 66:   ctx->geometryCtx.size[1]  = 2.0;
 67:   ctx->geometryCtx.start[0] = 0.0;
 68:   ctx->geometryCtx.start[1] = 0.0;
 69:   /* Setup refinement */
 70:   ctx->geometryCtx.maxArea  = 0.5;
 71:   ctx->geometryCtx.areaFunc = PointFunctionConstant;
 72:   ctx->geometryCtx.areaCtx  = PETSC_NULL;
 73:   /* Initialize problem loop */
 74:   ctx->numRefine  = 0;
 75:   ctx->numCoarsen = 0;

 77:   *mCtx = ctx;
 78:   return(0);
 79: }

 81: #undef  __FUNCT__
 83: /*@
 84:   MeshContextDestroy - This function destroys the Mesh context.

 86:   Collective on MeshContext

 88:   Input Parameter:
 89: . ctx - The MeshContext

 91:   Level: beginner

 93: .keywords: Mesh, context, destroy
 94: .seealso: MeshContextCreate()
 95: @*/
 96: int MeshContextDestroy(MeshContext ctx)
 97: {
 99:   if (--ctx->refct > 0) SETERRQ(PETSC_ERR_PLIB, "Mesh context should not be referenced more than once");
100:   PetscLogObjectDestroy(ctx);
101:   PetscHeaderDestroy(ctx);
102:   return(0);
103: }

105: /*------------------------------------------------ Mesh Creation -----------------------------------------------------*/
106: /*@
107:   MeshContextSetup - This function initializes all internal variables through options and creates the mesh.

109:   Collective on MeshContext

111:   Input Parameter:
112: . ctx - A MeshContext

114:   Options Database Keys:
115: + num_local_nodes - The number of nodes on an element
116: . num_refine      - The number of times to refine the mesh
117: . num_coarsen     - The number of times to coarsen the mesh
118: - mesh_max_area   - The maximum area of an element after refinement

120:   Level: beginner

122: .seealso MeshContextCleanup(), MeshContextCreate()
123: @*/
124: #undef  __FUNCT__
126: int MeshContextSetup(MeshContext ctx)
127: {
128:   PetscTruth opt;
129:   int        ierr;

132:   /* The number of local nodes (usually either 3 or 6) */
133:   PetscOptionsGetInt(PETSC_NULL, "-num_local_nodes",  &ctx->numLocalNodes,  &opt);
134:   /* The number of times to refine the mesh */
135:   PetscOptionsGetInt(PETSC_NULL, "-num_refine",  &ctx->numRefine,  &opt);
136:   /* The number of times to coarsen the mesh */
137:   PetscOptionsGetInt(PETSC_NULL, "-num_coarsen", &ctx->numCoarsen, &opt);
138:   /* Setup refinement */
139:   PetscOptionsGetReal("mesh", "-max_area", &ctx->geometryCtx.maxArea, &opt);

141:   MeshContextCreateMesh(ctx);
142:   return(0);
143: }

145: #undef  __FUNCT__
147: /*@
148:   MeshContextCreateMesh - This function creates a mesh

150:   Collective on MeshContext

152:   Input Parameter:
153: . ctx - A MeshContext

155:   Level: beginner

157: .seealso MeshContextRefineMesh(), MeshContextSetup(), MeshContextCleanup()
158: @*/
159: int MeshContextCreateMesh(MeshContext ctx)
160: {
161:   MeshGeometryContext *geomCtx = &ctx->geometryCtx;
162:   int                  meshInfo[4], globalMeshInfo[4];
163:   char                 name[256];
164:   int                  ierr;

167:   /* Setup mesh boundary */
168:   MeshBoundary2DCreateSimple(ctx->comm, &ctx->geometryCtx, &ctx->boundaryCtx);
169:   /* Construct the mesh */
170:   MeshCreate(ctx->comm, &ctx->mesh);
171:   MeshSetDimension(ctx->mesh, 2);
172:   MeshSetPeriodicDimension(ctx->mesh, 0, geomCtx->isPeriodic[0]);
173:   MeshSetPeriodicDimension(ctx->mesh, 1, geomCtx->isPeriodic[1]);
174:   MeshSetNumCorners(ctx->mesh, 6);
175:   MeshSetBoundary(ctx->mesh, &ctx->boundaryCtx);
176:   sprintf(name, "mesh.r%.4g", geomCtx->maxArea);
177:   PetscObjectSetName((PetscObject) ctx->mesh, name);
178:   MeshSetFromOptions(ctx->mesh);
179:   if (ctx->geometryCtx.areaCtx != PETSC_NULL) {
180:     MeshSetUserContext(ctx->mesh, ctx->geometryCtx.areaCtx);
181:   } else {
182:     MeshSetUserContext(ctx->mesh, &ctx->geometryCtx.maxArea);
183:   }
184:   MeshBoundary2DDestroy(ctx->comm, &ctx->boundaryCtx);
185:   /* Output mesh information */
186:   MeshGetInfo(ctx->mesh, &meshInfo[0], &meshInfo[1], &meshInfo[2], &meshInfo[3]);
187:   MPI_Allreduce(meshInfo, globalMeshInfo, 4, MPI_INT, MPI_SUM, ctx->comm);
188:   PetscPrintf(ctx->comm, "Elements: %d Vertices: %d Nodes: %d Edges: %d\n",
189:               globalMeshInfo[3], meshInfo[0], globalMeshInfo[1], globalMeshInfo[2]);

191:   return(0);
192: }

194: #undef  __FUNCT__
196: /*@
197:   MeshContextRefineMesh - This function refines the mesh

199:   Collective on MeshContext

201:   Input Parameters:
202: . ctx - A MeshContextContext

204:   Level: beginner

206: .seealso MeshContextCoarsenMesh(), MeshContextCreateMesh(), MeshContextCleanup()
207: @*/
208: int MeshContextRefineMesh(MeshContext ctx)
209: {
210:   MeshGeometryContext *geomCtx = &ctx->geometryCtx;
211:   Mesh                 refMesh;
212:   int                  meshInfo[4], globalMeshInfo[4];
213:   char                 name[256];
214:   int                  ierr;

217:   /* Decrease feature size */
218:   geomCtx->maxArea *= 0.5;
219:   /* Construct a refined mesh */
220:   MeshRefine(ctx->mesh, geomCtx->areaFunc, &refMesh);
221:   if (geomCtx->areaCtx != PETSC_NULL) {
222:     MeshSetUserContext(refMesh, geomCtx->areaCtx);
223:   } else {
224:     MeshSetUserContext(refMesh, &geomCtx->maxArea);
225:   }
226:   MeshSetOptionsPrefix(refMesh, "ref_");
227:   sprintf(name, "mesh.r%.4g", geomCtx->maxArea);
228:   PetscObjectSetName((PetscObject) refMesh, name);
229:   MeshSetFromOptions(refMesh);
230: #ifdef PETSC_USE_BOPT_g
231:   CHKMEMQ;
232: #endif
233:   /* Output new mesh information */
234:   MeshGetInfo(refMesh, &meshInfo[0], &meshInfo[1], &meshInfo[2], &meshInfo[3]);
235:   MPI_Allreduce(meshInfo, globalMeshInfo, 4, MPI_INT, MPI_SUM, ctx->comm);
236:   PetscPrintf(ctx->comm, "Elements: %d Vertices: %d Nodes: %d Edges: %d\n",
237:               globalMeshInfo[3], meshInfo[0], globalMeshInfo[1], globalMeshInfo[2]);

239:   /* Replace old mesh with refined mesh */
240:   MeshDestroy(ctx->mesh);
241:   ctx->mesh = refMesh;
242:   return(0);
243: }

245: #undef  __FUNCT__
247: /*@
248:   MeshContextCoarsenMesh - This function coarsen the mesh

250:   Collective on MeshContext

252:   Input Parameters:
253: . ctx - A MeshContextContext

255:   Level: beginner

257: .seealso MeshContextRefineMesh(), MeshContextCreateMesh(), MeshContextCleanup()
258: @*/
259: int MeshContextCoarsenMesh(MeshContext ctx)
260: {
262:   SETERRQ(PETSC_ERR_SUP, "No coarsening available yet");
263:   return(0);
264: }

266: #undef  __FUNCT__
268: /*@
269:   MeshContextSetup - This function destroys all internal variables including the mesh.

271:   Collective on MeshContext

273:   Input Parameter:
274: . ctx - A MeshContext

276:   Level: beginner

278: .seealso MeshContextSetup(), MeshContextCreate()
279: @*/
280: int MeshContextCleanup(MeshContext ctx)
281: {

285:   MeshDestroy(ctx->mesh);
286:   return(0);
287: }

289: /*---------------------------------------------- Sanity Checks ------------------------------------------------------*/

291: /*---------------------------------------------- Problem Callbacks --------------------------------------------------*/

293: /*---------------------------------------------- Main Computation ---------------------------------------------------*/
294: #undef  __FUNCT__
296: int MeshContextRun(MeshContext ctx)
297: {
298:   int loop;

302:   MeshContextSetup(ctx);

304:   for(loop = 0; loop < ctx->numRefine; loop++) {
305:     MeshContextRefineMesh(ctx);
306:   }
307:   for(loop = 0; loop < ctx->numCoarsen; loop++) {
308:     MeshContextCoarsenMesh(ctx);
309:   }

311:   MeshContextCleanup(ctx);
312:   return(0);
313: }