Actual source code: mesh.c

  1: #ifdef PETSC_RCS_HEADER
  2: static char vcid[] = "$Id: mesh.c,v 1.19 2000/10/17 13:48:57 knepley Exp $";
  3: #endif

  5: /*
  6:      Defines the interface to the mesh functions
  7: */

 9:  #include src/mesh/meshimpl.h

 11: /* Logging support */
 12: int MESH_COOKIE;
 13: int MESH_Reform, MESH_IsDistorted, MESH_Partition, MESH_SetupBoundary, MESH_MoveMesh, MESH_CalcNodeVelocities;
 14: int MESH_CalcNodeAccelerations, MESH_CreateLocalCSR, MESH_CreateFullCSR, MESH_CreateDualCSR, MESH_LocatePoint;

 16: /*------------------------------------------------ Generic Operations ------------------------------------------------*/
 17: #undef  __FUNCT__
 19: /*@
 20:   MeshSetUp - Set up any required internal data structures for a Mesh.

 22:   Collective on Mesh

 24:   Input Parameter:
 25: . mesh - The mesh

 27:   Level: beginner

 29: .keywords: Mesh, setup
 30: .seealso: MeshDestroy()
 31: @*/
 32: int MeshSetUp(Mesh mesh)
 33: {

 38:   if (mesh->setupcalled) return(0);
 39:   if (mesh->ops->setup) {
 40:     (*mesh->ops->setup)(mesh);
 41:   }
 42:   return(0);
 43: }

 45: #undef __FUNCT__  
 47: /*
 48:   MeshSetTypeFromOptions - Sets the type of mesh generation from user options.

 50:   Collective on Mesh

 52:   Input Parameter:
 53: . mesh - The mesh

 55:   Level: intermediate

 57: .keywords: Mesh, set, options, database, type
 58: .seealso: MeshSetFromOptions(), MeshSetType()
 59: */
 60: static int MeshSetTypeFromOptions(Mesh mesh)
 61: {
 62:   PetscTruth opt;
 63:   char      *defaultType;
 64:   char       typeName[256];
 65:   int        dim;
 66:   int        ierr;

 69:   MeshGetDimension(mesh, &dim);
 70:   if (mesh->dim == -1) {
 71:     dim  = 2;
 72:     if (mesh->dict != PETSC_NULL) {
 73:       ParameterDictGetInteger(mesh->dict, "dim", &dim);
 74:     }
 75:     MeshSetDimension(mesh, dim);
 76:   }
 77:   if (mesh->type_name != PETSC_NULL) {
 78:     defaultType = mesh->type_name;
 79:   } else {
 80:     switch(dim)
 81:     {
 82:     case 1:
 83:       defaultType = MESH_TRIANGULAR_1D;
 84:       break;
 85:     case 2:
 86:       defaultType = MESH_TRIANGULAR_2D;
 87:       break;
 88:     default:
 89:       SETERRQ1(PETSC_ERR_SUP, "Mesh dimension %d is not supported", dim);
 90:     }
 91:   }

 93:   if (!MeshRegisterAllCalled) {
 94:     MeshRegisterAll(PETSC_NULL);
 95:   }
 96:   PetscOptionsList("-mesh_type", "Mesh generation method"," MeshSetType", MeshList, defaultType, typeName, 256, &opt);
 97: 
 98:   if (opt == PETSC_TRUE) {
 99:     MeshSetType(mesh, typeName);
100:   } else {
101:     MeshSetType(mesh, defaultType);
102:   }
103:   return(0);
104: }

