Actual source code: mesh.c

  1: #include "private/meshimpl.h"   /*I      "petscmesh.h"   I*/
  2: #include <petscmesh_viewers.hh>
  3: #include <petscmesh_formats.hh>

  5: /* Logging support */
  6: PetscCookie  MESH_COOKIE;
  7: PetscLogEvent  Mesh_View, Mesh_GetGlobalScatter, Mesh_restrictVector, Mesh_assembleVector,
  8:             Mesh_assembleVectorComplete, Mesh_assembleMatrix, Mesh_updateOperator;

 10: PetscTruth MeshRegisterAllCalled = PETSC_FALSE;
 11: PetscFList MeshList;

 13: EXTERN PetscErrorCode MeshView_Mesh(Mesh, PetscViewer);
 14: EXTERN PetscErrorCode MeshRefine_Mesh(Mesh, MPI_Comm, Mesh *);
 15: EXTERN PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh, int, Mesh **);
 16: EXTERN PetscErrorCode MeshGetInterpolation_Mesh(Mesh, Mesh, Mat *, Vec *);
 17: EXTERN PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh, Mesh, Mat *, Vec *);

 22: /*
 23:    Private routine to delete internal tag storage when a communicator is freed.

 25:    This is called by MPI, not by users.


 29:          we do not use PetscFree() since it is unsafe after PetscFinalize()
 30: */
 31: PetscMPIInt  Mesh_DelTag(MPI_Comm comm,PetscMPIInt keyval,void* attr_val,void* extra_state)
 32: {
 33:   free(attr_val);
 34:   return(MPI_SUCCESS);
 35: }

 40: PetscErrorCode MeshFinalize()
 41: {
 43:   PETSC_MESH_TYPE::MeshNumberingFactory::singleton(0, 0, true);
 44:   return(0);
 45: }

 49: PetscErrorCode MeshView_Sieve_Ascii(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
 50: {
 51:   PetscViewerFormat format;
 52:   PetscErrorCode    ierr;

 55:   PetscViewerGetFormat(viewer, &format);
 56:   if (format == PETSC_VIEWER_ASCII_VTK) {
 57:     VTKViewer::writeHeader(viewer);
 58:     VTKViewer::writeVertices(mesh, viewer);
 59:     VTKViewer::writeElements(mesh, viewer);
 60:     const ALE::Obj<PETSC_MESH_TYPE::int_section_type>& p     = mesh->getIntSection("Partition");
 61:     const ALE::Obj<PETSC_MESH_TYPE::label_sequence>&   cells = mesh->heightStratum(0);
 62:     const PETSC_MESH_TYPE::label_sequence::iterator    end   = cells->end();
 63:     const int                                          rank  = mesh->commRank();

 65: #ifdef PETSC_OPT_SIEVE
 66:     p->setChart(PETSC_MESH_TYPE::int_section_type::chart_type(*cells));
 67: #endif
 68:     p->setFiberDimension(cells, 1);
 69:     p->allocatePoint();
 70:     for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin(); c_iter != end; ++c_iter) {
 71:       p->updatePoint(*c_iter, &rank);
 72:     }
 73:     PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_VTK_CELL);
 74:     SectionView_Sieve_Ascii(mesh, p, "Partition", viewer);
 75:     PetscViewerPopFormat(viewer);
 76:   } else if (format == PETSC_VIEWER_ASCII_PYLITH) {
 77:     char *filename;
 78:     char  connectFilename[2048];
 79:     char  coordFilename[2048];

 81:     PetscViewerFileGetName(viewer, &filename);
 82:     PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
 83:     PetscStrcpy(connectFilename, filename);
 84:     PetscStrcat(connectFilename, ".connect");
 85:     PetscViewerFileSetName(viewer, connectFilename);
 86:     ALE::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
 87:     PetscStrcpy(coordFilename, filename);
 88:     PetscStrcat(coordFilename, ".coord");
 89:     PetscViewerFileSetName(viewer, coordFilename);
 90:     ALE::PyLith::Viewer::writeVertices(mesh, viewer);
 91:     PetscViewerFileSetMode(viewer, FILE_MODE_READ);
 92:     PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
 93:     if (PetscExceptionValue(ierr)) {
 94:       /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
 95:     } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
 96:       0;
 97:     }
 98: 
 99:   } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
100:     PetscViewer connectViewer, coordViewer;
101:     char       *filename;
102:     char        localFilename[2048];
103:     int         rank = mesh->commRank();

105:     PetscViewerFileGetName(viewer, &filename);

107:     sprintf(localFilename, "%s.%d.connect", filename, rank);
108:     PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
109:     PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
110:     PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
111:     PetscViewerFileSetName(connectViewer, localFilename);
112:     ALE::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
113:     PetscViewerDestroy(connectViewer);

115:     sprintf(localFilename, "%s.%d.coord", filename, rank);
116:     PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
117:     PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
118:     PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
119:     PetscViewerFileSetName(coordViewer, localFilename);
120:     ALE::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
121:     PetscViewerDestroy(coordViewer);
122:   } else if (format == PETSC_VIEWER_ASCII_PCICE) {
123:     char      *filename;
124:     char       coordFilename[2048];
125:     PetscTruth isConnect;
126:     size_t     len;

128:     PetscViewerFileGetName(viewer, &filename);
129:     PetscStrlen(filename, &len);
130:     PetscStrcmp(&(filename[len-5]), ".lcon", &isConnect);
131:     if (!isConnect) {
132:       SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid element connectivity filename: %s", filename);
133:     }
134:     ALE::PCICE::Viewer::writeElements(mesh, viewer);
135:     PetscStrncpy(coordFilename, filename, len-5);
136:     coordFilename[len-5] = '\0';
137:     PetscStrcat(coordFilename, ".nodes");
138:     PetscViewerFileSetName(viewer, coordFilename);
139:     ALE::PCICE::Viewer::writeVertices(mesh, viewer);
140:   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
141:     mesh->view("");
142:   } else {
143:     int dim = mesh->getDimension();

145:     PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
146:     for(int d = 0; d <= dim; d++) {
147:       // FIX: Need to globalize
148:       PetscViewerASCIIPrintf(viewer, "  %d %d-cells\n", mesh->depthStratum(d)->size(), d);
149:     }
150:   }
151:   PetscViewerFlush(viewer);
152:   return(0);
153: }

157: PetscErrorCode MeshView_Sieve(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
158: {
159:   PetscTruth     iascii, isbinary, isdraw;

163:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
164:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
165:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);

167:   if (iascii){
168:     MeshView_Sieve_Ascii(mesh, viewer);
169:   } else if (isbinary) {
170:     SETERRQ(PETSC_ERR_SUP, "Binary viewer not implemented for Mesh");
171:   } else if (isdraw){
172:     SETERRQ(PETSC_ERR_SUP, "Draw viewer not implemented for Mesh");
173:   } else {
174:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
175:   }
176:   return(0);
177: }

181: PetscErrorCode  MeshView_Mesh(Mesh mesh, PetscViewer viewer)
182: {

186:   MeshView_Sieve(mesh->m, viewer);
187:   return(0);
188: }

192: /*@C
193:    MeshView - Views a Mesh object. 

195:    Collective on Mesh

197:    Input Parameters:
198: +  mesh - the mesh
199: -  viewer - an optional visualization context

201:    Notes:
202:    The available visualization contexts include
203: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
204: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
205:          output where only the first processor opens
206:          the file.  All other processors send their 
207:          data to the first processor to print. 

209:    You can change the format the mesh is printed using the 
210:    option PetscViewerSetFormat().

212:    The user can open alternative visualization contexts with
213: +    PetscViewerASCIIOpen() - Outputs mesh to a specified file
214: .    PetscViewerBinaryOpen() - Outputs mesh in binary to a
215:          specified file; corresponding input uses MeshLoad()
216: .    PetscViewerDrawOpen() - Outputs mesh to an X window display

218:    The user can call PetscViewerSetFormat() to specify the output
219:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
220:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
221: +    PETSC_VIEWER_DEFAULT - default, prints mesh information
222: -    PETSC_VIEWER_ASCII_VTK - outputs a VTK file describing the mesh

224:    Level: beginner

226:    Concepts: mesh^printing
227:    Concepts: mesh^saving to disk

229: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
230:           MeshLoad(), PetscViewerCreate()
231: @*/
232: PetscErrorCode  MeshView(Mesh mesh, PetscViewer viewer)
233: {

239:   if (!viewer) {
240:     PetscViewerASCIIGetStdout(((PetscObject)mesh)->comm,&viewer);
241:   }

245:   PetscLogEventBegin(Mesh_View,0,0,0,0);
246:   (*mesh->ops->view)(mesh, viewer);
247:   PetscLogEventEnd(Mesh_View,0,0,0,0);
248:   return(0);
249: }

253: /*@C
254:     MeshLoad - Create a mesh topology from the saved data in a viewer.

256:     Collective on Viewer

258:     Input Parameter:
259: .   viewer - The viewer containing the data

261:     Output Parameters:
262: .   mesh - the mesh object

264:     Level: advanced

266: .seealso MeshView()

268: @*/
269: PetscErrorCode  MeshLoad(PetscViewer viewer, Mesh *mesh)
270: {
271:   SETERRQ(PETSC_ERR_SUP, "");
272: }

276: /*@C
277:     MeshGetMesh - Gets the internal mesh object

279:     Not collective

281:     Input Parameter:
282: .    mesh - the mesh object

284:     Output Parameter:
285: .    m - the internal mesh object
286:  
287:     Level: advanced

289: .seealso MeshCreate(), MeshSetMesh()

291: @*/
292: PetscErrorCode  MeshGetMesh(Mesh mesh, ALE::Obj<PETSC_MESH_TYPE>& m)
293: {
296:   m = mesh->m;
297:   return(0);
298: }

302: /*@C
303:     MeshSetMesh - Sets the internal mesh object

305:     Not collective

307:     Input Parameters:
308: +    mesh - the mesh object
309: -    m - the internal mesh object
310:  
311:     Level: advanced

313: .seealso MeshCreate(), MeshGetMesh()

315: @*/
316: PetscErrorCode  MeshSetMesh(Mesh mesh, const ALE::Obj<PETSC_MESH_TYPE>& m)
317: {
320:   mesh->m = m;
321:   if (mesh->globalScatter) {

324:     VecScatterDestroy(mesh->globalScatter);
325:     mesh->globalScatter = PETSC_NULL;
326:   }
327:   return(0);
328: }

