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: #if PETSC_HAVE_SIEVE
 14: ALE::MemoryLogger Petsc_MemoryLogger;
 15: #endif

 17: EXTERN PetscErrorCode MeshView_Mesh(Mesh, PetscViewer);
 18: EXTERN PetscErrorCode MeshRefine_Mesh(Mesh, MPI_Comm, Mesh *);
 19: EXTERN PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh, int, Mesh *);
 20: EXTERN PetscErrorCode MeshGetInterpolation_Mesh(Mesh, Mesh, Mat *, Vec *);
 21: EXTERN PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh, Mesh, Mat *, Vec *);

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

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


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

 44: PetscErrorCode MeshFinalize()
 45: {
 47:   PETSC_MESH_TYPE::MeshNumberingFactory::singleton(0, 0, true);
 48:   return(0);
 49: }

 53: PetscErrorCode MeshView_Sieve_Ascii(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
 54: {
 55:   PetscViewerFormat format;
 56:   PetscErrorCode    ierr;

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

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

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

109:     PetscViewerFileGetName(viewer, &filename);

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

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

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

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


162: PetscErrorCode MeshView_Sieve_Binary(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
163: {
164:   char           *filename;
165:   PetscErrorCode  ierr;

168:   PetscViewerFileGetName(viewer, &filename);
169:   ALE::MeshSerializer::writeMesh(filename, *mesh);
170:   return(0);
171: }

175: PetscErrorCode MeshView_Sieve(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
176: {
177:   PetscTruth     iascii, isbinary, isdraw;

181:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
182:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
183:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);

185:   if (iascii){
186:     MeshView_Sieve_Ascii(mesh, viewer);
187:   } else if (isbinary) {
188:     MeshView_Sieve_Binary(mesh, viewer);
189:   } else if (isdraw){
190:     SETERRQ(PETSC_ERR_SUP, "Draw viewer not implemented for Mesh");
191:   } else {
192:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
193:   }
194:   return(0);
195: }

199: PetscErrorCode  MeshView_Mesh(Mesh mesh, PetscViewer viewer)
200: {

204:   MeshView_Sieve(mesh->m, viewer);
205:   return(0);
206: }

210: /*@C
211:    MeshView - Views a Mesh object. 

213:    Collective on Mesh

215:    Input Parameters:
216: +  mesh - the mesh
217: -  viewer - an optional visualization context

219:    Notes:
220:    The available visualization contexts include
221: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
222: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
223:          output where only the first processor opens
224:          the file.  All other processors send their 
225:          data to the first processor to print. 

227:    You can change the format the mesh is printed using the 
228:    option PetscViewerSetFormat().

230:    The user can open alternative visualization contexts with
231: +    PetscViewerASCIIOpen() - Outputs mesh to a specified file
232: .    PetscViewerBinaryOpen() - Outputs mesh in binary to a
233:          specified file; corresponding input uses MeshLoad()
234: .    PetscViewerDrawOpen() - Outputs mesh to an X window display

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

242:    Level: beginner

244:    Concepts: mesh^printing
245:    Concepts: mesh^saving to disk

247: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
248:           MeshLoad(), PetscViewerCreate()
249: @*/
250: PetscErrorCode  MeshView(Mesh mesh, PetscViewer viewer)
251: {

257:   if (!viewer) {
258:     PetscViewerASCIIGetStdout(((PetscObject)mesh)->comm,&viewer);
259:   }

263:   PetscLogEventBegin(Mesh_View,0,0,0,0);
264:   (*mesh->ops->view)(mesh, viewer);
265:   PetscLogEventEnd(Mesh_View,0,0,0,0);
266:   return(0);
267: }

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

274:     Collective on Viewer

276:     Input Parameter:
277: .   viewer - The viewer containing the data

279:     Output Parameters:
280: .   mesh - the mesh object

282:     Level: advanced

284: .seealso MeshView()

286: @*/
287: PetscErrorCode  MeshLoad(PetscViewer viewer, Mesh mesh)
288: {
289:   char           *filename;
290:   PetscErrorCode  ierr;

293:   if (!mesh->m) {
294:     MPI_Comm comm;

296:     PetscObjectGetComm((PetscObject) viewer, &comm);
297:     ALE::Obj<PETSC_MESH_TYPE> m = new PETSC_MESH_TYPE(comm, 1);

299:     MeshSetMesh(mesh, m);
300:   }
301:   PetscViewerFileGetName(viewer, &filename);
302:   ALE::MeshSerializer::loadMesh(filename, *mesh->m);
303:   return(0);
304: }

308: /*@C
309:     MeshGetMesh - Gets the internal mesh object

311:     Not collective

313:     Input Parameter:
314: .    mesh - the mesh object

316:     Output Parameter:
317: .    m - the internal mesh object
318:  
319:     Level: advanced

321: .seealso MeshCreate(), MeshSetMesh()

323: @*/
324: PetscErrorCode  MeshGetMesh(Mesh mesh, ALE::Obj<PETSC_MESH_TYPE>& m)
325: {
328:   m = mesh->m;
329:   return(0);
330: }

334: /*@C
335:     MeshSetMesh - Sets the internal mesh object

337:     Not collective

339:     Input Parameters:
340: +    mesh - the mesh object
341: -    m - the internal mesh object
342:  
343:     Level: advanced

345: .seealso MeshCreate(), MeshGetMesh()

347: @*/
348: PetscErrorCode  MeshSetMesh(Mesh mesh, const ALE::Obj<PETSC_MESH_TYPE>& m)
349: {
352:   mesh->m = m;
353:   if (mesh->globalScatter) {

356:     VecScatterDestroy(mesh->globalScatter);
357:     mesh->globalScatter = PETSC_NULL;
358:   }
359:   return(0);
360: }

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

368:   Collective on Mesh

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

376:   Output Parameter:
377: . J  - matrix with the correct nonzero preallocation
378:        (obviously without the correct Jacobian values)

380:   Level: advanced

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

385: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
386: @*/
387: PetscErrorCode  MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
388: {
389:   ALE::Obj<PETSC_MESH_TYPE> m;
390:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;

394:   MeshGetMesh(mesh, m);
395:   SectionRealGetSection(section, s);
396:   try {
397:     MeshCreateMatrix(m, s, mtype, J);
398:   } catch(ALE::Exception e) {
399:     SETERRQ(PETSC_ERR_LIB, e.message());
400:   }
401:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
402:   return(0);
403: }

407: PetscErrorCode  MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
408: {
409:   SectionReal    section;

413:   MeshGetVertexSectionReal(mesh, "default", 1, &section);
414:   MeshCreateMatrix(mesh, section, mtype, J);
415:   SectionRealDestroy(section);
416:   return(0);
417: }

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

425:     Collective on Mesh

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

432:     Output Parameter:
433: .   J  - matrix with the correct nonzero preallocation
434:         (obviously without the correct Jacobian values)

436:     Level: advanced

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

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

443: @*/
444: PetscErrorCode  MeshGetMatrix(Mesh mesh, const MatType mtype, Mat *J)
445: {
446:   ALE::Obj<PETSC_MESH_TYPE> m;
447:   PetscTruth          flag;
448:   PetscErrorCode      ierr;

451:   MeshHasSectionReal(mesh, "default", &flag);
452:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
453:   MeshGetMesh(mesh, m);
454:   MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
455:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
456:   return(0);
457: }

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

465:     Collective on MPI_Comm

467:     Input Parameter:
468: .   comm - the processors that will share the global vector

470:     Output Parameters:
471: .   mesh - the mesh object

473:     Level: advanced

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

477: @*/
478: PetscErrorCode  MeshCreate(MPI_Comm comm,Mesh *mesh)
479: {
481:   Mesh         p;

485:   *mesh = PETSC_NULL;
486: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
487:   DMInitializePackage(PETSC_NULL);
488: #endif

490:   PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
491:   p->ops->view               = MeshView_Mesh;
492:   p->ops->destroy            = PETSC_NULL;
493:   p->ops->createglobalvector = MeshCreateGlobalVector;
494:   p->ops->createlocalvector  = MeshCreateLocalVector;
495:   p->ops->getcoloring        = PETSC_NULL;
496:   p->ops->getmatrix          = MeshGetMatrix;
497:   p->ops->getinterpolation   = MeshGetInterpolation_Mesh_New;
498:   p->ops->getinjection       = PETSC_NULL;
499:   p->ops->refine             = MeshRefine_Mesh;
500:   p->ops->coarsen            = PETSC_NULL;
501:   p->ops->refinehierarchy    = PETSC_NULL;
502:   p->ops->coarsenhierarchy   = MeshCoarsenHierarchy_Mesh;

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

506:   new(&p->m) ALE::Obj<PETSC_MESH_TYPE>(PETSC_NULL);
507:   p->globalScatter = PETSC_NULL;
508:   p->lf            = PETSC_NULL;
509:   p->lj            = PETSC_NULL;
510:   p->data          = PETSC_NULL;
511:   *mesh = p;
512:   return(0);
513: }

517: /*@
518:     MeshDestroy - Destroys a mesh.

520:     Collective on Mesh

522:     Input Parameter:
523: .   mesh - the mesh object

525:     Level: advanced

527: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
528: @*/
529: PetscErrorCode  MeshDestroy(Mesh mesh)
530: {
531:   PetscErrorCode     ierr;

534:   if (--((PetscObject)mesh)->refct > 0) return(0);
535:   PETSc::Log::Event("MeshDestroy").begin();
536:   if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
537:   mesh->m = PETSC_NULL;
538:   PetscHeaderDestroy(mesh);
539:   PETSc::Log::Event("MeshDestroy").end();
540:   return(0);
541: }

545: /*@C
546:   MeshSetType - Sets the Mesh type

548:   Collective on Mesh

550:   Input Parameters:
551: + mesh - the Mesh context
552: - type - the type

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

558:   Notes:
559:   See "petsc/include/petscmesh.h" for available types (for instance,
560:   MESHCARTESIAN or MESHSIEVE).

562:   Level: intermediate

564: .keywords: Mesh, set, typr
565: .seealso: MeshGetType(), MeshType
566: @*/
567: PetscErrorCode  MeshSetType(Mesh mesh, const MeshType type)
568: {
569:   PetscErrorCode ierr,(*r)(Mesh);
570:   PetscTruth     match;


576:   PetscTypeCompare((PetscObject)mesh,type,&match);
577:   if (match) return(0);

579:    PetscFListFind(MeshList,((PetscObject)mesh)->comm,type,(void (**)(void)) &r);
580:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
581:   /* Destroy the previous private Mesh context */
582:   if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
583:   /* Reinitialize function pointers in MeshOps structure */
584:   PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
585:   /* Call the MeshCreate_XXX routine for this particular mesh */
586:   (*r)(mesh);
587:   PetscObjectChangeTypeName((PetscObject) mesh, type);
588:   return(0);
589: }

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

596:   Not Collective

598:   Input Parameter:
599: . mesh - Mesh context 

601:   Output Parameter:
602: . name - name of Mesh type 

604:   Level: intermediate

606: .keywords: Mesh, get, type
607: .seealso: MeshSetType()
608: @*/
609: PetscErrorCode  MeshGetType(Mesh mesh,const MeshType *type)
610: {
614:   *type = ((PetscObject)mesh)->type_name;
615:   return(0);
616: }

620: /*@C
621:   MeshRegister - See MeshRegisterDynamic()

623:   Level: advanced
624: @*/
625: PetscErrorCode  MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
626: {
628:   char           fullname[PETSC_MAX_PATH_LEN];

631:   PetscFListConcat(path,name,fullname);
632:   PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
633:   return(0);
634: }

637: EXTERN PetscErrorCode  MeshCreate_Cartesian(Mesh);

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

645:   Not Collective

647:   Level: advanced

649: .keywords: Mesh, register, all
650: .seealso:  MeshRegisterDestroy()
651: @*/
652: PetscErrorCode  MeshRegisterAll(const char path[])
653: {

657:   MeshRegisterAllCalled = PETSC_TRUE;

659:   MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
660:   return(0);
661: }

665: /*@C
666:   MeshRegisterDestroy - Frees the list of Mesh types that were
667:   registered by MeshRegister().

669:   Not Collective

671:   Level: advanced

673: .keywords: Mesh, register, destroy
674: .seealso: MeshRegister(), MeshRegisterAll()
675: @*/
676: PetscErrorCode  MeshRegisterDestroy(void)
677: {

681:   PetscFListDestroy(&MeshList);
682:   MeshRegisterAllCalled = PETSC_FALSE;
683:   return(0);
684: }

688: /*@C
689:     MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into 
690:         by the mesh.

692:     Collective on Mesh

694:     Input Parameter:
695: .    mesh - the mesh object

697:     Output Parameters:
698: .   gvec - the global vector

700:     Level: advanced

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

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

706: @*/
707: PetscErrorCode  MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
708: {
709:   ALE::Obj<PETSC_MESH_TYPE> m;
710:   PetscTruth     flag;

714:   MeshHasSectionReal(mesh, "default", &flag);
715:   if (!flag) {SETERRQ1(PETSC_ERR_ARG_WRONGSTATE, "Must set default section for mesh %p", m.objPtr);}
716:   MeshGetMesh(mesh, m);
717:   const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));

719:   VecCreate(m->comm(), gvec);
720:   VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
721:   VecSetFromOptions(*gvec);
722:   return(0);
723: }

727: /*@
728:   MeshCreateVector - Creates a global vector matching the input section

730:   Collective on Mesh

732:   Input Parameters:
733: + mesh - the Mesh
734: - section - the Section

736:   Output Parameter:
737: . vec - the global vector

739:   Level: advanced

741:   Notes: The vector can safely be destroyed using VecDestroy().
742: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
743: @*/
744: PetscErrorCode  MeshCreateVector(Mesh mesh, SectionReal section, Vec *vec)
745: {
746:   ALE::Obj<PETSC_MESH_TYPE> m;
747:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;

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

755:   VecCreate(m->comm(), vec);
756:   VecSetSizes(*vec, order->getLocalSize(), order->getGlobalSize());
757:   VecSetFromOptions(*vec);
758:   return(0);
759: }

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

766:     Collective on Mesh

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

771:     Output Parameters:
772: .   lvec - the local vector

774:     Level: advanced

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

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

780: @*/
781: PetscErrorCode  MeshCreateLocalVector(Mesh mesh, Vec *lvec)
782: {
783:   ALE::Obj<PETSC_MESH_TYPE> m;
784:   PetscTruth     flag;

788:   MeshHasSectionReal(mesh, "default", &flag);
789:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
790:   MeshGetMesh(mesh, m);
791:   const int size = m->getRealSection("default")->getStorageSize();

793:   VecCreate(PETSC_COMM_SELF, lvec);
794:   VecSetSizes(*lvec, size, size);
795:   VecSetFromOptions(*lvec);
796:   return(0);
797: }

801: /*@C
802:     MeshGetGlobalIndices - Gets the global indices for all the local entries

804:     Collective on Mesh

806:     Input Parameter:
807: .    mesh - the mesh object

809:     Output Parameters:
810: .    idx - the individual indices for each packed vector/array
811:  
812:     Level: advanced

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

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

819: @*/
820: PetscErrorCode  MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
821: {
822:   SETERRQ(PETSC_ERR_SUP, "");
823: }

827: /*@
828:   MeshCreateGlobalScatter - Create a VecScatter which maps from local, overlapping
829:   storage in the Section to a global Vec

831:   Collective on Mesh

833:   Input Parameters:
834: + mesh - the mesh object
835: - section - The Scetion which determines data layout

837:   Output Parameter:
838: . scatter - the VecScatter
839:  
840:   Level: advanced

842: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
843: @*/
844: PetscErrorCode  MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
845: {
846:   ALE::Obj<PETSC_MESH_TYPE> m;
847:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;

851:   MeshGetMesh(mesh, m);
852:   SectionRealGetSection(section, s);
853:   MeshCreateGlobalScatter(m, s, scatter);
854:   return(0);
855: }

859: PetscErrorCode  MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
860: {

866:   if (!mesh->globalScatter) {
867:     SectionReal section;

869:     MeshGetSectionReal(mesh, "default", &section);
870:     MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
871:     SectionRealDestroy(section);
872:   }
873:   *scatter = mesh->globalScatter;
874:   return(0);
875: }

879: PetscErrorCode  MeshGetLocalFunction(Mesh mesh, PetscErrorCode (**lf)(Mesh, SectionReal, SectionReal, void *))
880: {
883:   if (lf) *lf = mesh->lf;
884:   return(0);
885: }

889: PetscErrorCode  MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
890: {
893:   mesh->lf = lf;
894:   return(0);
895: }

899: PetscErrorCode  MeshGetLocalJacobian(Mesh mesh, PetscErrorCode (**lj)(Mesh, SectionReal, Mat, void *))
900: {
903:   if (lj) *lj = mesh->lj;
904:   return(0);
905: }

909: PetscErrorCode  MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
910: {
913:   mesh->lj = lj;
914:   return(0);
915: }

919: PetscErrorCode  MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
920: {

927:   if (mesh->lf) {
928:     (*mesh->lf)(mesh, X, F, ctx);
929:   }
930:   return(0);
931: }

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

943:   if (mesh->lj) {
944:     (*mesh->lj)(mesh, X, J, ctx);
945:   }
946:   return(0);
947: }