106: #undef __FUNCT__  
108: /*@
109:   MeshSetFromOptions - Sets various Mesh parameters from user options.

111:   Collective on Mesh

113:   Input Parameter:
114: . mesh - The mesh

116:   Notes:  To see all options, run your program with the -help option, or consult the users manual.
117:           Must be called after MeshCreate() but before the Mesh is used.

119:   Level: intermediate

121: .keywords: Mesh, set, options, database
122: .seealso: MeshCreate(), MeshPrintHelp(), MeshSetOptionsPrefix()
123: @*/
124: int MeshSetFromOptions(Mesh mesh)
125: {
126:   Partition  part;
127:   PetscTruth opt;
128:   int        ierr;

132:   PetscOptionsBegin(mesh->comm, mesh->prefix, "Mesh options", "Mesh");

134:   /* Handle generic mesh options */
135:   PetscOptionsHasName(PETSC_NULL, "-help", &opt);
136:   if (opt == PETSC_TRUE) {
137:     MeshPrintHelp(mesh);
138:   }
139:   PetscOptionsGetInt(mesh->prefix, "-mesh_dim", &mesh->dim, &opt);
140:   PetscOptionsGetReal(mesh->prefix, "-mesh_max_aspect_ratio", &mesh->maxAspectRatio, &opt);

142:   /* Handle mesh type options */
143:   MeshSetTypeFromOptions(mesh);

145:   /* Handle specific mesh options */
146:   if (mesh->ops->setfromoptions != PETSC_NULL) {
147:     (*mesh->ops->setfromoptions)(mesh);
148:   }

150:   PetscOptionsEnd();

152:   /* Handle subobject options */
153:   MeshGetPartition(mesh, &part);
154:   PartitionSetFromOptions(part);

156:   MeshViewFromOptions(mesh, mesh->name);
157:   return(0);
158: }

160: #undef  __FUNCT__
162: /*@
163:   MeshViewFromOptions - This function visualizes the mesh based upon user options.

165:   Collective on Mesh

167:   Input Parameter:
168: . mesh - The mesh

170:   Level: intermediate

172: .keywords: Mesh, view, options, database
173: .seealso: MeshSetFromOptions(), MeshView()
174: @*/
175: int MeshViewFromOptions(Mesh mesh, char *title)
176: {
177:   PetscViewer viewer;
178:   PetscDraw   draw;
179:   PetscTruth  opt;
180:   char       *titleStr;
181:   char        typeName[1024];
182:   char        fileName[PETSC_MAX_PATH_LEN];
183:   int         len;
184:   int         ierr;

187:   PetscOptionsHasName(mesh->prefix, "-mesh_view", &opt);
188:   if (opt == PETSC_TRUE) {
189:     PetscOptionsGetString(mesh->prefix, "-mesh_view", typeName, 1024, &opt);
190:     PetscStrlen(typeName, &len);
191:     if (len > 0) {
192:       PetscViewerCreate(mesh->comm, &viewer);
193:       PetscViewerSetType(viewer, typeName);
194:       PetscOptionsGetString(mesh->prefix, "-mesh_view_file", fileName, 1024, &opt);
195:       if (opt == PETSC_TRUE) {
196:         PetscViewerSetFilename(viewer, fileName);
197:       } else {
198:         PetscViewerSetFilename(viewer, mesh->name);
199:       }
200:       MeshView(mesh, viewer);
201:       PetscViewerFlush(viewer);
202:       PetscViewerDestroy(viewer);
203:     } else {
204:       MeshView(mesh, PETSC_NULL);
205:     }
206:   }
207:   PetscOptionsHasName(mesh->prefix, "-mesh_view_draw", &opt);
208:   if (opt == PETSC_TRUE) {
209:     PetscViewerDrawOpen(mesh->comm, 0, 0, 0, 0, 300, 300, &viewer);
210:     PetscViewerDrawGetDraw(viewer, 0, &draw);
211:     if (title != PETSC_NULL) {
212:       titleStr = title;
213:     } else {
214:       PetscObjectName((PetscObject) mesh);                                                         CHKERRQ(ierr) ;
215:       titleStr = mesh->name;
216:     }
217:     PetscDrawSetTitle(draw, titleStr);
218:     MeshView(mesh, viewer);
219:     PetscViewerFlush(viewer);
220:     PetscDrawPause(draw);
221:     PetscViewerDestroy(viewer);
222:   }
223:   return(0);
224: }

226: #undef  __FUNCT__
228: /*@
229:   MeshView - Views a mesh object.

231:   Collective on Mesh

233:   Input Parameters:
234: + mesh   - The mesh
235: - viewer - The viewer with which to view the mesh

237:   Level: beginner

239: .keywords: mesh, view
240: .seealso: MeshDestroy(), PetscViewerDrawOpen()
241: @*/
242: int MeshView(Mesh mesh, PetscViewer viewer)
243: {

248:   if (viewer == PETSC_NULL) {
249:     viewer = PETSC_VIEWER_STDOUT_SELF;
250:   } else {
252:   }
253:   (*mesh->ops->view)(mesh, viewer);
254:   return(0);
255: }