332: /*@C
333:   MeshCreateMatrix - Creates a matrix with the correct parallel layout required for 
334:     computing the Jacobian on a function defined using the information in the Section.

336:   Collective on Mesh

338:   Input Parameters:
339: + mesh    - the mesh object
340: . section - the section which determines data layout
341: - mtype   - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
342:             or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).

344:   Output Parameter:
345: . J  - matrix with the correct nonzero preallocation
346:        (obviously without the correct Jacobian values)

348:   Level: advanced

350:   Notes: This properly preallocates the number of nonzeros in the sparse matrix so you 
351:        do not need to do it yourself.

353: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
354: @*/
355: PetscErrorCode  MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
356: {
357:   ALE::Obj<PETSC_MESH_TYPE> m;
358:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;

362:   MeshGetMesh(mesh, m);
363:   SectionRealGetSection(section, s);
364:   MeshCreateMatrix(m, s, mtype, J);
365:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
366:   return(0);
367: }

371: PetscErrorCode  MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
372: {
373:   SectionReal    section;

377:   MeshGetVertexSectionReal(mesh, 1, &section);
378:   MeshCreateMatrix(mesh, section, mtype, J);
379:   SectionRealDestroy(section);
380:   return(0);
381: }

385: /*@C
386:     MeshGetMatrix - Creates a matrix with the correct parallel layout required for 
387:       computing the Jacobian on a function defined using the information in Mesh.

389:     Collective on Mesh

391:     Input Parameters:
392: +   mesh - the mesh object
393: -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
394:             or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).

396:     Output Parameter:
397: .   J  - matrix with the correct nonzero preallocation
398:         (obviously without the correct Jacobian values)

400:     Level: advanced

402:     Notes: This properly preallocates the number of nonzeros in the sparse matrix so you 
403:        do not need to do it yourself.

405: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()

407: @*/
408: PetscErrorCode  MeshGetMatrix(Mesh mesh, const MatType mtype, Mat *J)
409: {
410:   ALE::Obj<PETSC_MESH_TYPE> m;
411:   PetscTruth          flag;
412:   PetscErrorCode      ierr;

415:   MeshHasSectionReal(mesh, "default", &flag);
416:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
417:   MeshGetMesh(mesh, m);
418:   MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
419:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
420:   return(0);
421: }

425: /*@C
426:     MeshCreate - Creates a DM object, used to manage data for an unstructured problem
427:     described by a Sieve.

429:     Collective on MPI_Comm

431:     Input Parameter:
432: .   comm - the processors that will share the global vector

434:     Output Parameters:
435: .   mesh - the mesh object

437:     Level: advanced

439: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshGetGlobalIndices()

441: @*/
442: PetscErrorCode  MeshCreate(MPI_Comm comm,Mesh *mesh)
443: {
445:   Mesh         p;

449:   *mesh = PETSC_NULL;
450: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
451:   DMInitializePackage(PETSC_NULL);
452: #endif

454:   PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
455:   p->ops->view               = MeshView_Mesh;
456:   p->ops->destroy            = PETSC_NULL;
457:   p->ops->createglobalvector = MeshCreateGlobalVector;
458:   p->ops->createlocalvector  = MeshCreateLocalVector;
459:   p->ops->getcoloring        = PETSC_NULL;
460:   p->ops->getmatrix          = MeshGetMatrix;
461:   p->ops->getinterpolation   = MeshGetInterpolation_Mesh_New;
462:   p->ops->getinjection       = PETSC_NULL;
463:   p->ops->refine             = MeshRefine_Mesh;
464:   p->ops->coarsen            = PETSC_NULL;
465:   p->ops->refinehierarchy    = PETSC_NULL;
466:   p->ops->coarsenhierarchy   = MeshCoarsenHierarchy_Mesh;

468:   PetscObjectChangeTypeName((PetscObject) p, "sieve");

470:   new(&p->m) ALE::Obj<PETSC_MESH_TYPE>(PETSC_NULL);
471:   p->globalScatter = PETSC_NULL;
472:   p->lf            = PETSC_NULL;
473:   p->lj            = PETSC_NULL;
474:   p->data          = PETSC_NULL;
475:   *mesh = p;
476:   return(0);
477: }

481: /*@
482:     MeshDestroy - Destroys a mesh.

484:     Collective on Mesh

486:     Input Parameter:
487: .   mesh - the mesh object

489:     Level: advanced

491: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
492: @*/
493: PetscErrorCode  MeshDestroy(Mesh mesh)
494: {
495:   PetscErrorCode     ierr;

498:   if (--((PetscObject)mesh)->refct > 0) return(0);
499:   if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
500:   mesh->m = PETSC_NULL;
501:   PetscHeaderDestroy(mesh);
502:   return(0);
503: }

507: /*@C
508:   MeshSetType - Sets the Mesh type

510:   Collective on Mesh

512:   Input Parameters:
513: + mesh - the Mesh context
514: - type - the type

516:   Options Database Key:
517: . -mesh_type  <method> - Sets the type; use -help for a list 
518:     of available types (for instance, cartesian or sieve)

520:   Notes:
521:   See "petsc/include/petscmesh.h" for available types (for instance,
522:   MESHCARTESIAN or MESHSIEVE).

524:   Level: intermediate

526: .keywords: Mesh, set, typr
527: .seealso: MeshGetType(), MeshType
528: @*/
529: PetscErrorCode  MeshSetType(Mesh mesh, const MeshType type)
530: {
531:   PetscErrorCode ierr,(*r)(Mesh);
532:   PetscTruth     match;


538:   PetscTypeCompare((PetscObject)mesh,type,&match);
539:   if (match) return(0);

541:    PetscFListFind(MeshList,((PetscObject)mesh)->comm,type,(void (**)(void)) &r);
542:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
543:   /* Destroy the previous private Mesh context */
544:   if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
545:   /* Reinitialize function pointers in MeshOps structure */
546:   PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
547:   /* Call the MeshCreate_XXX routine for this particular mesh */
548:   (*r)(mesh);
549:   PetscObjectChangeTypeName((PetscObject) mesh, type);
550:   return(0);
551: }

555: /*@C
556:   MeshGetType - Gets the Mesh type as a string from the Mesh object.

558:   Not Collective

560:   Input Parameter:
561: . mesh - Mesh context 

563:   Output Parameter:
564: . name - name of Mesh type 

566:   Level: intermediate

568: .keywords: Mesh, get, type
569: .seealso: MeshSetType()
570: @*/
571: PetscErrorCode  MeshGetType(Mesh mesh,const MeshType *type)
572: {
576:   *type = ((PetscObject)mesh)->type_name;
577:   return(0);
578: }

582: /*@C
583:   MeshRegister - See MeshRegisterDynamic()

585:   Level: advanced
586: @*/
587: PetscErrorCode  MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
588: {
590:   char           fullname[PETSC_MAX_PATH_LEN];

593:   PetscFListConcat(path,name,fullname);
594:   PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
595:   return(0);
596: }

599: EXTERN PetscErrorCode  MeshCreate_Cartesian(Mesh);

604: /*@C
605:   MeshRegisterAll - Registers all of the Mesh types in the Mesh package.

607:   Not Collective

609:   Level: advanced

611: .keywords: Mesh, register, all
612: .seealso:  MeshRegisterDestroy()
613: @*/
614: PetscErrorCode  MeshRegisterAll(const char path[])
615: {

619:   MeshRegisterAllCalled = PETSC_TRUE;

621:   MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
622:   return(0);
623: }

627: /*@C
628:   MeshRegisterDestroy - Frees the list of Mesh types that were
629:   registered by MeshRegister().

631:   Not Collective

633:   Level: advanced

635: .keywords: Mesh, register, destroy
636: .seealso: MeshRegister(), MeshRegisterAll()
637: @*/
638: PetscErrorCode  MeshRegisterDestroy(void)
639: {

643:   PetscFListDestroy(&MeshList);
644:   MeshRegisterAllCalled = PETSC_FALSE;
645:   return(0);
646: }

650: /*@C
651:     MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into 
652:         by the mesh.

654:     Collective on Mesh

656:     Input Parameter:
657: .    mesh - the mesh object

659:     Output Parameters:
660: .   gvec - the global vector

662:     Level: advanced

664:     Notes: Once this has been created you cannot add additional arrays or vectors to be packed.

666: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()

668: @*/
669: PetscErrorCode  MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
670: {
671:   ALE::Obj<PETSC_MESH_TYPE> m;
672:   PetscTruth     flag;

676:   MeshHasSectionReal(mesh, "default", &flag);
677:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
678:   MeshGetMesh(mesh, m);
679:   const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));

681:   VecCreate(m->comm(), gvec);
682:   VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
683:   VecSetFromOptions(*gvec);
684:   return(0);
685: }

689: /*@
690:   MeshCreateVector - Creates a global vector matching the input section

692:   Collective on Mesh

694:   Input Parameters:
695: + mesh - the Mesh
696: - section - the Section

698:   Output Parameter:
699: . vec - the global vector

701:   Level: advanced

703:   Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
704: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
705: @*/
706: PetscErrorCode  MeshCreateVector(Mesh mesh, SectionReal section, Vec *vec)
707: {
708:   ALE::Obj<PETSC_MESH_TYPE> m;
709:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;

713:   MeshGetMesh(mesh, m);
714:   SectionRealGetSection(section, s);
715:   const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, s->getName(), s);

717:   VecCreate(m->comm(), vec);
718:   VecSetSizes(*vec, order->getLocalSize(), order->getGlobalSize());
719:   VecSetFromOptions(*vec);
720:   return(0);
721: }

725: /*@C
726:     MeshCreateLocalVector - Creates a vector of the correct size for local computation.

728:     Collective on Mesh

730:     Input Parameter:
731: .    mesh - the mesh object

733:     Output Parameters:
734: .   lvec - the local vector

736:     Level: advanced

738:     Notes: Once this has been created you cannot add additional arrays or vectors to be packed.

740: .seealso MeshDestroy(), MeshCreate(), MeshCreateGlobalVector()

742: @*/
743: PetscErrorCode  MeshCreateLocalVector(Mesh mesh, Vec *lvec)
744: {
745:   ALE::Obj<PETSC_MESH_TYPE> m;
746:   PetscTruth     flag;

750:   MeshHasSectionReal(mesh, "default", &flag);
751:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
752:   MeshGetMesh(mesh, m);
753:   const int size = m->getRealSection("default")->getStorageSize();

755:   VecCreate(PETSC_COMM_SELF, lvec);
756:   VecSetSizes(*lvec, size, size);
757:   VecSetFromOptions(*lvec);
758:   return(0);
759: }