951: // Here we assume:
952: //  - Assumes 3D and tetrahedron
953: //  - The section takes values on vertices and is P1
954: //  - Points have the same dimension as the mesh
955: //  - All values have the same dimension
956: PetscErrorCode  MeshInterpolatePoints(Mesh mesh, SectionReal section, int numPoints, double *points, double **values)
957: {
958:   Obj<PETSC_MESH_TYPE> m;
959:   Obj<PETSC_MESH_TYPE::real_section_type> s;
960:   double        *v0, *J, *invJ, detJ;

964:   MeshGetMesh(mesh, m);
965:   SectionRealGetSection(section, s);
966:   const Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
967:   int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
968:   int dim      = s->getFiberDimension(*m->depthStratum(0)->begin());

970:   PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
971:   PetscMalloc(numPoints*dim * sizeof(double), &values);
972:   for(int p = 0; p < numPoints; p++) {
973:     double *point = &points[p*embedDim];
974: 
975:     PETSC_MESH_TYPE::point_type e = m->locatePoint(point);
976:     const PETSC_MESH_TYPE::real_section_type::value_type *coeff = s->restrictPoint(e);

978:     m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
979:     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;
980:     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;
981:     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;

983:     for(int d = 0; d < dim; d++) {
984:       (*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;
985:     }
986:   }
987:   PetscFree3(v0, J, invJ);
988:   return(0);
989: }

993: /*@C
994:   MeshGetMaximumDegree - Return the maximum degree of any mesh vertex

996:   Collective on mesh

998:   Input Parameter:
999: . mesh - The Mesh

1001:   Output Parameter:
1002: . maxDegree - The maximum number of edges at any vertex

1004:    Level: beginner

1006: .seealso: MeshCreate()
1007: @*/
1008: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
1009: {
1010:   Obj<PETSC_MESH_TYPE> m;

1014:   MeshGetMesh(mesh, m);
1015:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& vertices = m->depthStratum(0);
1016:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type>&     sieve    = m->getSieve();
1017:   PetscInt                                          maxDeg   = -1;

1019:   for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
1020:     maxDeg = PetscMax(maxDeg, (PetscInt) sieve->getSupportSize(*v_iter));
1021:   }
1022:   *maxDegree = maxDeg;
1023:   return(0);
1024: }

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

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