257: #undef  __FUNCT__
259: /*
260:   MeshPreCopy_Private - Executes hook for generic pre-copying actions.

262:   Collective on Mesh

264:   Input Parameter:
265: . mesh - The mesh

267:   Level: developer

269: .keywords: Mesh, copy
270: .seealso: MeshPosCopy_Private(), MeshCopy(), MeshDuplicate(), MeshRefine(), MeshReform()
271: */
272: int MeshPreCopy_Private(Mesh mesh) {
273:   int (*precopy)(Mesh);
274:   int   ierr;

278:   /* Specific operations */
279:   PetscObjectQueryFunction((PetscObject) mesh, "PreCopy", (void (**)(void)) &precopy);
280:   if (precopy != PETSC_NULL) {
281:     (*precopy)(mesh);
282:   }
283:   return(0);
284: }

286: #undef  __FUNCT__
288: /*
289:   MeshPostCopy_Private - Executes hook for generic post-copying actions.

291:   Collective on Mesh

293:   Input Parameters:
294: + mesh    - The mesh
295: - newMesh - The new mesh

297:   Level: developer

299: .keywords: Mesh, copy
300: .seealso: MeshPosCopy_Private(), MeshCopy(), MeshDuplicate(), MeshRefine(), MeshReform()
301: */
302: int MeshPostCopy_Private(Mesh mesh, Mesh newMesh) {
303:   int      (*postcopy)(Mesh, Mesh);
304:   void      *ctx;
305:   PetscTruth isMoving;
306:   int        highlightElement;
307:   int        ierr;

312:   /* Generic operations */
313:   MeshGetUserContext(mesh, &ctx);
314:   MeshSetUserContext(newMesh, ctx);
315:   MeshGetHighlightElement(mesh, &highlightElement);
316:   MeshSetHighlightElement(newMesh, highlightElement);
317:   MeshGetMovement(mesh, &isMoving);
318:   MeshSetMovement(newMesh, isMoving);
319:   /* Specific operations */
320:   PetscObjectQueryFunction((PetscObject) mesh, "PostCopy", (void (**)(void)) &postcopy);
321:   if (postcopy != PETSC_NULL) {
322:     (*postcopy)(mesh, newMesh);
323:   }
324:   return(0);
325: }

327: #undef  __FUNCT__
329: /*@
330:   MeshCopy - Copies all the data from one mesh to another.

332:   Collective on Mesh

334:   Input Parameter:
335: . mesh    - The mesh

337:   Output Parameter:
338: . newmesh - The identical new mesh

340:   Level: beginner

342: .keywords: Mesh, copy
343: .seealso: MeshDuplicate()
344: @*/
345: int MeshCopy(Mesh mesh, Mesh newmesh)
346: {

353:   if (mesh->ops->copy == PETSC_NULL) SETERRQ(PETSC_ERR_SUP, " ");
354:   MeshPreCopy_Private(mesh);
355:   (*mesh->ops->copy)(mesh, newmesh);
356:   MeshPostCopy_Private(mesh, newmesh);
357:   return(0);
358: }

360: #undef  __FUNCT__
362: /*@
363:   MeshDuplicate - Duplicates the Mesh.

365:   Collective on Mesh

367:   Input Parameter:
368: . mesh    - The mesh

370:   Output Parameter:
371: . newmesh - The duplicate mesh

373:   Level: beginner

375: .keywords: mesh, duplicate, copy
376: .seealso: MeshCopy()
377: @*/
378: int MeshDuplicate(Mesh mesh, Mesh *newmesh)
379: {
380:   int   ierr;

385:   if (mesh->ops->duplicate == PETSC_NULL) SETERRQ(PETSC_ERR_SUP, " ");
386:   MeshPreCopy_Private(mesh);
387:   (*mesh->ops->duplicate)(mesh, newmesh);
388:   MeshPostCopy_Private(mesh, *newmesh);
389:   return(0);
390: }