763: /*@C
764:     MeshGetGlobalIndices - Gets the global indices for all the local entries

766:     Collective on Mesh

768:     Input Parameter:
769: .    mesh - the mesh object

771:     Output Parameters:
772: .    idx - the individual indices for each packed vector/array
773:  
774:     Level: advanced

776:     Notes:
777:        The idx parameters should be freed by the calling routine with PetscFree()

779: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()

781: @*/
782: PetscErrorCode  MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
783: {
784:   SETERRQ(PETSC_ERR_SUP, "");
785: }

789: /*@
790:   MeshCreateGlobalScatter - Create a VecScatter which maps from local, overlapping
791:   storage in the Section to a global Vec

793:   Collective on Mesh

795:   Input Parameters:
796: + mesh - the mesh object
797: - section - The Scetion which determines data layout

799:   Output Parameter:
800: . scatter - the VecScatter
801:  
802:   Level: advanced

804: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
805: @*/
806: PetscErrorCode  MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
807: {
808:   ALE::Obj<PETSC_MESH_TYPE> m;
809:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;

813:   MeshGetMesh(mesh, m);
814:   SectionRealGetSection(section, s);
815:   MeshCreateGlobalScatter(m, s, scatter);
816:   return(0);
817: }

821: PetscErrorCode  MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
822: {

828:   if (!mesh->globalScatter) {
829:     SectionReal section;

831:     MeshGetSectionReal(mesh, "default", &section);
832:     MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
833:     SectionRealDestroy(section);
834:   }
835:   *scatter = mesh->globalScatter;
836:   return(0);
837: }

841: PetscErrorCode  MeshGetLocalFunction(Mesh mesh, PetscErrorCode (**lf)(Mesh, SectionReal, SectionReal, void *))
842: {
845:   if (lf) *lf = mesh->lf;
846:   return(0);
847: }

851: PetscErrorCode  MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
852: {
855:   mesh->lf = lf;
856:   return(0);
857: }

861: PetscErrorCode  MeshGetLocalJacobian(Mesh mesh, PetscErrorCode (**lj)(Mesh, SectionReal, Mat, void *))
862: {
865:   if (lj) *lj = mesh->lj;
866:   return(0);
867: }

871: PetscErrorCode  MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
872: {
875:   mesh->lj = lj;
876:   return(0);
877: }

881: PetscErrorCode  MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
882: {

889:   if (mesh->lf) {
890:     (*mesh->lf)(mesh, X, F, ctx);
891:   }
892:   return(0);
893: }

897: PetscErrorCode  MeshFormJacobian(Mesh mesh, SectionReal X, Mat J, void *ctx)
898: {

905:   if (mesh->lj) {
906:     (*mesh->lj)(mesh, X, J, ctx);
907:   }
908:   return(0);
909: }

913: // Here we assume:
914: //  - Assumes 3D and tetrahedron
915: //  - The section takes values on vertices and is P1
916: //  - Points have the same dimension as the mesh
917: //  - All values have the same dimension
918: PetscErrorCode  MeshInterpolatePoints(Mesh mesh, SectionReal section, int numPoints, double *points, double **values)
919: {
920:   Obj<PETSC_MESH_TYPE> m;
921:   Obj<PETSC_MESH_TYPE::real_section_type> s;
922:   double        *v0, *J, *invJ, detJ;

926:   MeshGetMesh(mesh, m);
927:   SectionRealGetSection(section, s);
928:   const Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
929:   int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
930:   int dim      = s->getFiberDimension(*m->depthStratum(0)->begin());

932:   PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
933:   PetscMalloc(numPoints*dim * sizeof(double), &values);
934:   for(int p = 0; p < numPoints; p++) {
935:     double *point = &points[p*embedDim];
936: 
937:     PETSC_MESH_TYPE::point_type e = m->locatePoint(point);
938:     const PETSC_MESH_TYPE::real_section_type::value_type *coeff = s->restrictPoint(e);

940:     m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
941:     double xi   = (invJ[0*embedDim+0]*(point[0] - v0[0]) + invJ[0*embedDim+1]*(point[1] - v0[1]) + invJ[0*embedDim+2]*(point[2] - v0[2]))*0.5;
942:     double eta  = (invJ[1*embedDim+0]*(point[0] - v0[0]) + invJ[1*embedDim+1]*(point[1] - v0[1]) + invJ[1*embedDim+2]*(point[2] - v0[2]))*0.5;
943:     double zeta = (invJ[2*embedDim+0]*(point[0] - v0[0]) + invJ[2*embedDim+1]*(point[1] - v0[1]) + invJ[2*embedDim+2]*(point[2] - v0[2]))*0.5;

945:     for(int d = 0; d < dim; d++) {
946:       (*values)[p*dim+d] = coeff[0*dim+d]*(1 - xi - eta - zeta) + coeff[1*dim+d]*xi + coeff[2*dim+d]*eta + coeff[3*dim+d]*zeta;
947:     }
948:   }
949:   PetscFree3(v0, J, invJ);
950:   return(0);
951: }

955: /*@C
956:   MeshGetMaximumDegree - Return the maximum degree of any mesh vertex

958:   Collective on mesh

960:   Input Parameter:
961: . mesh - The Mesh

963:   Output Parameter:
964: . maxDegree - The maximum number of edges at any vertex

966:    Level: beginner

968: .seealso: MeshCreate()
969: @*/
970: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
971: {
972:   Obj<PETSC_MESH_TYPE> m;

976:   MeshGetMesh(mesh, m);
977:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& vertices = m->depthStratum(0);
978:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type>&     sieve    = m->getSieve();
979:   PetscInt                                          maxDeg   = -1;

981:   for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
982:     maxDeg = PetscMax(maxDeg, (PetscInt) sieve->getSupportSize(*v_iter));
983:   }
984:   *maxDegree = maxDeg;
985:   return(0);
986: }

988: EXTERN PetscErrorCode assembleFullField(VecScatter, Vec, Vec, InsertMode);

992: /*@C
993:   restrictVector - Insert values from a global vector into a local ghosted vector

995:   Collective on g

997:   Input Parameters:
998: + g - The global vector
999: . l - The local vector
1000: - mode - either ADD_VALUES or INSERT_VALUES, where
1001:    ADD_VALUES adds values to any existing entries, and
1002:    INSERT_VALUES replaces existing entries with new values

1004:    Level: beginner

1006: .seealso: MatSetOption()
1007: @*/
1008: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1009: {
1010:   VecScatter     injection;

1014:   PetscLogEventBegin(Mesh_restrictVector,0,0,0,0);
1015:   PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1016:   if (injection) {
1017:     VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
1018:     VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
1019:   } else {
1020:     if (mode == INSERT_VALUES) {
1021:       VecCopy(g, l);
1022:     } else {
1023:       VecAXPY(l, 1.0, g);
1024:     }
1025:   }
1026:   PetscLogEventEnd(Mesh_restrictVector,0,0,0,0);
1027:   return(0);
1028: }

1032: /*@C
1033:   assembleVectorComplete - Insert values from a local ghosted vector into a global vector

1035:   Collective on g

1037:   Input Parameters:
1038: + g - The global vector
1039: . l - The local vector
1040: - mode - either ADD_VALUES or INSERT_VALUES, where
1041:    ADD_VALUES adds values to any existing entries, and
1042:    INSERT_VALUES replaces existing entries with new values

1044:    Level: beginner

1046: .seealso: MatSetOption()
1047: @*/
1048: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1049: {
1050:   VecScatter     injection;

1054:   PetscLogEventBegin(Mesh_assembleVectorComplete,0,0,0,0);
1055:   PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1056:   if (injection) {
1057:     VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1058:     VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1059:   } else {
1060:     if (mode == INSERT_VALUES) {
1061:       VecCopy(l, g);
1062:     } else {
1063:       VecAXPY(g, 1.0, l);
1064:     }
1065:   }
1066:   PetscLogEventEnd(Mesh_assembleVectorComplete,0,0,0,0);
1067:   return(0);
1068: }

1072: /*@C
1073:   assembleVector - Insert values into a vector

1075:   Collective on A

1077:   Input Parameters:
1078: + b - the vector
1079: . e - The element number
1080: . v - The values
1081: - mode - either ADD_VALUES or INSERT_VALUES, where
1082:    ADD_VALUES adds values to any existing entries, and
1083:    INSERT_VALUES replaces existing entries with new values

1085:    Level: beginner

1087: .seealso: VecSetOption()
1088: @*/
1089: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1090: {
1091:   Mesh                       mesh;
1092:   ALE::Obj<PETSC_MESH_TYPE> m;
1093:   PetscInt                   firstElement;
1094:   PetscErrorCode             ierr;

1097:   PetscLogEventBegin(Mesh_assembleVector,0,0,0,0);
1098:   PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1099:   MeshGetMesh(mesh, m);
1100:   //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1101:   firstElement = 0;
1102:   // Must relate b to field
1103:   if (mode == INSERT_VALUES) {
1104:     m->update(m->getRealSection(std::string("x")), PETSC_MESH_TYPE::point_type(e + firstElement), v);
1105:   } else {
1106:     m->updateAdd(m->getRealSection(std::string("x")), PETSC_MESH_TYPE::point_type(e + firstElement), v);
1107:   }
1108:   PetscLogEventEnd(Mesh_assembleVector,0,0,0,0);
1109:   return(0);
1110: }

1114: PetscErrorCode updateOperator(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& section, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, const PETSC_MESH_TYPE::point_type& e, PetscScalar array[], InsertMode mode)
1115: {
1117: #ifdef PETSC_OPT_SIEVE
1118:   typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
1119:   visitor_type iV(*section, *globalOrder, (int) pow((double) m->getSieve()->getMaxConeSize(), m->depth())*m->getMaxDof(), m->depth() > 1);

1121:   PetscErrorCode updateOperator(A, *m->getSieve(), iV, e, array, ADD_VALUES);
1122: #else
1123:   const PETSC_MESH_TYPE::indices_type indicesBlock = m->getIndices(section, e, globalOrder);
1124:   const PetscInt *indices    = indicesBlock.first;
1125:   const int&      numIndices = indicesBlock.second;
1126:   PetscErrorCode  ierr;

1128:   PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1129:   if (section->debug()) {
1130:     printf("[%d]mat for element %d\n", section->commRank(), e);
1131:     for(int i = 0; i < numIndices; i++) {
1132:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1133:     }
1134:     for(int i = 0; i < numIndices; i++) {
1135:       printf("[%d]", section->commRank());
1136:       for(int j = 0; j < numIndices; j++) {
1137:         printf(" %g", array[i*numIndices+j]);
1138:       }
1139:       printf("\n");
1140:     }
1141:   }
1142:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1143:   if (ierr) {
1144:     printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
1145:     for(int i = 0; i < numIndices; i++) {
1146:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1147:     }
1148: 
1149:   }
1150:   PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1151: #endif
1152:   return(0);
1153: }