1033:   Collective on g

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

1042:    Level: beginner

1044: .seealso: MatSetOption()
1045: @*/
1046: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1047: {
1048:   VecScatter     injection;

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

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

1073:   Collective on g

1075:   Input Parameters:
1076: + g - The global vector
1077: . l - The local vector
1078: - mode - either ADD_VALUES or INSERT_VALUES, where
1079:    ADD_VALUES adds values to any existing entries, and
1080:    INSERT_VALUES replaces existing entries with new values

1082:    Level: beginner

1084: .seealso: MatSetOption()
1085: @*/
1086: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1087: {
1088:   VecScatter     injection;

1092:   PetscLogEventBegin(Mesh_assembleVectorComplete,0,0,0,0);
1093:   PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1094:   if (injection) {
1095:     VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1096:     VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1097:   } else {
1098:     if (mode == INSERT_VALUES) {
1099:       VecCopy(l, g);
1100:     } else {
1101:       VecAXPY(g, 1.0, l);
1102:     }
1103:   }
1104:   PetscLogEventEnd(Mesh_assembleVectorComplete,0,0,0,0);
1105:   return(0);
1106: }

1110: /*@C
1111:   assembleVector - Insert values into a vector

1113:   Collective on A

1115:   Input Parameters:
1116: + b - the vector
1117: . e - The element number
1118: . v - The values
1119: - mode - either ADD_VALUES or INSERT_VALUES, where
1120:    ADD_VALUES adds values to any existing entries, and
1121:    INSERT_VALUES replaces existing entries with new values

1123:    Level: beginner

1125: .seealso: VecSetOption()
1126: @*/
1127: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1128: {
1129:   Mesh           mesh;
1130:   SectionReal    section;

1134:   PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1135:   MeshGetSectionReal(mesh, "x", &section);
1136:   assembleVector(b, mesh, section, e, v, mode);
1137:   SectionRealDestroy(section);
1138:   return(0);
1139: }

1141: PetscErrorCode assembleVector(Vec b, Mesh mesh, SectionReal section, PetscInt e, PetscScalar v[], InsertMode mode)
1142: {
1143:   ALE::Obj<PETSC_MESH_TYPE> m;
1144:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
1145:   PetscInt                  firstElement;
1146:   PetscErrorCode            ierr;

1149:   PetscLogEventBegin(Mesh_assembleVector,0,0,0,0);
1150:   MeshGetMesh(mesh, m);
1151:   SectionRealGetSection(section, s);
1152:   //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1153:   firstElement = 0;
1154: #ifdef PETSC_USE_COMPLEX
1155:   SETERRQ(PETSC_ERR_SUP, "SectionReal does not support complex update");
1156: #else
1157:   if (mode == INSERT_VALUES) {
1158:     m->update(s, PETSC_MESH_TYPE::point_type(e + firstElement), v);
1159:   } else {
1160:     m->updateAdd(s, PETSC_MESH_TYPE::point_type(e + firstElement), v);
1161:   }
1162: #endif
1163:   PetscLogEventEnd(Mesh_assembleVector,0,0,0,0);
1164:   return(0);
1165: }

1169: 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)
1170: {
1172: #ifdef PETSC_OPT_SIEVE
1173:   typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
1174:   visitor_type iV(*section, *globalOrder, (int) pow((double) m->getSieve()->getMaxConeSize(), m->depth())*m->getMaxDof(), m->depth() > 1);

1176:   PetscErrorCode updateOperator(A, *m->getSieve(), iV, e, array, mode);
1177: #else
1178:   const PETSC_MESH_TYPE::indices_type indicesBlock = m->getIndices(section, e, globalOrder);
1179:   const PetscInt *indices    = indicesBlock.first;
1180:   const int&      numIndices = indicesBlock.second;
1181:   PetscErrorCode  ierr;

1183:   PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1184:   if (section->debug()) {
1185:     printf("[%d]mat for element %d\n", section->commRank(), e);
1186:     for(int i = 0; i < numIndices; i++) {
1187:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1188:     }
1189:     for(int i = 0; i < numIndices; i++) {
1190:       printf("[%d]", section->commRank());
1191:       for(int j = 0; j < numIndices; j++) {
1192:         printf(" %g", array[i*numIndices+j]);
1193:       }
1194:       printf("\n");
1195:     }
1196:   }
1197:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1198:   if (ierr) {
1199:     printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
1200:     for(int i = 0; i < numIndices; i++) {
1201:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1202:     }
1203: 
1204:   }
1205:   PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1206: #endif
1207:   return(0);
1208: }

1212: 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)
1213: {
1214: #ifdef PETSC_OPT_SIEVE
1215:   SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1216: #else
1217:   const int *offsets, *indices;

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

1224:   PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1225:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1226:   if (ierr) {
1227:     printf("[%d]ERROR in updateOperator: tag %d point num %d\n", section->commRank(), tag, p);
1228:     for(int i = 0; i < numIndices; i++) {
1229:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1230:     }
1231: 
1232:   }
1233:   PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1234: #endif
1235:   return(0);
1236: }

1240: 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)
1241: {
1242: #ifdef PETSC_OPT_SIEVE
1243:   typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
1244:   visitor_type iVr(*rowSection, *rowGlobalOrder, (int) pow((double) rowM->getSieve()->getMaxConeSize(), rowM->depth())*rowM->getMaxDof(), rowM->depth() > 1);
1245:   visitor_type iVc(*colSection, *colGlobalOrder, (int) pow((double) colM->getSieve()->getMaxConeSize(), colM->depth())*colM->getMaxDof(), colM->depth() > 1);

1247:   PetscErrorCode updateOperator(A, *rowM->getSieve(), iVr, rowE, *colM->getSieve(), iVc, colE, array, mode);
1248: #else

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

1254:   const PetscInt *tmpIndices    = rowIndicesBlock.first;
1255:   const int       numRowIndices = rowIndicesBlock.second;
1256:   PetscInt       *rowIndices    = new PetscInt[numRowIndices];
1257:   PetscMemcpy(rowIndices, tmpIndices, numRowIndices*sizeof(PetscInt));

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

1261:   const PetscInt *colIndices    = colIndicesBlock.first;
1262:   const int      numColIndices = colIndicesBlock.second;

1264:   PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1265:   if (rowSection->debug()) {
1266:     printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1267:     for(int i = 0; i < numRowIndices; i++) {
1268:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1269:     }
1270:   }
1271:   if (colSection->debug()) {
1272:     for(int i = 0; i < numColIndices; i++) {
1273:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1274:     }
1275:     for(int i = 0; i < numRowIndices; i++) {
1276:       printf("[%d]", rowSection->commRank());
1277:       for(int j = 0; j < numColIndices; j++) {
1278:         printf(" %g", array[i*numColIndices+j]);
1279:       }
1280:       printf("\n");
1281:     }
1282:   }
1283:   MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1284:   if (ierr) {
1285:     printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1286:     for(int i = 0; i < numRowIndices; i++) {
1287:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1288:     }
1289:     for(int i = 0; i < numColIndices; i++) {
1290:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1291:     }
1292: 
1293:   }
1294:   PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1295:   delete [] rowIndices;
1296: #endif
1297:   return(0);
1298: }