392: #undef  __FUNCT__
394: /*@
395:   MeshDestroy - Destroys a mesh object.

397:   Collective on Mesh

399:   Input Parameter:
400: . mesh - The mesh

402:   Level: beginner

404: .keywords: mesh, destroy
405: .seealso MeshCreate()
406: @*/
407: int MeshDestroy(Mesh mesh)
408: {

413:   if (--mesh->refct > 0) return(0);
414:   (*mesh->ops->destroy)(mesh);
415:   if (mesh->holes != PETSC_NULL) {
416:     PetscFree(mesh->holes);
417:   }
418:   PetscLogObjectDestroy(mesh);
419:   PetscHeaderDestroy(mesh);
420:   return(0);
421: }

423: #undef  __FUNCT__
425: /*@
426:   MeshSetUserContext - Sets the optional user-defined context for a mesh object.

428:   Collective on Mesh

430:   Input Parameters:
431: + mesh   - The mesh
432: - usrCtx - The optional user context

434:   Level: intermediate

436: .keywords: mesh, set, context
437: .seealso: MeshGetUserContext(), GridSetMeshContext()
438: @*/
439: int MeshSetUserContext(Mesh mesh, void *usrCtx)
440: {
443:   mesh->usr = usrCtx;
444:   return(0);
445: }

447: #undef  __FUNCT__
449: /*@
450:   MeshGetUserContext - Gets the optional user-defined context for a mesh object.

452:   Not collective

454:   Input Parameters:
455: . mesh - The mesh

457:   Output Parameters:
458: . usrCtx   - The optional user context

460:   Level: intermediate

462: .keywords: mesh, set, context
463: .seealso: MeshSetUserContext(), GridGetMeshContext()
464: @*/
465: int MeshGetUserContext(Mesh mesh, void **usrCtx)
466: {
470:   *usrCtx = mesh->usr;
471:   return(0);
472: }

474: #undef __FUNCT__  
476: /*@C
477:   MeshSetOptionsPrefix - Sets the prefix used for searching for all Mesh options in the database.

479:   Not collective

481:   Input Parameters:
482: + mesh   - The mesh
483: - prefix - The prefix to prepend to all option names

485:   Notes:
486:   A hyphen (-) must NOT be given at the beginning of the prefix name.
487:   The first character of all runtime options is AUTOMATICALLY the hyphen.

489:   Level: intermediate

491: .keywords: Mesh, set, options, prefix, database
492: .seealso: MeshGetOptionsPrefix(), MeshAppendOptionsPrefix(), MeshSetFromOptions()
493: @*/
494: int MeshSetOptionsPrefix(Mesh mesh, char *prefix)
495: {

500:   PetscObjectSetOptionsPrefix((PetscObject) mesh, prefix);
501:   return(0);
502: }

504: #undef __FUNCT__  
506: /*@C
507:   MeshAppendOptionsPrefix - Appends to the prefix used for searching for all Mesh options in the database.

509:   Not collective

511:   Input Parameters:
512: + mesh   - The mesh
513: - prefix - The prefix to prepend to all option names

515:   Notes:
516:   A hyphen (-) must NOT be given at the beginning of the prefix name.
517:   The first character of all runtime options is AUTOMATICALLY the hyphen.

519:   Level: intermediate

521: .keywords: Mesh, append, options, prefix, database
522: .seealso: MeshGetOptionsPrefix(), MeshSetOptionsPrefix(), MeshSetFromOptions()
523: @*/
524: int MeshAppendOptionsPrefix(Mesh mesh, char *prefix)
525: {
527: 
530:   PetscObjectAppendOptionsPrefix((PetscObject) mesh, prefix);
531:   return(0);
532: }

534: #undef __FUNCT__  
536: /*@
537:   MeshGetOptionsPrefix - Returns the prefix used for searching for all Mesh options in the database.

539:   Input Parameter:
540: . mesh   - The mesh

542:   Output Parameter:
543: . prefix - A pointer to the prefix string used

545:   Level: intermediate

547: .keywords: Mesh, get, options, prefix, database
548: .seealso: MeshSetOptionsPrefix(), MeshSetOptionsPrefix(), MeshSetFromOptions()
549: @*/
550: int MeshGetOptionsPrefix(Mesh mesh, char **prefix)
551: {

556:   PetscObjectGetOptionsPrefix((PetscObject) mesh, prefix);
557:   return(0);
558: }