1157: PetscErrorCode updateOperator(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& section, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, int tag, int p, PetscScalar array[], InsertMode mode)
1158: {
1159: #ifdef PETSC_OPT_SIEVE
1160:   SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1161: #else
1162:   const int *offsets, *indices;

1166:   section->getCustomRestrictAtlas(tag, &offsets, &indices);
1167:   const int& numIndices = offsets[p+1] - offsets[p];

1169:   PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1170:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1171:   if (ierr) {
1172:     printf("[%d]ERROR in updateOperator: tag %d point num %d\n", section->commRank(), tag, p);
1173:     for(int i = 0; i < numIndices; i++) {
1174:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1175:     }
1176: 
1177:   }
1178:   PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1179: #endif
1180:   return(0);
1181: }

1185: PetscErrorCode updateOperatorGeneral(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& rowM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& rowSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& rowGlobalOrder, const PETSC_MESH_TYPE::point_type& rowE, const ALE::Obj<PETSC_MESH_TYPE>& colM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& colSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& colGlobalOrder, const PETSC_MESH_TYPE::point_type& colE, PetscScalar array[], InsertMode mode)
1186: {
1187: #ifdef PETSC_OPT_SIEVE
1188:   SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1189: #else

1193:   const PETSC_MESH_TYPE::indices_type rowIndicesBlock = rowM->getIndices(rowSection, rowE, rowGlobalOrder);

1195:   const PetscInt *tmpIndices    = rowIndicesBlock.first;
1196:   const int       numRowIndices = rowIndicesBlock.second;
1197:   PetscInt       *rowIndices    = new PetscInt[numRowIndices];
1198:   PetscMemcpy(rowIndices, tmpIndices, numRowIndices*sizeof(PetscInt));

1200:   const PETSC_MESH_TYPE::indices_type colIndicesBlock = colM->getIndices(colSection, colE, colGlobalOrder);

1202:   const PetscInt *colIndices    = colIndicesBlock.first;
1203:   const int      numColIndices = colIndicesBlock.second;

1205:   PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1206:   if (rowSection->debug()) {
1207:     printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1208:     for(int i = 0; i < numRowIndices; i++) {
1209:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1210:     }
1211:   }
1212:   if (colSection->debug()) {
1213:     for(int i = 0; i < numColIndices; i++) {
1214:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1215:     }
1216:     for(int i = 0; i < numRowIndices; i++) {
1217:       printf("[%d]", rowSection->commRank());
1218:       for(int j = 0; j < numColIndices; j++) {
1219:         printf(" %g", array[i*numColIndices+j]);
1220:       }
1221:       printf("\n");
1222:     }
1223:   }
1224:   MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1225:   if (ierr) {
1226:     printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1227:     for(int i = 0; i < numRowIndices; i++) {
1228:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1229:     }
1230:     for(int i = 0; i < numColIndices; i++) {
1231:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1232:     }
1233: 
1234:   }
1235:   PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1236:   delete [] rowIndices;
1237: #endif
1238:   return(0);
1239: }

1243: /*@C
1244:   assembleMatrix - Insert values into a matrix

1246:   Collective on A

1248:   Input Parameters:
1249: + A - the matrix
1250: . e - The element number
1251: . v - The values
1252: - mode - either ADD_VALUES or INSERT_VALUES, where
1253:    ADD_VALUES adds values to any existing entries, and
1254:    INSERT_VALUES replaces existing entries with new values

1256:    Level: beginner

1258: .seealso: MatSetOption()
1259: @*/
1260: PetscErrorCode assembleMatrix(Mat A, PetscInt e, PetscScalar v[], InsertMode mode)
1261: {
1262: #ifdef PETSC_OPT_SIEVE
1263:   SETERRQ(PETSC_ERR_SUP, "I am being lazy, bug me.");
1264: #else
1265:   Mesh           mesh;

1269:   PetscLogEventBegin(Mesh_assembleMatrix,0,0,0,0);
1270:   PetscObjectQuery((PetscObject) A, "mesh", (PetscObject *) &mesh);
1271:   try {
1272:     Obj<PETSC_MESH_TYPE> m;

1274:     MeshGetMesh(mesh, m);
1275:     const ALE::Obj<PETSC_MESH_TYPE::numbering_type>&    cNumbering  = m->getFactory()->getLocalNumbering(m, m->depth());
1276:     const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s           = m->getRealSection("default");
1277:     const ALE::Obj<PETSC_MESH_TYPE::order_type>&        globalOrder = m->getFactory()->getGlobalOrder(m, "default", s);

1279:     if (m->debug()) {
1280:       std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1281:     }
1282:     updateOperator(A, m, s, globalOrder, cNumbering->getPoint(e), v, mode);
1283:   } catch (ALE::Exception e) {
1284:     std::cout << e.msg() << std::endl;
1285:   }
1286:   PetscLogEventEnd(Mesh_assembleMatrix,0,0,0,0);
1287: #endif
1288:   return(0);
1289: }

1293: PetscErrorCode preallocateMatrix(const ALE::Obj<PETSC_MESH_TYPE>& mesh, const int bs, const ALE::Obj<PETSC_MESH_TYPE::real_section_type::atlas_type>& atlas, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, Mat A)
1294: {
1295: #ifdef PETSC_OPT_SIEVE
1296:   SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1297: #else
1298:   PetscInt       localSize = globalOrder->getLocalSize();
1299:   PetscInt      *dnz, *onz;

1303:   PetscMalloc2(localSize, PetscInt, &dnz, localSize, PetscInt, &onz);
1304:   preallocateOperator(mesh, bs, atlas, globalOrder, dnz, onz, A);
1305:   PetscFree2(dnz, onz);
1306:   return(0);
1307: #endif
1308: }

1310: /******************************** C Wrappers **********************************/

1314: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1315: {
1316:   return VTKViewer::writeHeader(viewer);
1317: }

1321: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1322: {
1323:   ALE::Obj<PETSC_MESH_TYPE> m;

1326:   MeshGetMesh(mesh, m);
1327:   return VTKViewer::writeVertices(m, viewer);
1328: }

1332: PetscErrorCode WriteVTKElements(Mesh mesh, PetscViewer viewer)
1333: {
1334:   ALE::Obj<PETSC_MESH_TYPE> m;

1337:   MeshGetMesh(mesh, m);
1338:   return VTKViewer::writeElements(m, viewer);
1339: }

1343: PetscErrorCode WritePCICEVertices(Mesh mesh, PetscViewer viewer)
1344: {
1345:   ALE::Obj<PETSC_MESH_TYPE> m;

1348:   MeshGetMesh(mesh, m);
1349:   return ALE::PCICE::Viewer::writeVertices(m, viewer);
1350: }

1354: PetscErrorCode WritePCICEElements(Mesh mesh, PetscViewer viewer)
1355: {
1356:   ALE::Obj<PETSC_MESH_TYPE> m;

1359:   MeshGetMesh(mesh, m);
1360:   return ALE::PCICE::Viewer::writeElements(m, viewer);
1361: }

1365: PetscErrorCode WritePCICERestart(Mesh mesh, PetscViewer viewer)
1366: {
1367:   ALE::Obj<PETSC_MESH_TYPE> m;

1370:   MeshGetMesh(mesh, m);
1371:   return ALE::PCICE::Viewer::writeRestart(m, viewer);
1372: }

1376: /*@C
1377:   MeshCreatePFLOTRAN - Create a Mesh from PFLOTRAN HDF5 files.

1379:   Not Collective

1381:   Input Parameters:
1382: + dim - The topological mesh dimension
1383: . hdf5Filename - The HDF5 file containing the vertices for each element and vertex coordinates
1384: . interpolate - The flag for construction of intermediate elements

1386:   Output Parameter:
1387: . mesh - The Mesh object

1389:   Level: beginner

1391: .keywords: mesh, PFLOTRAN
1392: .seealso: MeshCreate()
1393: @*/
1394: PetscErrorCode MeshCreatePFLOTRAN(MPI_Comm comm, const int dim, const char hdf5Filename[], PetscTruth interpolate, Mesh *mesh)
1395: {
1396:   ALE::Obj<PETSC_MESH_TYPE> m;
1397:   PetscInt            debug = 0;
1398:   PetscTruth          flag;
1399:   PetscErrorCode      ierr;

1402:   MeshCreate(comm, mesh);
1403:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1404:   try {
1405:     m  = ALE::PFLOTRAN::Builder::readMesh(comm, dim, std::string(hdf5Filename), true, interpolate, debug);
1406:     if (debug) {m->view("Mesh");}
1407:   } catch(ALE::Exception e) {
1408:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1409:   }
1410: #if 0
1411:   if (bcFilename) {
1412:     ALE::PFLOTRAN::Builder::readBoundary(m, std::string(bcFilename));
1413:   }
1414: #endif
1415:   MeshSetMesh(*mesh, m);
1416:   return(0);
1417: }

1421: /*@C
1422:   MeshCreatePCICE - Create a Mesh from PCICE files.

1424:   Not Collective

1426:   Input Parameters:
1427: + dim - The topological mesh dimension
1428: . coordFilename - The file containing vertex coordinates
1429: . adjFilename - The file containing the vertices for each element
1430: . interpolate - The flag for construction of intermediate elements
1431: . bcFilename - The file containing the boundary topology and conditions
1432: . numBdFaces - The number of boundary faces (or edges)
1433: - numBdVertices - The number of boundary vertices

1435:   Output Parameter:
1436: . mesh - The Mesh object

1438:   Level: beginner

1440: .keywords: mesh, PCICE
1441: .seealso: MeshCreate()
1442: @*/
1443: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], Mesh *mesh)
1444: {
1445:   ALE::Obj<PETSC_MESH_TYPE> m;
1446:   PetscInt            debug = 0;
1447:   PetscTruth          flag;
1448:   PetscErrorCode      ierr;

1451:   MeshCreate(comm, mesh);
1452:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1453:   try {
1454:     m  = ALE::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1455:     if (debug) {m->view("Mesh");}
1456:   } catch(ALE::Exception e) {
1457:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1458:   }
1459:   if (bcFilename) {
1460:     ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1461:   }
1462:   MeshSetMesh(*mesh, m);
1463:   return(0);
1464: }