1302: /*@
1303:   MeshSetMaxDof - Sets the maximum number of degrees of freedom on any sieve point

1305:   Collective on A

1307:   Input Parameters:
1308: + A - the matrix
1309: . mesh - Mesh needed for orderings
1310: . section - A Section which describes the layout
1311: . e - The element number
1312: . v - The values
1313: - mode - either ADD_VALUES or INSERT_VALUES, where
1314:    ADD_VALUES adds values to any existing entries, and
1315:    INSERT_VALUES replaces existing entries with new values

1317:    Notes: This is used by routines like updateOperator() to bound buffer sizes

1319:    Level: developer

1321: .seealso: updateOperator(), assembleMatrix()
1322: @*/
1323: PetscErrorCode MeshSetMaxDof(Mesh mesh, PetscInt maxDof)
1324: {
1325:   Obj<PETSC_MESH_TYPE> m;
1326:   PetscErrorCode       ierr;

1329:   MeshGetMesh(mesh, m);
1330:   m->setMaxDof(maxDof);
1331:   return(0);
1332: }

1336: /*@
1337:   assembleMatrix - Insert values into a matrix

1339:   Collective on A

1341:   Input Parameters:
1342: + A - the matrix
1343: . mesh - Mesh needed for orderings
1344: . section - A Section which describes the layout
1345: . e - The element
1346: . v - The values
1347: - mode - either ADD_VALUES or INSERT_VALUES, where
1348:    ADD_VALUES adds values to any existing entries, and
1349:    INSERT_VALUES replaces existing entries with new values

1351:    Level: beginner

1353: .seealso: MatSetOption()
1354: @*/
1355: PetscErrorCode assembleMatrix(Mat A, Mesh mesh, SectionReal section, PetscInt e, PetscScalar v[], InsertMode mode)
1356: {

1360:   PetscLogEventBegin(Mesh_assembleMatrix,0,0,0,0);
1361:   try {
1362:     Obj<PETSC_MESH_TYPE> m;
1363:     Obj<PETSC_MESH_TYPE::real_section_type> s;

1365:     MeshGetMesh(mesh, m);
1366:     SectionRealGetSection(section, s);
1367:     const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, s->getName(), s);

1369:     if (m->debug()) {
1370:       std::cout << "Assembling matrix for element number " << e << " --> point " << e << std::endl;
1371:     }
1372:     updateOperator(A, m, s, globalOrder, e, v, mode);
1373:   } catch (ALE::Exception e) {
1374:     std::cout << e.msg() << std::endl;
1375:   }
1376:   PetscLogEventEnd(Mesh_assembleMatrix,0,0,0,0);
1377:   return(0);
1378: }

1382: 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)
1383: {
1384: #ifdef PETSC_OPT_SIEVE
1385:   SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1386: #else
1387:   PetscInt       localSize = globalOrder->getLocalSize();
1388:   PetscInt      *dnz, *onz;

1392:   PetscMalloc2(localSize, PetscInt, &dnz, localSize, PetscInt, &onz);
1393:   preallocateOperator(mesh, bs, atlas, globalOrder, dnz, onz, A);
1394:   PetscFree2(dnz, onz);
1395:   return(0);
1396: #endif
1397: }

1399: /******************************** C Wrappers **********************************/

1403: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1404: {
1405:   return VTKViewer::writeHeader(viewer);
1406: }

1410: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1411: {
1412:   ALE::Obj<PETSC_MESH_TYPE> m;

1415:   MeshGetMesh(mesh, m);
1416:   return VTKViewer::writeVertices(m, viewer);
1417: }

1421: PetscErrorCode WriteVTKElements(Mesh mesh, PetscViewer viewer)
1422: {
1423:   ALE::Obj<PETSC_MESH_TYPE> m;

1426:   MeshGetMesh(mesh, m);
1427:   return VTKViewer::writeElements(m, viewer);
1428: }

1432: PetscErrorCode WritePCICEVertices(Mesh mesh, PetscViewer viewer)
1433: {
1434:   ALE::Obj<PETSC_MESH_TYPE> m;

1437:   MeshGetMesh(mesh, m);
1438:   return ALE::PCICE::Viewer::writeVertices(m, viewer);
1439: }

1443: PetscErrorCode WritePCICEElements(Mesh mesh, PetscViewer viewer)
1444: {
1445:   ALE::Obj<PETSC_MESH_TYPE> m;

1448:   MeshGetMesh(mesh, m);
1449:   return ALE::PCICE::Viewer::writeElements(m, viewer);
1450: }

1454: PetscErrorCode WritePCICERestart(Mesh mesh, PetscViewer viewer)
1455: {
1456:   ALE::Obj<PETSC_MESH_TYPE> m;

1459:   MeshGetMesh(mesh, m);
1460:   return ALE::PCICE::Viewer::writeRestart(m, viewer);
1461: }

1465: /*@C
1466:   MeshCreatePCICE - Create a Mesh from PCICE files.

1468:   Not Collective

1470:   Input Parameters:
1471: + dim - The topological mesh dimension
1472: . coordFilename - The file containing vertex coordinates
1473: . adjFilename - The file containing the vertices for each element
1474: . interpolate - The flag for construction of intermediate elements
1475: . bcFilename - The file containing the boundary topology and conditions
1476: . numBdFaces - The number of boundary faces (or edges)
1477: - numBdVertices - The number of boundary vertices

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

1482:   Level: beginner

1484: .keywords: mesh, PCICE
1485: .seealso: MeshCreate()
1486: @*/
1487: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], 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::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1499:     if (debug) {m->view("Mesh");}
1500:   } catch(ALE::Exception e) {
1501:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1502:   }
1503:   if (bcFilename) {
1504:     ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1505:   }
1506:   MeshSetMesh(*mesh, m);
1507:   return(0);
1508: }

1512: /*@C
1513:   MeshCreatePyLith - Create a Mesh from PyLith files.

1515:   Not Collective

1517:   Input Parameters:
1518: + dim - The topological mesh dimension
1519: . baseFilename - The basename for mesh files
1520: . zeroBase - Use 0 to start numbering
1521: - interpolate - The flag for mesh interpolation

1523:   Output Parameter:
1524: . mesh - The Mesh object

1526:   Level: beginner

1528: .keywords: mesh, PCICE
1529: .seealso: MeshCreate()
1530: @*/
1531: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1532: {
1533:   ALE::Obj<PETSC_MESH_TYPE> m;
1534:   PetscInt            debug = 0;
1535:   PetscTruth          flag;
1536:   PetscErrorCode      ierr;

1539:   MeshCreate(comm, mesh);
1540:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1541:   try {
1542:     m  = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1543:   } catch(ALE::Exception e) {
1544:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1545:   }
1546:   MeshSetMesh(*mesh, m);
1547:   return(0);
1548: }

1552: /*@C
1553:   MeshGetCoordinates - Creates an array holding the coordinates.

1555:   Not Collective

1557:   Input Parameter:
1558: + mesh - The Mesh object
1559: - columnMajor - Flag for column major order

1561:   Output Parameter:
1562: + numVertices - The number of vertices
1563: . dim - The embedding dimension
1564: - coords - The array holding local coordinates

1566:   Level: intermediate

1568: .keywords: mesh, coordinates
1569: .seealso: MeshCreate()
1570: @*/
1571: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1572: {
1573:   ALE::Obj<PETSC_MESH_TYPE> m;
1574:   PetscErrorCode      ierr;

1577:   MeshGetMesh(mesh, m);
1578:   ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1579:   return(0);
1580: }

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

1587:   Not Collective

1589:   Input Parameters:
1590: + mesh - The Mesh object
1591: - columnMajor - Flag for column major order

1593:   Output Parameters:
1594: + numElements - The number of elements
1595: . numCorners - The number of vertices per element
1596: - vertices - The array holding vertices on each local element

1598:   Level: intermediate

1600: .keywords: mesh, elements
1601: .seealso: MeshCreate()
1602: @*/
1603: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1604: {
1605:   ALE::Obj<PETSC_MESH_TYPE> m;
1606:   PetscErrorCode      ierr;

1609:   MeshGetMesh(mesh, m);
1610:   ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1611:   return(0);
1612: }