560: #undef __FUNCT__  
562: /*@
563:   MeshPrintHelp - Prints all options for the Mesh.

565:   Input Parameter:
566: . mesh - The mesh

568:   Options Database Keys:
569: $  -help, -h

571:   Level: intermediate

573: .keywords: Mesh, help
574: .seealso: MeshSetFromOptions()
575: @*/
576: int MeshPrintHelp(Mesh mesh)
577: {
578:   char p[64];
579:   int  ierr;


584:   PetscStrcpy(p, "-");
585:   if (mesh->prefix != PETSC_NULL) {
586:     PetscStrcat(p, mesh->prefix);
587:   }

589:   (*PetscHelpPrintf)(mesh->comm, "Mesh options ------------------------------------------------n");
590:   (*PetscHelpPrintf)(mesh->comm,"   %smesh_type <typename> : Sets the mesh typen", p);
591:   (*PetscHelpPrintf)(mesh->comm,"   %smesh_dim  <num>      : Sets the dimension of the meshn", p);
592:   return(0);
593: }

595: /*--------------------------------------------- Mesh-Specific Operations ---------------------------------------------*/
596: #undef  __FUNCT__
598: /*
599:   MeshCheckBoundary_Triangular_1D - Checks a boundary for validity.

601:   Collective on Mesh

603:   Input Parameter:
604: . mesh        - The mesh

606:   Input Parameters from bdCtx:
607: + numBD       - The number of closed boundaries in the geometry, or different markers
608: . numVertices - The umber of boundary points
609: . vertices    - The (x,y) coordinates of the boundary points
610: . markers     - The boundary markers for nodes, 0 indicates an interior point, each boundary must have a different marker

612:   Level: advanced

614: .keywords: mesh, boundary
615: .seealso: MeshSetBoundary(), MeshSetReformBoundary()
616: */
617: static int MeshCheckBoundary_Triangular_1D(Mesh mesh, MeshBoundary2D *bdCtx) {
618:   int rank;

623:   MPI_Comm_rank(mesh->comm, &rank);
624:   if (rank == 0) {
625:     if (bdCtx->numBd != bdCtx->numVertices) {
626:       SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "All boundaries must be points: %d != %d", bdCtx->numBd, bdCtx->numVertices);
627:     }
628:     if ((bdCtx->numVertices != 0) && (bdCtx->numVertices != 2)) {
629:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of boundary points %d", bdCtx->numVertices);
630:     }
631:     if (bdCtx->numVertices > 0) {
634:     }
635:   }
636:   return(0);
637: }

639: #undef  __FUNCT__
641: /*
642:   MeshCheckBoundary_Triangular_2D - Checks a boundary for validity.

644:   Collective on Mesh

646:   Input Parameter:
647: . mesh        - The mesh

649:   Input Parameters from bdCtx:
650: + numBD       - The number of closed boundaries in the geometry, or different markers
651: . numVertices - The umber of boundary points
652: . vertices    - The (x,y) coordinates of the boundary points
653: . markers     - The boundary markers for nodes, 0 indicates an interior point, each boundary must have a different marker
654: . numSegments - The number of boundary segments
655: . segments    - The endpoints of boundary segments or PETSC_NULL
656: . segMarkers  - The boundary markers for each segment
657: . numHoles    - The number of holes
658: - holes       - The (x,y) coordinates of holes or PETSC_NULL

660:   Level: advanced

662: .keywords: mesh, boundary
663: .seealso: MeshSetBoundary(), MeshSetReformBoundary()
664: */
665: static int MeshCheckBoundary_Triangular_2D(Mesh mesh, MeshBoundary2D *bdCtx) {
666:   int rank;

671:   MPI_Comm_rank(mesh->comm, &rank);
672:   if (rank == 0) {
673:     if (bdCtx->numVertices < 3) {
674:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Insufficient number of boundary points %d", bdCtx->numVertices);
675:     }
676:     if (bdCtx->numSegments < 3) {
677:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of boundary segments %d", bdCtx->numSegments);
678:     }
679:     if (bdCtx->numHoles    < 0) {
680:       SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of holes %d", bdCtx->numHoles);
681:     }
682:     if (bdCtx->numVertices > 0) {
685:     }
686:     if (bdCtx->numSegments > 0) {
689:     }
690:     if (bdCtx->numHoles    > 0) {
692:     }
693:   }
694:   return(0);
695: }