1468: /*@C
1469:   MeshCreatePyLith - Create a Mesh from PyLith files.

1471:   Not Collective

1473:   Input Parameters:
1474: + dim - The topological mesh dimension
1475: . baseFilename - The basename for mesh files
1476: . zeroBase - Use 0 to start numbering
1477: - interpolate - The flag for mesh interpolation

1479:   Output Parameter:
1480: . mesh - The Mesh object

1482:   Level: beginner

1484: .keywords: mesh, PCICE
1485: .seealso: MeshCreate()
1486: @*/
1487: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1488: {
1489:   ALE::Obj<PETSC_MESH_TYPE> m;
1490:   PetscInt            debug = 0;
1491:   PetscTruth          flag;
1492:   PetscErrorCode      ierr;

1495:   MeshCreate(comm, mesh);
1496:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1497:   try {
1498:     m  = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1499:   } catch(ALE::Exception e) {
1500:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1501:   }
1502:   MeshSetMesh(*mesh, m);
1503:   return(0);
1504: }

1508: /*@C
1509:   MeshGetCoordinates - Creates an array holding the coordinates.

1511:   Not Collective

1513:   Input Parameter:
1514: + mesh - The Mesh object
1515: - columnMajor - Flag for column major order

1517:   Output Parameter:
1518: + numVertices - The number of vertices
1519: . dim - The embedding dimension
1520: - coords - The array holding local coordinates

1522:   Level: intermediate

1524: .keywords: mesh, coordinates
1525: .seealso: MeshCreate()
1526: @*/
1527: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1528: {
1529:   ALE::Obj<PETSC_MESH_TYPE> m;
1530:   PetscErrorCode      ierr;

1533:   MeshGetMesh(mesh, m);
1534:   ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1535:   return(0);
1536: }

1540: /*@C
1541:   MeshGetElements - Creates an array holding the vertices on each element.

1543:   Not Collective

1545:   Input Parameters:
1546: + mesh - The Mesh object
1547: - columnMajor - Flag for column major order

1549:   Output Parameters:
1550: + numElements - The number of elements
1551: . numCorners - The number of vertices per element
1552: - vertices - The array holding vertices on each local element

1554:   Level: intermediate

1556: .keywords: mesh, elements
1557: .seealso: MeshCreate()
1558: @*/
1559: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1560: {
1561:   ALE::Obj<PETSC_MESH_TYPE> m;
1562:   PetscErrorCode      ierr;

1565:   MeshGetMesh(mesh, m);
1566:   ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1567:   return(0);
1568: }

1572: /*@C
1573:   MeshDistribute - Distributes the mesh and any associated sections.

1575:   Not Collective

1577:   Input Parameter:
1578: + serialMesh  - The original Mesh object
1579: - partitioner - The partitioning package, or NULL for the default

1581:   Output Parameter:
1582: . parallelMesh - The distributed Mesh object

1584:   Level: intermediate

1586: .keywords: mesh, elements

1588: .seealso: MeshCreate(), MeshDistributeByFace()
1589: @*/
1590: PetscErrorCode MeshDistribute(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1591: {
1592:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1593:   PetscErrorCode      ierr;

1596:   MeshGetMesh(serialMesh, oldMesh);
1597:   MeshCreate(oldMesh->comm(), parallelMesh);
1598: #ifdef PETSC_OPT_SIEVE
1599:   const Obj<PETSC_MESH_TYPE>             newMesh  = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->getDimension(), oldMesh->debug());
1600:   const Obj<PETSC_MESH_TYPE::sieve_type> newSieve = new PETSC_MESH_TYPE::sieve_type(oldMesh->comm(), oldMesh->debug());

1602:   newMesh->setSieve(newSieve);
1603:   ALE::DistributionNew<PETSC_MESH_TYPE>::distributeMeshAndSectionsV(oldMesh, newMesh);
1604:   MeshSetMesh(*parallelMesh, newMesh);
1605: #else
1606:   if (partitioner == NULL) {
1607:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh);
1608:     MeshSetMesh(*parallelMesh, newMesh);
1609:   } else {
1610:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 0, partitioner);
1611:     MeshSetMesh(*parallelMesh, newMesh);
1612:   }
1613: #endif
1614:   return(0);
1615: }

1619: /*@C
1620:   MeshDistribute - Distributes the mesh and any associated sections.

1622:   Not Collective

1624:   Input Parameter:
1625: + serialMesh  - The original Mesh object
1626: - partitioner - The partitioning package, or NULL for the default

1628:   Output Parameter:
1629: . parallelMesh - The distributed Mesh object

1631:   Level: intermediate

1633: .keywords: mesh, elements

1635: .seealso: MeshCreate(), MeshDistribute()
1636: @*/
1637: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1638: {
1639:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1640:   PetscErrorCode      ierr;

1643:   MeshGetMesh(serialMesh, oldMesh);
1644:   MeshCreate(oldMesh->comm(), parallelMesh);
1645: #ifdef PETSC_OPT_SIEVE
1646:   SETERRQ(PETSC_ERR_SUP, "I am being lazy, bug me.");
1647: #else
1648:   if (partitioner == NULL) {
1649:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1);
1650:     MeshSetMesh(*parallelMesh, newMesh);
1651:   } else {
1652:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1, partitioner);
1653:     MeshSetMesh(*parallelMesh, newMesh);
1654:   }
1655: #endif
1656:   return(0);
1657: }

1661: /*@C
1662:   MeshGenerate - Generates a mesh.

1664:   Not Collective

1666:   Input Parameters:
1667: + boundary - The Mesh boundary object
1668: - interpolate - Flag to create intermediate mesh elements

1670:   Output Parameter:
1671: . mesh - The Mesh object

1673:   Level: intermediate

1675: .keywords: mesh, elements
1676: .seealso: MeshCreate(), MeshRefine()
1677: @*/
1678: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1679: {
1680:   ALE::Obj<PETSC_MESH_TYPE> mB;
1681:   PetscErrorCode      ierr;

1684:   MeshGetMesh(boundary, mB);
1685:   MeshCreate(mB->comm(), mesh);
1686: #ifdef PETSC_OPT_SIEVE
1687:   ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMeshV(mB, interpolate);
1688: #else
1689:   ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMesh(mB, interpolate);
1690: #endif
1691:   MeshSetMesh(*mesh, m);
1692:   return(0);
1693: }

1697: /*@C
1698:   MeshRefine - Refines the mesh.

1700:   Not Collective

1702:   Input Parameters:
1703: + mesh - The original Mesh object
1704: . refinementLimit - The maximum size of any cell
1705: - interpolate - Flag to create intermediate mesh elements

1707:   Output Parameter:
1708: . refinedMesh - The refined Mesh object

1710:   Level: intermediate

1712: .keywords: mesh, elements
1713: .seealso: MeshCreate(), MeshGenerate()
1714: @*/
1715: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1716: {
1717:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1718:   PetscErrorCode      ierr;

1721:   MeshGetMesh(mesh, oldMesh);
1722:   MeshCreate(oldMesh->comm(), refinedMesh);
1723: #ifdef PETSC_OPT_SIEVE
1724:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, interpolate);
1725: #else
1726:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, interpolate);
1727: #endif
1728:   MeshSetMesh(*refinedMesh, newMesh);
1729:   return(0);
1730: }

1734: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1735: {
1736:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1737:   double              refinementLimit;
1738:   PetscErrorCode      ierr;

1741:   MeshGetMesh(mesh, oldMesh);
1742:   MeshCreate(comm, refinedMesh);
1743:   refinementLimit = oldMesh->getMaxVolume()/2.0;
1744: #ifdef PETSC_OPT_SIEVE
1745:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, true);
1746: #else
1747:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, true);
1748: #endif
1749:   MeshSetMesh(*refinedMesh, newMesh);
1750: #ifndef PETSC_OPT_SIEVE
1751:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");
1752:   const Obj<std::set<std::string> >& discs = oldMesh->getDiscretizations();

1754:   for(std::set<std::string>::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter) {
1755:     newMesh->setDiscretization(*f_iter, oldMesh->getDiscretization(*f_iter));
1756:   }
1757:   newMesh->setupField(s);
1758: #endif
1759:   return(0);
1760: }

1762: #ifndef PETSC_OPT_SIEVE

1764: #include "Hierarchy_New.hh"



1770: #include "Hierarchy.hh"

1774: /*@C
1775:   MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.

1777:   Not Collective

1779:   Input Parameters:
1780: + mesh - The original Mesh object
1781: . numLevels - The number of 
1782: . coarseningFactor - The expansion factor for coarse meshes
1783: - interpolate - Flag to create intermediate mesh elements

1785:   Output Parameter:
1786: . coarseHierarchy - The coarse Mesh objects

1788:   Level: intermediate

1790: .keywords: mesh, elements
1791: .seealso: MeshCreate(), MeshGenerate()
1792: @*/
1793: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh **coarseHierarchy)
1794: {
1795:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1796:   PetscErrorCode      ierr;

1799:   if (numLevels < 1) {
1800:     *coarseHierarchy = PETSC_NULL;
1801:     return(0);
1802:   }
1803:   MeshGetMesh(mesh, oldMesh);
1804:   PetscMalloc((numLevels+1) * sizeof(Mesh), coarseHierarchy);
1805:   for (int i = 0; i < numLevels+1; i++) {
1806:     MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[i]);
1807:   }
1808:   MeshSpacingFunction(mesh);
1809:   MeshCreateHierarchyLabel_Link(mesh, coarseningFactor, numLevels+1, *coarseHierarchy);
1810: 
1811: #if 0
1812:   if (oldMesh->getDimension() != 2) SETERRQ(PETSC_ERR_SUP, "Coarsening only works in two dimensions right now");
1813:   ALE::Coarsener::IdentifyBoundary(oldMesh, 2);
1814:   ALE::Coarsener::make_coarsest_boundary(oldMesh, 2, numLevels+1);
1815:   ALE::Coarsener::CreateSpacingFunction(oldMesh, 2);
1816:   ALE::Coarsener::CreateCoarsenedHierarchyNew(oldMesh, 2, numLevels, coarseningFactor);
1817:   PetscMalloc(numLevels * sizeof(Mesh),coarseHierarchy);
1818:   for(int l = 0; l < numLevels; l++) {
1819:     ALE::Obj<PETSC_MESH_TYPE> newMesh = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->debug());
1820:     const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");