1616: /*@C
1617:   MeshGetCone - Creates an array holding the cone of a given point

1619:   Not Collective

1621:   Input Parameters:
1622: + mesh - The Mesh object
1623: - p - The mesh point

1625:   Output Parameters:
1626: + numPoints - The number of points in the cone
1627: - points - The array holding the cone points

1629:   Level: intermediate

1631: .keywords: mesh, cone
1632: .seealso: MeshCreate()
1633: @*/
1634: PetscErrorCode MeshGetCone(Mesh mesh, PetscInt p, PetscInt *numPoints, PetscInt *points[])
1635: {
1636:   ALE::Obj<PETSC_MESH_TYPE> m;
1637:   PetscErrorCode      ierr;

1640:   MeshGetMesh(mesh, m);
1641:   *numPoints = m->getSieve()->getConeSize(p);
1642:   ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type> v(*numPoints);

1644:   m->getSieve()->cone(p, v);
1645:   *points = const_cast<PetscInt*>(v.getPoints());
1646:   return(0);
1647: }

1651: /*@C
1652:   MeshDistribute - Distributes the mesh and any associated sections.

1654:   Not Collective

1656:   Input Parameter:
1657: + serialMesh  - The original Mesh object
1658: - partitioner - The partitioning package, or NULL for the default

1660:   Output Parameter:
1661: . parallelMesh - The distributed Mesh object

1663:   Level: intermediate

1665: .keywords: mesh, elements

1667: .seealso: MeshCreate(), MeshDistributeByFace()
1668: @*/
1669: PetscErrorCode MeshDistribute(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1670: {
1671:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1672:   PetscErrorCode      ierr;

1675:   MeshGetMesh(serialMesh, oldMesh);
1676:   MeshCreate(oldMesh->comm(), parallelMesh);
1677: #ifdef PETSC_OPT_SIEVE
1678:   const Obj<PETSC_MESH_TYPE>             newMesh  = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->getDimension(), oldMesh->debug());
1679:   const Obj<PETSC_MESH_TYPE::sieve_type> newSieve = new PETSC_MESH_TYPE::sieve_type(oldMesh->comm(), oldMesh->debug());

1681:   newMesh->setSieve(newSieve);
1682:   PetscPrintf(oldMesh->comm(), "Starting Mesh Distribution");
1683:   ALE::DistributionNew<PETSC_MESH_TYPE>::distributeMeshAndSectionsV(oldMesh, newMesh);
1684:   MeshSetMesh(*parallelMesh, newMesh);
1685:   PetscPrintf(oldMesh->comm(), "Ending Mesh Distribution");
1686: #else
1687:   if (partitioner == NULL) {
1688:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh);
1689:     MeshSetMesh(*parallelMesh, newMesh);
1690:   } else {
1691:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 0, partitioner);
1692:     MeshSetMesh(*parallelMesh, newMesh);
1693:   }
1694: #endif
1695:   return(0);
1696: }

1700: /*@C
1701:   MeshDistribute - Distributes the mesh and any associated sections.

1703:   Not Collective

1705:   Input Parameter:
1706: + serialMesh  - The original Mesh object
1707: - partitioner - The partitioning package, or NULL for the default

1709:   Output Parameter:
1710: . parallelMesh - The distributed Mesh object

1712:   Level: intermediate

1714: .keywords: mesh, elements

1716: .seealso: MeshCreate(), MeshDistribute()
1717: @*/
1718: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1719: {
1720:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1721:   PetscErrorCode      ierr;

1724:   MeshGetMesh(serialMesh, oldMesh);
1725:   MeshCreate(oldMesh->comm(), parallelMesh);
1726: #ifdef PETSC_OPT_SIEVE
1727:   SETERRQ(PETSC_ERR_SUP, "I am being lazy, bug me.");
1728: #else
1729:   if (partitioner == NULL) {
1730:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1);
1731:     MeshSetMesh(*parallelMesh, newMesh);
1732:   } else {
1733:     ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1, partitioner);
1734:     MeshSetMesh(*parallelMesh, newMesh);
1735:   }
1736: #endif
1737:   return(0);
1738: }

1742: /*@C
1743:   MeshGenerate - Generates a mesh.

1745:   Not Collective

1747:   Input Parameters:
1748: + boundary - The Mesh boundary object
1749: - interpolate - Flag to create intermediate mesh elements

1751:   Output Parameter:
1752: . mesh - The Mesh object

1754:   Level: intermediate

1756: .keywords: mesh, elements
1757: .seealso: MeshCreate(), MeshRefine()
1758: @*/
1759: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1760: {
1761:   ALE::Obj<PETSC_MESH_TYPE> mB;
1762:   PetscErrorCode      ierr;

1765:   MeshGetMesh(boundary, mB);
1766:   MeshCreate(mB->comm(), mesh);
1767: #ifdef PETSC_OPT_SIEVE
1768:   ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMeshV(mB, interpolate);
1769: #else
1770:   ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMesh(mB, interpolate);
1771: #endif
1772:   MeshSetMesh(*mesh, m);
1773:   return(0);
1774: }

1778: /*@C
1779:   MeshRefine - Refines the mesh.

1781:   Not Collective

1783:   Input Parameters:
1784: + mesh - The original Mesh object
1785: . refinementLimit - The maximum size of any cell
1786: - interpolate - Flag to create intermediate mesh elements

1788:   Output Parameter:
1789: . refinedMesh - The refined Mesh object

1791:   Level: intermediate

1793: .keywords: mesh, elements
1794: .seealso: MeshCreate(), MeshGenerate()
1795: @*/
1796: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1797: {
1798:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1799:   PetscErrorCode      ierr;

1802:   MeshGetMesh(mesh, oldMesh);
1803:   MeshCreate(oldMesh->comm(), refinedMesh);
1804: #ifdef PETSC_OPT_SIEVE
1805:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, interpolate);
1806: #else
1807:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, interpolate);
1808: #endif
1809:   MeshSetMesh(*refinedMesh, newMesh);
1810:   return(0);
1811: }

1815: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1816: {
1817:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1818:   double              refinementLimit;
1819:   PetscErrorCode      ierr;

1822:   MeshGetMesh(mesh, oldMesh);
1823:   MeshCreate(comm, refinedMesh);
1824:   refinementLimit = oldMesh->getMaxVolume()/2.0;
1825: #ifdef PETSC_OPT_SIEVE
1826:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, true);
1827: #else
1828:   ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, true);
1829: #endif
1830:   MeshSetMesh(*refinedMesh, newMesh);
1831: #ifndef PETSC_OPT_SIEVE
1832:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");
1833:   const Obj<std::set<std::string> >& discs = oldMesh->getDiscretizations();

1835:   for(std::set<std::string>::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter) {
1836:     newMesh->setDiscretization(*f_iter, oldMesh->getDiscretization(*f_iter));
1837:   }
1838:   newMesh->setupField(s);
1839: #endif
1840:   return(0);
1841: }

1843: #ifndef PETSC_OPT_SIEVE

1845: #include "Hierarchy_New.hh"



1851: #include "Hierarchy.hh"

1855: /*@C
1856:   MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.

1858:   Not Collective

1860:   Input Parameters:
1861: + mesh - The original Mesh object
1862: . numLevels - The number of 
1863: . coarseningFactor - The expansion factor for coarse meshes
1864: - interpolate - Flag to create intermediate mesh elements

1866:   Output Parameter:
1867: . coarseHierarchy - The coarse Mesh objects

1869:   Level: intermediate

1871: .keywords: mesh, elements
1872: .seealso: MeshCreate(), MeshGenerate()
1873: @*/
1874: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh *coarseHierarchy)
1875: {
1876:   ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1877:   PetscErrorCode      ierr;

1880:   if (numLevels < 1) {
1881:     *coarseHierarchy = PETSC_NULL;
1882:     return(0);
1883:   }
1884:   MeshGetMesh(mesh, oldMesh);
1885:   for (int i = 0; i < numLevels; i++) {
1886:     MeshCreate(oldMesh->comm(), &coarseHierarchy[i]);
1887:   }
1888:   MeshSpacingFunction(mesh);
1889:   MeshCreateHierarchyLabel_Link(mesh, coarseningFactor, numLevels+1, coarseHierarchy);
1890: 
1891: #if 0
1892:   if (oldMesh->getDimension() != 2) SETERRQ(PETSC_ERR_SUP, "Coarsening only works in two dimensions right now");
1893:   ALE::Coarsener::IdentifyBoundary(oldMesh, 2);
1894:   ALE::Coarsener::make_coarsest_boundary(oldMesh, 2, numLevels+1);
1895:   ALE::Coarsener::CreateSpacingFunction(oldMesh, 2);
1896:   ALE::Coarsener::CreateCoarsenedHierarchyNew(oldMesh, 2, numLevels, coarseningFactor);
1897:   PetscMalloc(numLevels * sizeof(Mesh),coarseHierarchy);
1898:   for(int l = 0; l < numLevels; l++) {
1899:     ALE::Obj<PETSC_MESH_TYPE> newMesh = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->debug());
1900:     const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");

1902:     MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1903:     newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1904:     newMesh->setDiscretization(oldMesh->getDiscretization());
1905:     newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1906:     newMesh->setupField(s);
1907:     MeshSetMesh((*coarseHierarchy)[l], newMesh);
1908:   }
1909: #endif
1910:   return(0);
1911: }