697: #undef  __FUNCT__
699: /*@
700:   MeshCheckBoundary - Checks the mesh boundary for validity.

702:   Collective on Mesh

704:   Input Parameters:
705: + mesh  - The mesh
706: - bdCtx - The MeshBoundary

708:   Level: intermediate

710: .keywords: mesh, partition
711: .seealso: MeshSetBoundary(), MeshSetReformBoundary()
712: @*/
713: int MeshCheckBoundary(Mesh mesh, MeshBoundary2D *bdCtx) {

718:   /* This needs to go in MeshBoundary later */
719:   if (mesh->dim == 1) {
720:     MeshCheckBoundary_Triangular_1D(mesh, bdCtx);
721:   } else if (mesh->dim == 2) {
722:     MeshCheckBoundary_Triangular_2D(mesh, bdCtx);
723:   } else {
724:     SETERRQ(PETSC_ERR_ARG_WRONG, "Mehs dimension has to be set in order to validate boundary");
725:   }
726:   return(0);
727: }

729: #undef  __FUNCT__
731: /*@
732:   MeshSetBoundary - Store a boundary to use for mesh generation.

734:   Not collective

736:   Input Parameters:
737: + mesh  - The mesh
738: - bdCtx - The MeshBoundary

740:   Level: intermediate

742: .keywords: mesh, boundary, refinement
743: .seealso: MeshReform()
744: @*/
745: int MeshSetBoundary(Mesh mesh, MeshBoundary2D *bdCtx) {

751:   MeshCheckBoundary(mesh, bdCtx);
752:   mesh->bdCtx = bdCtx;
753:   return(0);
754: }

756: #undef  __FUNCT__
758: /*@
759:   MeshSetReformBoundary - Store an alternate boundary to use for reforming.

761:   Not collective

763:   Input Parameters:
764: + mesh  - The mesh
765: - bdCtx - The MeshBoundary

767:   Level: intermediate

769: .keywords: mesh, boundary, refinement
770: .seealso: MeshReform()
771: @*/
772: int MeshSetReformBoundary(Mesh mesh, MeshBoundary2D *bdCtx) {

778:   MeshCheckBoundary(mesh, bdCtx);
779:   mesh->bdCtxNew = bdCtx;
780:   return(0);
781: }

783: #undef  __FUNCT__
785: /*@
786:   MeshPartition - Partitions the mesh among the processors

788:   Collective on Mesh

790:   Input Parameter:
791: . mesh - the mesh

793:   Level: beginner

795: .keywords: mesh, partition
796: .seealso: MeshGetBoundaryStart()
797: @*/
798: int MeshPartition(Mesh mesh)
799: {

804:   PetscLogEventBegin(MESH_Partition, mesh, 0, 0, 0);
805:   (*mesh->ops->partition)(mesh);
806:   PetscLogEventEnd(MESH_Partition, mesh, 0, 0, 0);
807:   MeshUpdateBoundingBox(mesh);
808:   return(0);
809: }
810: 
811: #undef  __FUNCT__
813: /*@
814:   MeshCoarsen - Coarsen a mesh based on area constraints.

816:   Collective on Mesh

818:   Input Parameters:
819: + mesh    - The initial mesh
820: - area    - A function which gives an area constraint when evaluated inside an element

822:   Output Parameter:
823: . newmesh - The coarse mesh

825:   Note:
826:   If PETSC_NULL is used for the 'area' argument, then the mesh consisting only of vertices
827:   is returned.

829:   Level: beginner

831: .keywords: mesh, coarsening
832: .seealso: MeshRefine(), MeshDestroy()
833: @*/
834: int MeshCoarsen(Mesh mesh, PointFunction area, Mesh *newmesh)
835: {

841:   if (mesh->ops->coarsen == PETSC_NULL) SETERRQ(PETSC_ERR_SUP, " ");
842:   MeshPreCopy_Private(mesh);
843:   (*mesh->ops->coarsen)(mesh, area, newmesh);
844:   MeshPostCopy_Private(mesh, *newmesh);
845:   return(0);
846: }
847: 
848: #undef  __FUNCT__
850: /*@
851:   MeshRefine - Refine a mesh based on area constraints.

853:   Input Parameters:
854: + mesh    - The initial mesh
855: - area    - A function which gives an area constraint when evaluated inside an element

857:   Output Parameter:
858: . newmesh - The refined mesh

860:   Level: beginner

862: .keywords: mesh, refinement
863: .seealso: MeshCoarsen(), MeshDestroy()
864: @*/
865: int MeshRefine(Mesh mesh, PointFunction area, Mesh *newmesh)
866: {

872:   if (mesh->ops->refine == PETSC_NULL) SETERRQ(PETSC_ERR_SUP, " ");
873:   MeshPreCopy_Private(mesh);
874:   (*mesh->ops->refine)(mesh, area, newmesh);
875:   MeshPostCopy_Private(mesh, *newmesh);
876:   return(0);
877: }