1822:     MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1823:     newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1824:     newMesh->setDiscretization(oldMesh->getDiscretization());
1825:     newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1826:     newMesh->setupField(s);
1827:     MeshSetMesh((*coarseHierarchy)[l], newMesh);
1828:   }
1829: #endif
1830:   return(0);
1831: }

1833: #endif

1835: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh **coarseHierarchy)
1836: {
1838:   double cfactor = 1.5;
1840:   PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1841: #ifdef PETSC_OPT_SIEVE
1842:   SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
1843: #else
1844:   MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1845: #endif
1846:   return(0);
1847: }

1849: #if 0


1854: //Interpolate between two meshes whenever the unknowns can be evaluated at points.

1856: PetscErrorCode MeshGetInterpolation_Mesh_General(Mesh coarse_mesh, Mesh fine_mesh, Mat *interpolation, Vec *scaling) {
1857:   ALE::Obj<PETSC_MESH_TYPE> fm, cm;
1858:   Mat                 P;
1859:   PetscErrorCode      ierr;
1860: 
1862:   //Stages:
1863:   //  1. Create a section on the fine mesh describing the location in the fine mesh of the assorted unknowns.
1864:   //  2. Fill in this section by traversing across the mesh via cones and supports, transforming the coordinates of the assorted functional points
1865:   //  3. Preallocate the matrix rows/columns
1866:   //  4. Assemble the matrix by writing evaluating each unknown as the point
1867:   MeshGetMesh(dmFine, fm);
1868:   MeshGetMesh(dmCoarse, cm);
1869:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
1870:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal   = fm->createLabel ("traversal");
1871:   const int                       debug           = fm->debug();
1872:   if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1873:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates   = fm->getRealSection("coordinates");
1874:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");

1876:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse           = cm->getRealSection("default");
1877:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine             = fm->getRealSection("default");

1879:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        coarseOrder       = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1880:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        fineOrder         = fm->getFactory()->getGlobalOrder(fm, "default", sFine);

1882:   std::list<PETSC_MESH_TYPE::point_type> travlist;        // store point
1883:   std::list<PETSC_MESH_TYPE::point_type> travguesslist;   // store guess
1884:   std::list<PETSC_MESH_TYPE::point_type> eguesslist;      // store the next guesses for the location of the current point.

1886:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1887:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1888:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> covering_points = PETSC_MESH_TYPE::sieve_type::supportSet();

1890:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> uncorrected_points = PETSC_MESH_TYPE::sieve_type::supportSet();
1891:   static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1892:   if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}

1894:   //set up the new section holding the names of the contained points.

1896:   const ALE::Obj<PETSC_MESH_TYPE::int_section_type> & node_locations = fm->getIntSection("node_locations");
1897:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type> & fine_default = fm->getRealSection("default");
1898:   int total_dimension
1899:   for (int i = 0; i < dim; i++) {
1900:     const ALE::Obj<PETSC_MESH_TYPE::label_sequence> & present_level = fm->depthStratum(i);
1901:     int current_dimension = fine_default->getFiberDimension(*present_level->begin());
1902:     node_locations->setFiberDimension(present_level, current_dimension);
1903:   }
1904:   node_locations->allocate();
1905:   //traverse!

1907: 

1909:   ALE::Obj<PETSC_MESH_TYPE::label_sequence> fine_cells = fm->heightStratum(0);
1910:   ALE::Obj<PETSC_MESH_TYPE::label_sequence> coarse_cells = cm->heightStratum(0);

1912:   PETSC_MESH_TYPE::label_sequence::iterator fc_iter = fine_cells->begin();
1913:   PETSC_MESH_TYPE::label_sequence::iterator fc_iter_end = fine_cells->end();
1914:   while (fc_iter != fc_iter_end) {
1915:     //locate an initial coarse cell that overlaps with this fine cell in terms of their bounding boxes;
1916:     PETSC_MESH_TYPE::label_sequence::iterator cc_iter = coarse_cells->begin();
1917:     PETSC_MESH_TYPE::label_sequence::iterator cc_iter_end = coarse_cells->end();
1918:     while (cc_iter != cc_iter_end) {
1919: 
1920:       cc_iter++;
1921:     }
1922:     fc_iter++;
1923:   }
1924: }

1926: #endif


1931: PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling) {

1933: #ifdef PETSC_OPT_SIEVE
1934:   SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
1935: #else
1936:   ALE::Obj<PETSC_MESH_TYPE> fm, cm;
1937:   Mat                 P;
1938:   PetscErrorCode      ierr;

1941:   MeshGetMesh(dmFine, fm);
1942:   MeshGetMesh(dmCoarse, cm);
1943:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
1944:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal   = fm->createLabel ("traversal");
1945:   const int                       debug           = fm->debug();
1946:   if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1947:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates   = fm->getRealSection("coordinates");
1948:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
1949:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse           = cm->getRealSection("default");
1950:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine             = fm->getRealSection("default");
1951:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        coarseOrder       = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1952:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        fineOrder         = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
1953:   std::list<PETSC_MESH_TYPE::point_type> travlist;        // store point
1954:   std::list<PETSC_MESH_TYPE::point_type> travguesslist;   // store guess
1955:   std::list<PETSC_MESH_TYPE::point_type> eguesslist;      // store the next guesses for the location of the current point.
1956:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1957:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1958:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> uncorrected_points = PETSC_MESH_TYPE::sieve_type::supportSet();
1959:   static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1960:   if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}

1962:   MatCreate(fm->comm(), &P);
1963:   MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
1964:   MatSeqAIJSetPreallocation(P,10,PETSC_NULL);
1965:   MatSetFromOptions(P);

1967:   const int dim = fm->getDimension();
1968:   int maxComparisons = 60; //point is considered a lost cause beyond this many comparisons with volumes
1969:   if (dim == 3) maxComparisons = 1000; //3D is odd
1970:   if (dim != cm->getDimension()) throw ALE::Exception("Dimensions of the fine and coarse meshes do not match");

1972:   //traversal labels on both layers
1973:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& finevertices = fm->depthStratum(0);
1974:   const PETSC_MESH_TYPE::label_sequence::iterator  fv_iter_end  = finevertices->end();
1975:   PETSC_MESH_TYPE::label_sequence::iterator        fv_iter      = finevertices->begin();

1977:   //  while (fv_iter != fv_iter_end) {
1978:   //    fm->setValue(finetraversal, *fv_iter, 0);
1979:   //    fv_iter++;
1980:   //  }

1982:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& coarseelements = cm->heightStratum(0);
1983:   const PETSC_MESH_TYPE::label_sequence::iterator  ce_iter_end    = coarseelements->end();
1984:   PETSC_MESH_TYPE::label_sequence::iterator        ce_iter        = coarseelements->begin();
1985: 
1986:   //  while (ce_iter != ce_iter_end) {
1987:   //    cm->setValue(coarsetraversal, *ce_iter, 0);
1988:   //    ce_iter++;
1989:   //  }

1991:   double *fvCoords = new double[dim], *nvCoords = new double[dim];
1992:   bool pointIsInElement;