1913: #endif

1915: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh *coarseHierarchy)
1916: {
1918:   double cfactor = 1.5;
1920:   PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1921: #ifdef PETSC_OPT_SIEVE
1922:   SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
1923: #else
1924:   MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1925: #endif
1926:   return(0);
1927: }

1929: #if 0


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

1936: PetscErrorCode MeshGetInterpolation_Mesh_General(Mesh coarse_mesh, Mesh fine_mesh, Mat *interpolation, Vec *scaling) {
1937:   ALE::Obj<PETSC_MESH_TYPE> fm, cm;
1938:   Mat                 P;
1939:   PetscErrorCode      ierr;
1940: 
1942:   //Stages:
1943:   //  1. Create a section on the fine mesh describing the location in the fine mesh of the assorted unknowns.
1944:   //  2. Fill in this section by traversing across the mesh via cones and supports, transforming the coordinates of the assorted functional points
1945:   //  3. Preallocate the matrix rows/columns
1946:   //  4. Assemble the matrix by writing evaluating each unknown as the point
1947:   MeshGetMesh(dmFine, fm);
1948:   MeshGetMesh(dmCoarse, cm);
1949:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
1950:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal   = fm->createLabel ("traversal");
1951:   const int                       debug           = fm->debug();
1952:   if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1953:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates   = fm->getRealSection("coordinates");
1954:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");

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

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

1962:   std::list<PETSC_MESH_TYPE::point_type> travlist;        // store point
1963:   std::list<PETSC_MESH_TYPE::point_type> travguesslist;   // store guess
1964:   std::list<PETSC_MESH_TYPE::point_type> eguesslist;      // store the next guesses for the location of the current point.

1966:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1967:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1968:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> covering_points = PETSC_MESH_TYPE::sieve_type::supportSet();

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

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

1976:   const ALE::Obj<PETSC_MESH_TYPE::int_section_type> & node_locations = fm->getIntSection("node_locations");
1977:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type> & fine_default = fm->getRealSection("default");
1978:   int total_dimension
1979:   for (int i = 0; i < dim; i++) {
1980:     const ALE::Obj<PETSC_MESH_TYPE::label_sequence> & present_level = fm->depthStratum(i);
1981:     int current_dimension = fine_default->getFiberDimension(*present_level->begin());
1982:     node_locations->setFiberDimension(present_level, current_dimension);
1983:   }
1984:   node_locations->allocate();
1985:   //traverse!

1987: 

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

1992:   PETSC_MESH_TYPE::label_sequence::iterator fc_iter = fine_cells->begin();
1993:   PETSC_MESH_TYPE::label_sequence::iterator fc_iter_end = fine_cells->end();
1994:   while (fc_iter != fc_iter_end) {
1995:     //locate an initial coarse cell that overlaps with this fine cell in terms of their bounding boxes;
1996:     PETSC_MESH_TYPE::label_sequence::iterator cc_iter = coarse_cells->begin();
1997:     PETSC_MESH_TYPE::label_sequence::iterator cc_iter_end = coarse_cells->end();
1998:     while (cc_iter != cc_iter_end) {
1999: 
2000:       cc_iter++;
2001:     }
2002:     fc_iter++;
2003:   }
2004: }

2006: #endif


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

2013: #ifdef PETSC_OPT_SIEVE
2014:   SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
2015: #else
2016:   ALE::Obj<PETSC_MESH_TYPE> fm, cm;
2017:   Mat                 P;
2018:   PetscErrorCode      ierr;

2021:   MeshGetMesh(dmFine, fm);
2022:   MeshGetMesh(dmCoarse, cm);
2023:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
2024:   //  ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal   = fm->createLabel ("traversal");
2025:   const int                       debug           = fm->debug();
2026:   if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
2027:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates   = fm->getRealSection("coordinates");
2028:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
2029:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse           = cm->getRealSection("default");
2030:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine             = fm->getRealSection("default");
2031:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        coarseOrder       = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
2032:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        fineOrder         = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
2033:   std::list<PETSC_MESH_TYPE::point_type> travlist;        // store point
2034:   std::list<PETSC_MESH_TYPE::point_type> travguesslist;   // store guess
2035:   std::list<PETSC_MESH_TYPE::point_type> eguesslist;      // store the next guesses for the location of the current point.
2036:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
2037:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
2038:   const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> uncorrected_points = PETSC_MESH_TYPE::sieve_type::supportSet();
2039:   static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
2040:   if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}

2042:   MatCreate(fm->comm(), &P);
2043:   MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2044:   MatSeqAIJSetPreallocation(P,10,PETSC_NULL);
2045:   MatSetFromOptions(P);

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

2052:   //traversal labels on both layers
2053:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& finevertices = fm->depthStratum(0);
2054:   const PETSC_MESH_TYPE::label_sequence::iterator  fv_iter_end  = finevertices->end();
2055:   PETSC_MESH_TYPE::label_sequence::iterator        fv_iter      = finevertices->begin();

2057:   //  while (fv_iter != fv_iter_end) {
2058:   //    fm->setValue(finetraversal, *fv_iter, 0);
2059:   //    fv_iter++;
2060:   //  }

2062:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& coarseelements = cm->heightStratum(0);
2063:   const PETSC_MESH_TYPE::label_sequence::iterator  ce_iter_end    = coarseelements->end();
2064:   PETSC_MESH_TYPE::label_sequence::iterator        ce_iter        = coarseelements->begin();
2065: 
2066:   //  while (ce_iter != ce_iter_end) {
2067:   //    cm->setValue(coarsetraversal, *ce_iter, 0);
2068:   //    ce_iter++;
2069:   //  }

2071:   double *fvCoords = new double[dim], *nvCoords = new double[dim];
2072:   bool pointIsInElement;