879: #undef  __FUNCT__
881: /*@
882:   MeshResetNodes - Using the vertex and edge structure, move auxilliary nodes back to
883:   their default positions.

885:   Input Parameters:
886: + mesh    - The mesh
887: - resetBd - The flag which indicates whether boundaries should also be reset

889:   Note:
890:   This function was developed to allow midnodes to be moved back onto the edges
891:   with which they were associated. Midnodes on edges between nodes on the same
892:   boundary are only reset if resetBd == PETSC_TRUE (to allow for curved boundaries).

894:   Level: advanced

896: .keywords: mesh, reset, node
897: .seealso: MeshReform(), MeshSetBounday()
898: @*/
899: int MeshResetNodes(Mesh mesh, PetscTruth resetBd)
900: {

905:   if (!mesh->ops->resetnodes) {
906:     SETERRQ(PETSC_ERR_SUP, "Not supported by this Mesh object");
907:   }
908:   (*mesh->ops->resetnodes)(mesh, resetBd);
909:   return(0);
910: }

912: #undef  __FUNCT__
914: /*@
915:   MeshSaveMesh - This function saves the mesh coordinates.

917:   Collective on Mesh

919:   Input Parameter:
920: . mesh - The mesh

922:   Level: advanced

924:   Note:
925:   This function is meant to be used in conjuction with MeshMoveMesh(),
926:   and MeshRestoreMesh() so that the mesh may be moved, checked for
927:   distortion, and if necessary moved back.

929: .keywords: mesh, movement
930: .seealso: MeshMoveMesh(), MeshRestoreMesh()
931: @*/
932: int MeshSaveMesh(Mesh mesh) {

937:   (*mesh->ops->savemesh)(mesh);
938:   return(0);
939: }

941: #undef  __FUNCT__
943: /*@
944:   MeshRestoreMesh - This function restores the mesh coordinates which were
945:   previously saved.

947:   Collective on Mesh

949:   Input Parameter:
950: . mesh - The mesh

952:   Level: advanced

954:   Note:
955:   This function is meant to be used in conjuction with MeshMoveMesh(),
956:   and MeshRestoreMesh() so that the mesh may be moved, checked for
957:   distortion, and if necessary moved back.

959: .keywords: mesh, movement
960: .seealso: MeshMoveMesh(), MeshSaveMesh()
961: @*/
962: int MeshRestoreMesh(Mesh mesh) {

967:   (*mesh->ops->restoremesh)(mesh);
968:   return(0);
969: }

971: #undef  __FUNCT__
973: /*@
974:   MeshIsDistorted - This function checks for more than the maximum
975:   level of distortion in the mesh. It also returns an error when
976:   encountering elements with negative area.

978:   Collective on Mesh

980:   Input Parameter:
981: . mesh - The mesh

983:   Output Parameter:
984: . flag - Signals a distorted mesh

986:   Level: intermediate

988: .keywords: mesh, distortion, movement
989: .seealso: MeshMoveMesh()
990: @*/
991: int MeshIsDistorted(Mesh mesh, PetscTruth *flag) {

997:   PetscLogEventBegin(MESH_IsDistorted, mesh, 0, 0, 0);
998:   /* Do not use CHKERRQ since we want the return value at the top level */
999:   (*mesh->ops->isdistorted)(mesh, flag);
1000:   PetscLogEventEnd(MESH_IsDistorted, mesh, 0, 0, 0);
1001:   PetscFunctionReturn(ierr);
1002: }