1994:   if (debug) {PetscPrintf(fm->comm(), "starting iterations\n");}
1995:   fv_iter = finevertices->begin();
1996:   while (fv_iter != fv_iter_end) {
1997:     // locate an initial point.
1998:     //    if (fm->getValue(finetraversal, *fv_iter) == 0) {
1999:     if ((fine_traversal->find(*fv_iter) == fine_traversal->end()) && (uncorrected_points->find(*fv_iter) == uncorrected_points->end())) {
2000:       bool isLocated = false;

2002:       ce_iter = coarseelements->begin();
2003:       PetscMemcpy(fvCoords, finecoordinates->restrictPoint(*fv_iter), dim*sizeof(double));
2004:       while ((ce_iter != ce_iter_end) && (!isLocated)) {
2005:         cm->computeElementGeometry(coarsecoordinates, *ce_iter, v0, J, invJ, detJ);
2006:         // generalized simplicial location for 2D, 3D:
2007:         loc[0] = 1.0;
2008:         pointIsInElement = true;
2009:         for(int i = 0; i < dim; i++) {
2010:           loc[i+1] = 0.0;
2011:           for(int j = 0; j < dim; j++) {
2012:             loc[i+1] += 0.5*invJ[i*dim+j]*(fvCoords[j] - v0[j]);
2013:           }
2014:           loc[0] -= loc[i+1];
2015:           //PetscPrintf(fm->comm(), "%f, ", loc[i+1]);
2016:           if (loc[i+1] < -0.000000000001) pointIsInElement = false;
2017:         }
2018:         //PetscPrintf(fm->comm(), "%f\n", loc[0]);
2019:         if (loc[0] < -0.000000000001) pointIsInElement = false;
2020:         if (pointIsInElement) {
2021:           //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2022:           //PetscPrintf(fm->comm(), "located by guess.\n");
2023:           isLocated = true;
2024:           updateOperatorGeneral(P, fm, sFine, fineOrder, *fv_iter, cm, sCoarse, coarseOrder, *ce_iter, loc, INSERT_VALUES);
2025:           //fm->setValue(finetraversal, *fv_iter, 1);
2026:           fine_traversal->insert(*fv_iter);
2027:           const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> & neighbors  = fm->getSieve()->cone(fm->getSieve()->support(*fv_iter));
2028:           const PETSC_MESH_TYPE::sieve_type::coneSet::iterator n_iter_end = neighbors->end();
2029:           PETSC_MESH_TYPE::sieve_type::coneSet::iterator       n_iter     = neighbors->begin();
2030:           while (n_iter != n_iter_end) {
2031:             //            if (fm->getValue(finetraversal, *n_iter) == 0) {
2032:             if (fine_traversal->find(*n_iter) != fine_traversal->end()) {
2033:               travlist.push_back(*n_iter);
2034:               //              fm->setValue(finetraversal, *n_iter, 1);
2035:               fine_traversal->insert(*n_iter);
2036:               travguesslist.push_back(*ce_iter);
2037:             }
2038:             n_iter++;
2039:           }
2040:           //do a DFS across the finemesh with BFSes on the coarse mesh for each point using assumed regularity of edgelength as a justification for guessing neighboring point's locations.
2041:           while (!travlist.empty()) {
2042:             PETSC_MESH_TYPE::point_type curVert = *travlist.begin();
2043:             PetscMemcpy(nvCoords, finecoordinates->restrictPoint(curVert), dim*sizeof(double));
2044:             PETSC_MESH_TYPE::point_type curEle =  *travguesslist.begin();
2045:             travlist.pop_front();
2046:             travguesslist.pop_front();
2047:             eguesslist.push_front(curEle);
2048:             //cm->setValue(coarsetraversal, curEle, 1);
2049:             coarse_traversal->insert(curEle);
2050:             bool locationDiscovered  = false;
2051:             //int traversalcomparisons = 0;
2052:             while ((!eguesslist.empty()) && (!locationDiscovered) && (int)coarse_traversal->size() < maxComparisons) {
2053:               //traversalcomparisons = 0;
2054:               PETSC_MESH_TYPE::point_type curguess = *eguesslist.begin();
2055:               eguesslist.pop_front();
2056:               pointIsInElement = true;
2057:               cm->computeElementGeometry(coarsecoordinates, curguess, v0, J, invJ, detJ);
2058:               loc[0] = 1.0;
2059:               for(int i = 0; i < dim; i++) {
2060:                 loc[i+1] = 0.0;
2061:                 for(int j = 0; j < dim; j++) {
2062:                   loc[i+1] += 0.5*invJ[i*dim+j]*(nvCoords[j] - v0[j]);
2063:                 }
2064:                 loc[0] -= loc[i+1];
2065:                 if (loc[i+1] < -0.00000000001) pointIsInElement = false;
2066:               }
2067:               if (loc[0] < -0.00000000001) pointIsInElement = false;

2069:               if (pointIsInElement) {
2070:                 //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2071:                 locationDiscovered = true;
2072:                 //PetscPrintf(fm->comm(), "located by traversal.\n");
2073:                 //set the label.
2074:                 //fm->setValue(prolongation, curVert, curguess);
2075:                 updateOperatorGeneral(P, fm, sFine, fineOrder, curVert, cm, sCoarse, coarseOrder, curguess, loc, INSERT_VALUES);
2076:                 //PetscPrintf(fm->comm(), "Point %d located in %d.\n",  curVert, curguess);
2077:                 //stick its neighbors in the queue along with its location as a good guess of the location of its neighbors
2078:                 const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> newNeighbors = fm->getSieve()->cone(fm->getSieve()->support(curVert));
2079:                 const PETSC_MESH_TYPE::sieve_type::coneSet::iterator nn_iter_end  = newNeighbors->end();
2080:                 PETSC_MESH_TYPE::sieve_type::coneSet::iterator       nn_iter      = newNeighbors->begin();
2081:                 while (nn_iter != nn_iter_end) {
2082:                   //if (fm->getValue(finetraversal, *nn_iter) == 0) { //unlocated neighbor
2083:                   if (fine_traversal->find(*nn_iter) == fine_traversal->end()) {
2084:                     travlist.push_back(*nn_iter);
2085:                     travguesslist.push_back(curguess);
2086:                     //fm->setValue(finetraversal, *nn_iter, 1);
2087:                     fine_traversal->insert(*nn_iter);
2088:                   }
2089:                   nn_iter++;
2090:                 }
2091:               } else {
2092:               //add the current guesses neighbors to the comparison queue and start over.
2093:                 const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> & curguessneighbors = cm->getSieve()->support(cm->getSieve()->cone(curguess));
2094:                 const PETSC_MESH_TYPE::sieve_type::supportSet::iterator cgn_iter_end      = curguessneighbors->end();
2095:                 PETSC_MESH_TYPE::sieve_type::supportSet::iterator       cgn_iter          = curguessneighbors->begin();
2096:                 while (cgn_iter != cgn_iter_end) {
2097:                   //if (cm->getValue(coarsetraversal, *cgn_iter) == 0) {
2098:                   if (coarse_traversal->find(*cgn_iter) == coarse_traversal->end()) {
2099:                     eguesslist.push_back(*cgn_iter);
2100:                     //cm->setValue(coarsetraversal, *cgn_iter, 1);
2101:                     coarse_traversal->insert(*cgn_iter);
2102:                   }
2103:                   cgn_iter++;
2104:                 }
2105:               }
2106:             }
2107:             coarse_traversal->clear();
2108:             if (!locationDiscovered) {  //if a position for it is not discovered, it doesn't get corrected; complain
2109:               if (fm->debug())PetscPrintf(fm->comm(), "Point %d (%f, %f) not located.\n",  curVert, nvCoords[0], nvCoords[1]);
2110:               //fm->setValue(finetraversal, curVert, 2); //don't try again.
2111:               uncorrected_points->insert(curVert);
2112:             }
2113:             eguesslist.clear(); //we've discovered the location of the point or exhausted our possibilities on this contiguous block of elements.
2114:             //unset the traversed element list
2115:             //const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& traved_elements = cm->getLabelStratum("traversal", 1);
2116:             //const PETSC_MESH_TYPE::label_sequence::iterator  tp_iter_end     = traved_elements->end();
2117:             //PETSC_MESH_TYPE::label_sequence::iterator        tp_iter         = traved_elements->begin();
2118:             //PetscPrintf(cm->comm(), "%d\n", traved_elements->size());
2119:             //while (tp_iter != tp_iter_end) {
2120:             //  eguesslist.push_back(*tp_iter);
2121:             //  tp_iter++;
2122:             //}
2123:             //while (!eguesslist.empty()) {
2124:             //  cm->setValue(coarsetraversal, *eguesslist.begin(), 0);
2125:             //  eguesslist.pop_front();
2126:             //}
2127: 
2128:           }
2129:         }
2130:         ce_iter++;
2131:       }
2132:       if (!isLocated) {
2133:        if (fm->debug())PetscPrintf(fm->comm(), "NOT located\n");
2134:        //fm->setValue(finetraversal, *fv_iter, 2); //don't try again.
2135:        uncorrected_points->insert(*fv_iter);
2136:       }
2137:     }
2138:     // printf("-");
2139:     fv_iter++;
2140:   }
2141:   MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2142:   MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2143:   //MatView(P, PETSC_VIEWER_STDOUT_SELF);
2144:   delete [] fvCoords; delete [] nvCoords;
2145:   *interpolation = P;
2146:   if (debug) {PetscPrintf(fm->comm(), "Ending Interpolation Matrix Build\n");}
2147:   return(0);
2148: #endif
2149: }


2154: /*
2155:   This method only handle P_1 discretizations at present.
2156: */
2157: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
2158: {
2159: #ifdef PETSC_OPT_SIEVE
2160:   SETERRQ(PETSC_ERR_SUP, "This has been superceded.");
2161: #else
2162:   ALE::Obj<PETSC_MESH_TYPE> coarse;
2163:   ALE::Obj<PETSC_MESH_TYPE> fine;
2164:   Mat                 P;
2165:   PetscErrorCode      ierr;

2168:   MeshGetMesh(dmFine,   fine);
2169:   MeshGetMesh(dmCoarse, coarse);
2170:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
2171:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& fineCoordinates   = fine->getRealSection("coordinates");
2172:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>&    vertices          = fine->depthStratum(0);
2173:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse           = coarse->getRealSection("default");
2174:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine             = fine->getRealSection("default");
2175:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
2176:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        fineOrder   = fine->getFactory()->getGlobalOrder(fine, "default", sFine);

2178:   const int dim    = coarse->getDimension();
2179:   const int numDof = fine->getDiscretization()->getNumDof(fine->getDimension());
2180:   double *v0, *J, *invJ, detJ, *refCoords, *values;

2182:   MatCreate(fine->comm(), &P);
2183:   MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2184:   MatSetFromOptions(P);
2185:   MatSeqAIJSetPreallocation(P, numDof, PETSC_NULL);
2186:   MatMPIAIJSetPreallocation(P, numDof, PETSC_NULL, numDof, PETSC_NULL);
2187:   PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
2188:   bool hasprolong;
2189:   if (fine->hasLabel("prolongation")) {
2190:     hasprolong = true;
2191:   } else {
2192:     hasprolong = false;
2193:     PetscPrintf(fine->comm(), "WARNING: Point Location Label Does Not Exist");
2194:   }
2195:   PETSC_MESH_TYPE::label_sequence::iterator v_iter_end = vertices->end();
2196:   PETSC_MESH_TYPE::real_section_type::value_type *coords = new PETSC_MESH_TYPE::real_section_type::value_type[dim];

2198:   for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != v_iter_end; ++v_iter) {
2199:     //const PETSC_MESH_TYPE::real_section_type::value_type *coords     = fineCoordinates->restrictPoint(*v_iter);
2200:     PetscMemcpy(coords, fineCoordinates->restrictPoint(*v_iter), dim*sizeof(double));
2201:     PETSC_MESH_TYPE::point_type coarseCell;
2202:     PETSC_MESH_TYPE::point_type cellguess = -1;
2203:     if (hasprolong) {
2204:       cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
2205:       coarseCell = coarse->locatePoint(coords, cellguess);
2206:     } else {
2207:       coarseCell = coarse->locatePoint(coords);
2208:     }
2209: //      coarseCell = coarse->locatePoint(coords);
2210:     if (coarseCell == -1) {
2211:      // do NO CORRECTION!
2212:     } else {
2213:       coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
2214:       for(int d = 0; d < dim; ++d) {
2215:         refCoords[d] = 0.0;
2216:         for(int e = 0; e < dim; ++e) {
2217:           refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
2218:         }
2219:         refCoords[d] -= 1.0;
2220:       }
2221:       values[0] = -(refCoords[0] + refCoords[1])/2.0;
2222:       values[1] = 0.5*(refCoords[0] + 1.0);
2223:       values[2] = 0.5*(refCoords[1] + 1.0);
2224:   //    PetscPrintf(fine->comm(), "%f, %f, %f\n", values[0], values[1], values[2]);
2225:       updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
2226:     }
2227:   }
2228:   PetscFree5(v0,J,invJ,refCoords,values);
2229:   MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2230:   MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2231:   delete [] coords;
2232:   *interpolation = P;
2233:   return(0);
2234: #endif
2235: }