2074:   if (debug) {PetscPrintf(fm->comm(), "starting iterations\n");}
2075:   fv_iter = finevertices->begin();
2076:   while (fv_iter != fv_iter_end) {
2077:     // locate an initial point.
2078:     //    if (fm->getValue(finetraversal, *fv_iter) == 0) {
2079:     if ((fine_traversal->find(*fv_iter) == fine_traversal->end()) && (uncorrected_points->find(*fv_iter) == uncorrected_points->end())) {
2080:       bool isLocated = false;

2082:       ce_iter = coarseelements->begin();
2083:       PetscMemcpy(fvCoords, finecoordinates->restrictPoint(*fv_iter), dim*sizeof(double));
2084:       while ((ce_iter != ce_iter_end) && (!isLocated)) {
2085:         cm->computeElementGeometry(coarsecoordinates, *ce_iter, v0, J, invJ, detJ);
2086:         // generalized simplicial location for 2D, 3D:
2087:         loc[0] = 1.0;
2088:         pointIsInElement = true;
2089:         for(int i = 0; i < dim; i++) {
2090:           loc[i+1] = 0.0;
2091:           for(int j = 0; j < dim; j++) {
2092:             loc[i+1] += 0.5*invJ[i*dim+j]*(fvCoords[j] - v0[j]);
2093:           }
2094:           loc[0] -= loc[i+1];
2095:           //PetscPrintf(fm->comm(), "%f, ", loc[i+1]);
2096:           if (loc[i+1] < -0.000000000001) pointIsInElement = false;
2097:         }
2098:         //PetscPrintf(fm->comm(), "%f\n", loc[0]);
2099:         if (loc[0] < -0.000000000001) pointIsInElement = false;
2100:         if (pointIsInElement) {
2101:           //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2102:           //PetscPrintf(fm->comm(), "located by guess.\n");
2103:           isLocated = true;
2104:           updateOperatorGeneral(P, fm, sFine, fineOrder, *fv_iter, cm, sCoarse, coarseOrder, *ce_iter, loc, INSERT_VALUES);
2105:           //fm->setValue(finetraversal, *fv_iter, 1);
2106:           fine_traversal->insert(*fv_iter);
2107:           const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> & neighbors  = fm->getSieve()->cone(fm->getSieve()->support(*fv_iter));
2108:           const PETSC_MESH_TYPE::sieve_type::coneSet::iterator n_iter_end = neighbors->end();
2109:           PETSC_MESH_TYPE::sieve_type::coneSet::iterator       n_iter     = neighbors->begin();
2110:           while (n_iter != n_iter_end) {
2111:             //            if (fm->getValue(finetraversal, *n_iter) == 0) {
2112:             if (fine_traversal->find(*n_iter) != fine_traversal->end()) {
2113:               travlist.push_back(*n_iter);
2114:               //              fm->setValue(finetraversal, *n_iter, 1);
2115:               fine_traversal->insert(*n_iter);
2116:               travguesslist.push_back(*ce_iter);
2117:             }
2118:             n_iter++;
2119:           }
2120:           //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.
2121:           while (!travlist.empty()) {
2122:             PETSC_MESH_TYPE::point_type curVert = *travlist.begin();
2123:             PetscMemcpy(nvCoords, finecoordinates->restrictPoint(curVert), dim*sizeof(double));
2124:             PETSC_MESH_TYPE::point_type curEle =  *travguesslist.begin();
2125:             travlist.pop_front();
2126:             travguesslist.pop_front();
2127:             eguesslist.push_front(curEle);
2128:             //cm->setValue(coarsetraversal, curEle, 1);
2129:             coarse_traversal->insert(curEle);
2130:             bool locationDiscovered  = false;
2131:             //int traversalcomparisons = 0;
2132:             while ((!eguesslist.empty()) && (!locationDiscovered) && (int)coarse_traversal->size() < maxComparisons) {
2133:               //traversalcomparisons = 0;
2134:               PETSC_MESH_TYPE::point_type curguess = *eguesslist.begin();
2135:               eguesslist.pop_front();
2136:               pointIsInElement = true;
2137:               cm->computeElementGeometry(coarsecoordinates, curguess, v0, J, invJ, detJ);
2138:               loc[0] = 1.0;
2139:               for(int i = 0; i < dim; i++) {
2140:                 loc[i+1] = 0.0;
2141:                 for(int j = 0; j < dim; j++) {
2142:                   loc[i+1] += 0.5*invJ[i*dim+j]*(nvCoords[j] - v0[j]);
2143:                 }
2144:                 loc[0] -= loc[i+1];
2145:                 if (loc[i+1] < -0.00000000001) pointIsInElement = false;
2146:               }
2147:               if (loc[0] < -0.00000000001) pointIsInElement = false;

2149:               if (pointIsInElement) {
2150:                 //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2151:                 locationDiscovered = true;
2152:                 //PetscPrintf(fm->comm(), "located by traversal.\n");
2153:                 //set the label.
2154:                 //fm->setValue(prolongation, curVert, curguess);
2155:                 updateOperatorGeneral(P, fm, sFine, fineOrder, curVert, cm, sCoarse, coarseOrder, curguess, loc, INSERT_VALUES);
2156:                 //PetscPrintf(fm->comm(), "Point %d located in %d.\n",  curVert, curguess);
2157:                 //stick its neighbors in the queue along with its location as a good guess of the location of its neighbors
2158:                 const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> newNeighbors = fm->getSieve()->cone(fm->getSieve()->support(curVert));
2159:                 const PETSC_MESH_TYPE::sieve_type::coneSet::iterator nn_iter_end  = newNeighbors->end();
2160:                 PETSC_MESH_TYPE::sieve_type::coneSet::iterator       nn_iter      = newNeighbors->begin();
2161:                 while (nn_iter != nn_iter_end) {
2162:                   //if (fm->getValue(finetraversal, *nn_iter) == 0) { //unlocated neighbor
2163:                   if (fine_traversal->find(*nn_iter) == fine_traversal->end()) {
2164:                     travlist.push_back(*nn_iter);
2165:                     travguesslist.push_back(curguess);
2166:                     //fm->setValue(finetraversal, *nn_iter, 1);
2167:                     fine_traversal->insert(*nn_iter);
2168:                   }
2169:                   nn_iter++;
2170:                 }
2171:               } else {
2172:               //add the current guesses neighbors to the comparison queue and start over.
2173:                 const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> & curguessneighbors = cm->getSieve()->support(cm->getSieve()->cone(curguess));
2174:                 const PETSC_MESH_TYPE::sieve_type::supportSet::iterator cgn_iter_end      = curguessneighbors->end();
2175:                 PETSC_MESH_TYPE::sieve_type::supportSet::iterator       cgn_iter          = curguessneighbors->begin();
2176:                 while (cgn_iter != cgn_iter_end) {
2177:                   //if (cm->getValue(coarsetraversal, *cgn_iter) == 0) {
2178:                   if (coarse_traversal->find(*cgn_iter) == coarse_traversal->end()) {
2179:                     eguesslist.push_back(*cgn_iter);
2180:                     //cm->setValue(coarsetraversal, *cgn_iter, 1);
2181:                     coarse_traversal->insert(*cgn_iter);
2182:                   }
2183:                   cgn_iter++;
2184:                 }
2185:               }
2186:             }
2187:             coarse_traversal->clear();
2188:             if (!locationDiscovered) {  //if a position for it is not discovered, it doesn't get corrected; complain
2189:               if (fm->debug())PetscPrintf(fm->comm(), "Point %d (%f, %f) not located.\n",  curVert, nvCoords[0], nvCoords[1]);
2190:               //fm->setValue(finetraversal, curVert, 2); //don't try again.
2191:               uncorrected_points->insert(curVert);
2192:             }
2193:             eguesslist.clear(); //we've discovered the location of the point or exhausted our possibilities on this contiguous block of elements.
2194:             //unset the traversed element list
2195:             //const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& traved_elements = cm->getLabelStratum("traversal", 1);
2196:             //const PETSC_MESH_TYPE::label_sequence::iterator  tp_iter_end     = traved_elements->end();
2197:             //PETSC_MESH_TYPE::label_sequence::iterator        tp_iter         = traved_elements->begin();
2198:             //PetscPrintf(cm->comm(), "%d\n", traved_elements->size());
2199:             //while (tp_iter != tp_iter_end) {
2200:             //  eguesslist.push_back(*tp_iter);
2201:             //  tp_iter++;
2202:             //}
2203:             //while (!eguesslist.empty()) {
2204:             //  cm->setValue(coarsetraversal, *eguesslist.begin(), 0);
2205:             //  eguesslist.pop_front();
2206:             //}
2207: 
2208:           }
2209:         }
2210:         ce_iter++;
2211:       }
2212:       if (!isLocated) {
2213:        if (fm->debug())PetscPrintf(fm->comm(), "NOT located\n");
2214:        //fm->setValue(finetraversal, *fv_iter, 2); //don't try again.
2215:        uncorrected_points->insert(*fv_iter);
2216:       }
2217:     }
2218:     // printf("-");
2219:     fv_iter++;
2220:   }
2221:   MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2222:   MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2223:   //MatView(P, PETSC_VIEWER_STDOUT_SELF);
2224:   delete [] fvCoords; delete [] nvCoords;
2225:   *interpolation = P;
2226:   if (debug) {PetscPrintf(fm->comm(), "Ending Interpolation Matrix Build\n");}
2227:   return(0);
2228: #endif
2229: }


2234: /*
2235:   This method only handle P_1 discretizations at present.
2236: */
2237: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
2238: {
2239: #ifdef PETSC_OPT_SIEVE
2240:   SETERRQ(PETSC_ERR_SUP, "This has been superceded.");
2241: #else
2242:   ALE::Obj<PETSC_MESH_TYPE> coarse;
2243:   ALE::Obj<PETSC_MESH_TYPE> fine;
2244:   Mat                 P;
2245:   PetscErrorCode      ierr;

2248:   MeshGetMesh(dmFine,   fine);
2249:   MeshGetMesh(dmCoarse, coarse);
2250:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
2251:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& fineCoordinates   = fine->getRealSection("coordinates");
2252:   const ALE::Obj<PETSC_MESH_TYPE::label_sequence>&    vertices          = fine->depthStratum(0);
2253:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse           = coarse->getRealSection("default");
2254:   const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine             = fine->getRealSection("default");
2255:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
2256:   const ALE::Obj<PETSC_MESH_TYPE::order_type>&        fineOrder   = fine->getFactory()->getGlobalOrder(fine, "default", sFine);

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

2262:   MatCreate(fine->comm(), &P);
2263:   MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2264:   MatSetFromOptions(P);
2265:   MatSeqAIJSetPreallocation(P, numDof, PETSC_NULL);
2266:   MatMPIAIJSetPreallocation(P, numDof, PETSC_NULL, numDof, PETSC_NULL);
2267:   PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
2268:   bool hasprolong;
2269:   if (fine->hasLabel("prolongation")) {
2270:     hasprolong = true;
2271:   } else {
2272:     hasprolong = false;
2273:     PetscPrintf(fine->comm(), "WARNING: Point Location Label Does Not Exist");
2274:   }
2275:   PETSC_MESH_TYPE::label_sequence::iterator v_iter_end = vertices->end();
2276:   PETSC_MESH_TYPE::real_section_type::value_type *coords = new PETSC_MESH_TYPE::real_section_type::value_type[dim];

2278:   for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != v_iter_end; ++v_iter) {
2279:     //const PETSC_MESH_TYPE::real_section_type::value_type *coords     = fineCoordinates->restrictPoint(*v_iter);
2280:     PetscMemcpy(coords, fineCoordinates->restrictPoint(*v_iter), dim*sizeof(double));
2281:     PETSC_MESH_TYPE::point_type coarseCell;
2282:     PETSC_MESH_TYPE::point_type cellguess = -1;
2283:     if (hasprolong) {
2284:       cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
2285:       coarseCell = coarse->locatePoint(coords, cellguess);
2286:     } else {
2287:       coarseCell = coarse->locatePoint(coords);
2288:     }
2289: //      coarseCell = coarse->locatePoint(coords);
2290:     if (coarseCell == -1) {
2291:      // do NO CORRECTION!
2292:     } else {
2293:       coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
2294:       for(int d = 0; d < dim; ++d) {
2295:         refCoords[d] = 0.0;
2296:         for(int e = 0; e < dim; ++e) {
2297:           refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
2298:         }
2299:         refCoords[d] -= 1.0;
2300:       }
2301:       values[0] = -(refCoords[0] + refCoords[1])/2.0;
2302:       values[1] = 0.5*(refCoords[0] + 1.0);
2303:       values[2] = 0.5*(refCoords[1] + 1.0);
2304:   //    PetscPrintf(fine->comm(), "%f, %f, %f\n", values[0], values[1], values[2]);
2305:       updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
2306:     }
2307:   }
2308:   PetscFree5(v0,J,invJ,refCoords,values);
2309:   MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2310:   MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2311:   delete [] coords;
2312:   *interpolation = P;
2313:   return(0);
2314: #endif
2315: }

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

2322:   Not Collective

2324:   Input Parameters:
2325: + mesh - The Mesh object
2326: - name - The section name

2328:   Output Parameter:
2329: . flag - True if the SectionReal is present in the Mesh

2331:   Level: intermediate

2333: .keywords: mesh, elements
2334: .seealso: MeshCreate()
2335: @*/
2336: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
2337: {
2338:   ALE::Obj<PETSC_MESH_TYPE> m;
2339:   PetscErrorCode      ierr;

2342:   MeshGetMesh(mesh, m);
2343:   *flag = (PetscTruth) m->hasRealSection(std::string(name));
2344:   return(0);
2345: }

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

2352:   Collective on Mesh

2354:   Input Parameters:
2355: + mesh - The Mesh object
2356: - name - The section name

2358:   Output Parameter:
2359: . section - The SectionReal

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

2363:   Level: intermediate

2365: .keywords: mesh, elements
2366: .seealso: MeshCreate()
2367: @*/
2368: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
2369: {
2370:   ALE::Obj<PETSC_MESH_TYPE> m;
2371:   bool                      has;
2372:   PetscErrorCode            ierr;

2375:   MeshGetMesh(mesh, m);
2376:   SectionRealCreate(m->comm(), section);
2377:   PetscObjectSetName((PetscObject) *section, name);
2378:   has  = m->hasRealSection(std::string(name));
2379:   SectionRealSetSection(*section, m->getRealSection(std::string(name)));
2380:   SectionRealSetBundle(*section, m);
2381: #ifdef PETSC_OPT_SIEVE
2382:   if (!has) {
2383:     m->getRealSection(std::string(name))->setChart(m->getSieve()->getChart());
2384:   }
2385: #endif
2386:   return(0);
2387: }

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

2394:   Collective on Mesh

2396:   Input Parameters:
2397: + mesh - The Mesh object
2398: - section - The SectionReal

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

2402:   Level: intermediate

2404: .keywords: mesh, elements
2405: .seealso: MeshCreate()
2406: @*/
2407: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
2408: {
2409:   ALE::Obj<PETSC_MESH_TYPE> m;
2410:   ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2411:   const char         *name;
2412:   PetscErrorCode      ierr;

2415:   MeshGetMesh(mesh, m);
2416:   PetscObjectGetName((PetscObject) section, &name);
2417:   SectionRealGetSection(section, s);
2418:   m->setRealSection(std::string(name), s);
2419:   return(0);
2420: }

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

2427:   Not Collective

2429:   Input Parameters:
2430: + mesh - The Mesh object
2431: - name - The section name

2433:   Output Parameter:
2434: . flag - True if the SectionInt is present in the Mesh

2436:   Level: intermediate

2438: .keywords: mesh, elements
2439: .seealso: MeshCreate()
2440: @*/
2441: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2442: {
2443:   ALE::Obj<PETSC_MESH_TYPE> m;
2444:   PetscErrorCode      ierr;

2447:   MeshGetMesh(mesh, m);
2448:   *flag = (PetscTruth) m->hasIntSection(std::string(name));
2449:   return(0);
2450: }

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

2457:   Collective on Mesh

2459:   Input Parameters:
2460: + mesh - The Mesh object
2461: - name - The section name

2463:   Output Parameter:
2464: . section - The SectionInt

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

2468:   Level: intermediate

2470: .keywords: mesh, elements
2471: .seealso: MeshCreate()
2472: @*/
2473: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2474: {
2475:   ALE::Obj<PETSC_MESH_TYPE> m;
2476:   bool                      has;
2477:   PetscErrorCode            ierr;

2480:   MeshGetMesh(mesh, m);
2481:   SectionIntCreate(m->comm(), section);
2482:   PetscObjectSetName((PetscObject) *section, name);
2483:   has  = m->hasIntSection(std::string(name));
2484:   SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2485:   SectionIntSetBundle(*section, m);
2486: #ifdef PETSC_OPT_SIEVE
2487:   if (!has) {
2488:     m->getIntSection(std::string(name))->setChart(m->getSieve()->getChart());
2489:   }
2490: #endif
2491:   return(0);
2492: }

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

2499:   Collective on Mesh

2501:   Input Parameters:
2502: + mesh - The Mesh object
2503: - section - The SectionInt

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

2507:   Level: intermediate

2509: .keywords: mesh, elements
2510: .seealso: MeshCreate()
2511: @*/
2512: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2513: {
2514:   ALE::Obj<PETSC_MESH_TYPE> m;
2515:   ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2516:   const char         *name;
2517:   PetscErrorCode      ierr;

2520:   MeshGetMesh(mesh, m);
2521:   PetscObjectGetName((PetscObject) section, &name);
2522:   SectionIntGetSection(section, s);
2523:   m->setIntSection(std::string(name), s);
2524:   return(0);
2525: }

2529: /*@C
2530:   SectionGetArray - Returns the array underlying the Section.

2532:   Not Collective

2534:   Input Parameters:
2535: + mesh - The Mesh object
2536: - name - The section name

2538:   Output Parameters:
2539: + numElements - The number of mesh element with values
2540: . fiberDim - The number of values per element
2541: - array - The array

2543:   Level: intermediate

2545: .keywords: mesh, elements
2546: .seealso: MeshCreate()
2547: @*/
2548: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2549: {
2550:   ALE::Obj<PETSC_MESH_TYPE> m;
2551:   PetscErrorCode      ierr;

2554:   MeshGetMesh(mesh, m);
2555:   const Obj<PETSC_MESH_TYPE::real_section_type>& section = m->getRealSection(std::string(name));
2556:   if (section->size() == 0) {
2557:     *numElements = 0;
2558:     *fiberDim    = 0;
2559:     *array       = NULL;
2560:     return(0);
2561:   }
2562:   const PETSC_MESH_TYPE::real_section_type::chart_type& chart = section->getChart();
2563: /*   const int                                  depth   = m->depth(*chart.begin()); */
2564: /*   *numElements = m->depthStratum(depth)->size(); */
2565: /*   *fiberDim    = section->getFiberDimension(*chart.begin()); */
2566: /*   *array       = (PetscScalar *) m->restrict(section); */
2567:   int fiberDimMin = section->getFiberDimension(*chart.begin());
2568:   int numElem     = 0;

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

2573:     if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2574:   }
2575:   for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2576:     const int fiberDim = section->getFiberDimension(*c_iter);

2578:     numElem += fiberDim/fiberDimMin;
2579:   }
2580:   *numElements = numElem;
2581:   *fiberDim    = fiberDimMin;
2582:   *array       = (PetscScalar *) section->restrictSpace();
2583:   return(0);
2584: }

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

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

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

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

2612: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2613: {
2614:   ALE::Obj<PETSC_MESH_TYPE> m;

2617:   MeshGetMesh(mesh, m);
2618:   return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2619: }

2623: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2624: {
2625:   ALE::Obj<PETSC_MESH_TYPE> m;
2626:   ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;

2629:   MeshGetMesh(mesh, m);
2630:   SectionIntGetSection(material, s);
2631:   return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2632: }

2634: #if 0
2637: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2638: {
2639:   ALE::Obj<PETSC_MESH_TYPE> m;

2642:   MeshGetMesh(mesh, m);
2643:   return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2644: }
2645: #endif

2649: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2650: {
2651:   const int end = interval.prefix + interval.index;
2652:   for(int i = interval.index; i < end; i++) {
2653:     indices[indx++] = i;
2654:   }
2655: }

2659: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2660: {
2661:   for(int i = 0; i < interval.prefix; i++) {
2662:     indices[(*indx)++] = interval.index + i;
2663:   }
2664:   for(int i = 0; i < -interval.prefix; i++) {
2665:     indices[(*indx)++] = -1;
2666:   }
2667: }