2239: /*@C
2240:   MeshHasSectionReal - Determines whether this mesh has a SectionReal with the given name.

2242:   Not Collective

2244:   Input Parameters:
2245: + mesh - The Mesh object
2246: - name - The section name

2248:   Output Parameter:
2249: . flag - True if the SectionReal is present in the Mesh

2251:   Level: intermediate

2253: .keywords: mesh, elements
2254: .seealso: MeshCreate()
2255: @*/
2256: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
2257: {
2258:   ALE::Obj<PETSC_MESH_TYPE> m;
2259:   PetscErrorCode      ierr;

2262:   MeshGetMesh(mesh, m);
2263:   *flag = (PetscTruth) m->hasRealSection(std::string(name));
2264:   return(0);
2265: }

2269: /*@C
2270:   MeshGetSectionReal - Returns a SectionReal of the given name from the Mesh.

2272:   Collective on Mesh

2274:   Input Parameters:
2275: + mesh - The Mesh object
2276: - name - The section name

2278:   Output Parameter:
2279: . section - The SectionReal

2281:   Note: The section is a new object, and must be destroyed by the user

2283:   Level: intermediate

2285: .keywords: mesh, elements
2286: .seealso: MeshCreate()
2287: @*/
2288: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
2289: {
2290:   ALE::Obj<PETSC_MESH_TYPE> m;
2291:   PetscErrorCode      ierr;

2294:   MeshGetMesh(mesh, m);
2295:   SectionRealCreate(m->comm(), section);
2296:   PetscObjectSetName((PetscObject) *section, name);
2297:   SectionRealSetSection(*section, m->getRealSection(std::string(name)));
2298:   SectionRealSetBundle(*section, m);
2299:   return(0);
2300: }

2304: /*@C
2305:   MeshSetSectionReal - Puts a SectionReal of the given name into the Mesh.

2307:   Collective on Mesh

2309:   Input Parameters:
2310: + mesh - The Mesh object
2311: - section - The SectionReal

2313:   Note: This takes the section name from the PETSc object

2315:   Level: intermediate

2317: .keywords: mesh, elements
2318: .seealso: MeshCreate()
2319: @*/
2320: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
2321: {
2322:   ALE::Obj<PETSC_MESH_TYPE> m;
2323:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2324:   const char         *name;
2325:   PetscErrorCode      ierr;

2328:   MeshGetMesh(mesh, m);
2329:   PetscObjectGetName((PetscObject) section, &name);
2330:   SectionRealGetSection(section, s);
2331:   m->setRealSection(std::string(name), s);
2332:   return(0);
2333: }

2337: /*@C
2338:   MeshHasSectionInt - Determines whether this mesh has a SectionInt with the given name.

2340:   Not Collective

2342:   Input Parameters:
2343: + mesh - The Mesh object
2344: - name - The section name

2346:   Output Parameter:
2347: . flag - True if the SectionInt is present in the Mesh

2349:   Level: intermediate

2351: .keywords: mesh, elements
2352: .seealso: MeshCreate()
2353: @*/
2354: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2355: {
2356:   ALE::Obj<PETSC_MESH_TYPE> m;
2357:   PetscErrorCode      ierr;

2360:   MeshGetMesh(mesh, m);
2361:   *flag = (PetscTruth) m->hasIntSection(std::string(name));
2362:   return(0);
2363: }

2367: /*@C
2368:   MeshGetSectionInt - Returns a SectionInt of the given name from the Mesh.

2370:   Collective on Mesh

2372:   Input Parameters:
2373: + mesh - The Mesh object
2374: - name - The section name

2376:   Output Parameter:
2377: . section - The SectionInt

2379:   Note: The section is a new object, and must be destroyed by the user

2381:   Level: intermediate

2383: .keywords: mesh, elements
2384: .seealso: MeshCreate()
2385: @*/
2386: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2387: {
2388:   ALE::Obj<PETSC_MESH_TYPE> m;
2389:   PetscErrorCode      ierr;

2392:   MeshGetMesh(mesh, m);
2393:   SectionIntCreate(m->comm(), section);
2394:   PetscObjectSetName((PetscObject) *section, name);
2395:   SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2396:   SectionIntSetBundle(*section, m);
2397:   return(0);
2398: }

2402: /*@C
2403:   MeshSetSectionInt - Puts a SectionInt of the given name into the Mesh.

2405:   Collective on Mesh

2407:   Input Parameters:
2408: + mesh - The Mesh object
2409: - section - The SectionInt

2411:   Note: This takes the section name from the PETSc object

2413:   Level: intermediate

2415: .keywords: mesh, elements
2416: .seealso: MeshCreate()
2417: @*/
2418: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2419: {
2420:   ALE::Obj<PETSC_MESH_TYPE> m;
2421:   ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2422:   const char         *name;
2423:   PetscErrorCode      ierr;

2426:   MeshGetMesh(mesh, m);
2427:   PetscObjectGetName((PetscObject) section, &name);
2428:   SectionIntGetSection(section, s);
2429:   m->setIntSection(std::string(name), s);
2430:   return(0);
2431: }

2435: /*@C
2436:   SectionGetArray - Returns the array underlying the Section.

2438:   Not Collective

2440:   Input Parameters:
2441: + mesh - The Mesh object
2442: - name - The section name

2444:   Output Parameters:
2445: + numElements - The number of mesh element with values
2446: . fiberDim - The number of values per element
2447: - array - The array

2449:   Level: intermediate

2451: .keywords: mesh, elements
2452: .seealso: MeshCreate()
2453: @*/
2454: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2455: {
2456:   ALE::Obj<PETSC_MESH_TYPE> m;
2457:   PetscErrorCode      ierr;

2460:   MeshGetMesh(mesh, m);
2461:   const Obj<PETSC_MESH_TYPE::real_section_type>& section = m->getRealSection(std::string(name));
2462:   if (section->size() == 0) {
2463:     *numElements = 0;
2464:     *fiberDim    = 0;
2465:     *array       = NULL;
2466:     return(0);
2467:   }
2468:   const PETSC_MESH_TYPE::real_section_type::chart_type& chart = section->getChart();
2469: /*   const int                                  depth   = m->depth(*chart.begin()); */
2470: /*   *numElements = m->depthStratum(depth)->size(); */
2471: /*   *fiberDim    = section->getFiberDimension(*chart.begin()); */
2472: /*   *array       = (PetscScalar *) m->restrict(section); */
2473:   int fiberDimMin = section->getFiberDimension(*chart.begin());
2474:   int numElem     = 0;

2476:   for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2477:     const int fiberDim = section->getFiberDimension(*c_iter);

2479:     if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2480:   }
2481:   for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2482:     const int fiberDim = section->getFiberDimension(*c_iter);

2484:     numElem += fiberDim/fiberDimMin;
2485:   }
2486:   *numElements = numElem;
2487:   *fiberDim    = fiberDimMin;
2488:   *array       = (PetscScalar *) section->restrictSpace();
2489:   return(0);
2490: }

2494: /*@C
2495:   MeshRestrictClosure - Returns an array with the values in a given closure

2497:   Not Collective

2499:   Input Parameters:
2500: + mesh    - The Mesh object
2501: . section - The section
2502: . point   - The sieve point
2503: . n       - The array size
2504: - array   - The array to fill up

2506:   Output Parameter:
2507: . array - The array full of values in the closure

2509:   Level: intermediate

2511: .keywords: mesh, elements
2512: .seealso: MeshCreate()
2513: @*/
2514: PetscErrorCode MeshRestrictClosure(Mesh mesh, SectionReal section, PetscInt point, PetscInt n, PetscScalar values[])
2515: {
2516:   ALE::Obj<PETSC_MESH_TYPE> m;
2517:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2518:   PetscErrorCode            ierr;

2521:   MeshGetMesh(mesh, m);
2522:   SectionRealGetSection(section, s);
2523:   m->restrictClosure(s, point, values, n);
2524:   return(0);
2525: }

2529: /*@C
2530:   MeshUpdateClosure - Updates the values in a given closure from the array

2532:   Not Collective

2534:   Input Parameters:
2535: + mesh    - The Mesh object
2536: . section - The section
2537: . point   - The sieve point
2538: - array   - The array to fill up

2540:   Output Parameter:
2541: . array - The array full of values in the closure

2543:   Level: intermediate

2545: .keywords: mesh, elements
2546: .seealso: MeshCreate()
2547: @*/
2548: PetscErrorCode MeshUpdateClosure(Mesh mesh, SectionReal section, PetscInt point, PetscScalar values[])
2549: {
2550:   ALE::Obj<PETSC_MESH_TYPE> m;
2551:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2552:   PetscErrorCode            ierr;

2555:   MeshGetMesh(mesh, m);
2556:   SectionRealGetSection(section, s);
2557:   m->update(s, point, values);
2558:   return(0);
2559: }

2563: PetscErrorCode WritePyLithVertices(Mesh mesh, PetscViewer viewer)
2564: {
2565:   ALE::Obj<PETSC_MESH_TYPE> m;

2568:   MeshGetMesh(mesh, m);
2569:   return ALE::PyLith::Viewer::writeVertices(m, viewer);
2570: }

2574: PetscErrorCode WritePyLithElements(Mesh mesh, SectionInt material, PetscViewer viewer)
2575: {
2576:   ALE::Obj<PETSC_MESH_TYPE> m;
2577:   ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;

2580:   MeshGetMesh(mesh, m);
2581:   SectionIntGetSection(material, s);
2582:   return ALE::PyLith::Viewer::writeElements(m, s, viewer);
2583: }

2587: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2588: {
2589:   ALE::Obj<PETSC_MESH_TYPE> m;

2592:   MeshGetMesh(mesh, m);
2593:   return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2594: }

2598: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2599: {
2600:   ALE::Obj<PETSC_MESH_TYPE> m;
2601:   ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;

2604:   MeshGetMesh(mesh, m);
2605:   SectionIntGetSection(material, s);
2606:   return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2607: }

2609: #if 0
2612: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2613: {
2614:   ALE::Obj<PETSC_MESH_TYPE> m;

2617:   MeshGetMesh(mesh, m);
2618:   return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2619: }
2620: #endif

2624: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2625: {
2626:   const int end = interval.prefix + interval.index;
2627:   for(int i = interval.index; i < end; i++) {
2628:     indices[indx++] = i;
2629:   }
2630: }

2634: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2635: {
2636:   for(int i = 0; i < interval.prefix; i++) {
2637:     indices[(*indx)++] = interval.index + i;
2638:   }
2639:   for(int i = 0; i < -interval.prefix; i++) {
2640:     indices[(*indx)++] = -1;
2641:   }
2642: }