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 = 0;
  7: PetscEvent  Mesh_View = 0, Mesh_GetGlobalScatter = 0, Mesh_restrictVector = 0, Mesh_assembleVector = 0,
  8:             Mesh_assembleVectorComplete = 0, Mesh_assembleMatrix = 0, Mesh_updateOperator = 0;

 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 *);

 19: EXTERN PetscErrorCode updateOperatorCompat(Mat, const ALE::Obj<ALECompat::Mesh::real_section_type>&, const ALE::Obj<ALECompat::Mesh::order_type>&, const ALECompat::Mesh::point_type&, PetscScalar[], InsertMode);

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

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


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

 42: PetscErrorCode MeshFinalize()
 43: {
 45:   ALE::Mesh::NumberingFactory::singleton(0, 0, true);
 46:   return(0);
 47: }

 51: PetscErrorCode MeshView_Sieve_Ascii(const ALE::Obj<ALE::Mesh>& mesh, PetscViewer viewer)
 52: {
 53:   PetscViewerFormat format;
 54:   PetscErrorCode    ierr;

 57:   PetscViewerGetFormat(viewer, &format);
 58:   if (format == PETSC_VIEWER_ASCII_VTK) {
 59:     VTKViewer::writeHeader(viewer);
 60:     VTKViewer::writeVertices(mesh, viewer);
 61:     VTKViewer::writeElements(mesh, viewer);
 62:   } else if (format == PETSC_VIEWER_ASCII_PYLITH) {
 63:     char *filename;
 64:     char  connectFilename[2048];
 65:     char  coordFilename[2048];

 67:     PetscViewerFileGetName(viewer, &filename);
 68:     PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
 69:     PetscStrcpy(connectFilename, filename);
 70:     PetscStrcat(connectFilename, ".connect");
 71:     PetscViewerFileSetName(viewer, connectFilename);
 72:     ALE::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
 73:     PetscStrcpy(coordFilename, filename);
 74:     PetscStrcat(coordFilename, ".coord");
 75:     PetscViewerFileSetName(viewer, coordFilename);
 76:     ALE::PyLith::Viewer::writeVertices(mesh, viewer);
 77:     PetscViewerFileSetMode(viewer, FILE_MODE_READ);
 78:     PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
 79:     if (PetscExceptionValue(ierr)) {
 80:       /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
 81:     } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
 82:       0;
 83:     }
 84: 
 85:   } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
 86:     PetscViewer connectViewer, coordViewer;
 87:     char       *filename;
 88:     char        localFilename[2048];
 89:     int         rank = mesh->commRank();

 91:     PetscViewerFileGetName(viewer, &filename);

 93:     sprintf(localFilename, "%s.%d.connect", filename, rank);
 94:     PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
 95:     PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
 96:     PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
 97:     PetscViewerFileSetName(connectViewer, localFilename);
 98:     ALE::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
 99:     PetscViewerDestroy(connectViewer);

101:     sprintf(localFilename, "%s.%d.coord", filename, rank);
102:     PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
103:     PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
104:     PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
105:     PetscViewerFileSetName(coordViewer, localFilename);
106:     ALE::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
107:     PetscViewerDestroy(coordViewer);
108:   } else if (format == PETSC_VIEWER_ASCII_PCICE) {
109:     char      *filename;
110:     char       coordFilename[2048];
111:     PetscTruth isConnect;
112:     size_t     len;

114:     PetscViewerFileGetName(viewer, &filename);
115:     PetscStrlen(filename, &len);
116:     PetscStrcmp(&(filename[len-5]), ".lcon", &isConnect);
117:     if (!isConnect) {
118:       SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid element connectivity filename: %s", filename);
119:     }
120:     ALE::PCICE::Viewer::writeElements(mesh, viewer);
121:     PetscStrncpy(coordFilename, filename, len-5);
122:     coordFilename[len-5] = '\0';
123:     PetscStrcat(coordFilename, ".nodes");
124:     PetscViewerFileSetName(viewer, coordFilename);
125:     ALE::PCICE::Viewer::writeVertices(mesh, viewer);
126:   } else {
127:     int dim = mesh->getDimension();

129:     PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
130:     for(int d = 0; d <= dim; d++) {
131:       // FIX: Need to globalize
132:       PetscViewerASCIIPrintf(viewer, "  %d %d-cells\n", mesh->depthStratum(d)->size(), d);
133:     }
134:   }
135:   PetscViewerFlush(viewer);
136:   return(0);
137: }

141: PetscErrorCode MeshCompatView_Sieve_Ascii(const ALE::Obj<ALECompat::Mesh>& mesh, PetscViewer viewer)
142: {
143:   PetscViewerFormat format;
144:   PetscErrorCode    ierr;

147:   PetscViewerGetFormat(viewer, &format);
148:   if (format == PETSC_VIEWER_ASCII_PYLITH) {
149:     char *filename;
150:     char  connectFilename[2048];
151:     char  coordFilename[2048];

153:     PetscViewerFileGetName(viewer, &filename);
154:     PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
155:     PetscStrcpy(connectFilename, filename);
156:     PetscStrcat(connectFilename, ".connect");
157:     PetscViewerFileSetName(viewer, connectFilename);
158:     ALECompat::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
159:     PetscStrcpy(coordFilename, filename);
160:     PetscStrcat(coordFilename, ".coord");
161:     PetscViewerFileSetName(viewer, coordFilename);
162:     ALECompat::PyLith::Viewer::writeVertices(mesh, viewer);
163:     PetscViewerFileSetMode(viewer, FILE_MODE_READ);
164:     PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
165:     if (PetscExceptionValue(ierr)) {
166:       /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
167:     } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
168:       0;
169:     }
170: 
171:   } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
172:     PetscViewer connectViewer, coordViewer;
173:     char       *filename;
174:     char        localFilename[2048];
175:     int         rank = mesh->commRank();

177:     PetscViewerFileGetName(viewer, &filename);

179:     sprintf(localFilename, "%s.%d.connect", filename, rank);
180:     PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
181:     PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
182:     PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
183:     PetscViewerFileSetName(connectViewer, localFilename);
184:     ALECompat::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
185:     PetscViewerDestroy(connectViewer);

187:     sprintf(localFilename, "%s.%d.coord", filename, rank);
188:     PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
189:     PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
190:     PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
191:     PetscViewerFileSetName(coordViewer, localFilename);
192:     ALECompat::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
193:     PetscViewerDestroy(coordViewer);

195:     if (mesh->hasPairSection("split")) {
196:       PetscViewer splitViewer;

198:       sprintf(localFilename, "%s.%d.split", filename, rank);
199:       PetscViewerCreate(PETSC_COMM_SELF, &splitViewer);
200:       PetscViewerSetType(splitViewer, PETSC_VIEWER_ASCII);
201:       PetscViewerSetFormat(splitViewer, PETSC_VIEWER_ASCII_PYLITH);
202:       PetscViewerFileSetName(splitViewer, localFilename);
203:       ALECompat::PyLith::Viewer::writeSplitLocal(mesh, mesh->getPairSection("split"), splitViewer);
204:       PetscViewerDestroy(splitViewer);
205:     }

207:     if (mesh->hasRealSection("traction")) {
208:       PetscViewer tractionViewer;

210:       sprintf(localFilename, "%s.%d.traction", filename, rank);
211:       PetscViewerCreate(PETSC_COMM_SELF, &tractionViewer);
212:       PetscViewerSetType(tractionViewer, PETSC_VIEWER_ASCII);
213:       PetscViewerSetFormat(tractionViewer, PETSC_VIEWER_ASCII_PYLITH);
214:       PetscViewerFileSetName(tractionViewer, localFilename);
215:       ALECompat::PyLith::Viewer::writeTractionsLocal(mesh, mesh->getRealSection("traction"), tractionViewer);
216:       PetscViewerDestroy(tractionViewer);
217:     }
218:   } else {
219:     int dim = mesh->getDimension();

221:     PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
222:     for(int d = 0; d <= dim; d++) {
223:       // FIX: Need to globalize
224:       PetscViewerASCIIPrintf(viewer, "  %d %d-cells\n", mesh->getTopology()->depthStratum(0, d)->size(), d);
225:     }
226:   }
227:   PetscViewerFlush(viewer);
228:   return(0);
229: }

233: PetscErrorCode MeshView_Sieve(const ALE::Obj<ALE::Mesh>& mesh, PetscViewer viewer)
234: {
235:   PetscTruth     iascii, isbinary, isdraw;

239:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
240:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
241:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);

243:   if (iascii){
244:     MeshView_Sieve_Ascii(mesh, viewer);
245:   } else if (isbinary) {
246:     SETERRQ(PETSC_ERR_SUP, "Binary viewer not implemented for Mesh");
247:   } else if (isdraw){
248:     SETERRQ(PETSC_ERR_SUP, "Draw viewer not implemented for Mesh");
249:   } else {
250:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
251:   }
252:   return(0);
253: }

257: PetscErrorCode  MeshView_Mesh(Mesh mesh, PetscViewer viewer)
258: {

262:   if (!mesh->mcompat.isNull()) {
263:     MeshCompatView_Sieve_Ascii(mesh->mcompat, viewer);
264:   } else {
265:     MeshView_Sieve(mesh->m, viewer);
266:   }
267:   return(0);
268: }

272: /*@C
273:    MeshView - Views a Mesh object. 

275:    Collective on Mesh

277:    Input Parameters:
278: +  mesh - the mesh
279: -  viewer - an optional visualization context

281:    Notes:
282:    The available visualization contexts include
283: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
284: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
285:          output where only the first processor opens
286:          the file.  All other processors send their 
287:          data to the first processor to print. 

289:    You can change the format the mesh is printed using the 
290:    option PetscViewerSetFormat().

292:    The user can open alternative visualization contexts with
293: +    PetscViewerASCIIOpen() - Outputs mesh to a specified file
294: .    PetscViewerBinaryOpen() - Outputs mesh in binary to a
295:          specified file; corresponding input uses MeshLoad()
296: .    PetscViewerDrawOpen() - Outputs mesh to an X window display

298:    The user can call PetscViewerSetFormat() to specify the output
299:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
300:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
301: +    PETSC_VIEWER_ASCII_DEFAULT - default, prints mesh information
302: -    PETSC_VIEWER_ASCII_VTK - outputs a VTK file describing the mesh

304:    Level: beginner

306:    Concepts: mesh^printing
307:    Concepts: mesh^saving to disk

309: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
310:           MeshLoad(), PetscViewerCreate()
311: @*/
312: PetscErrorCode  MeshView(Mesh mesh, PetscViewer viewer)
313: {

319:   if (!viewer) {
320:     PetscViewerASCIIGetStdout(((PetscObject)mesh)->comm,&viewer);
321:   }

326:   (*mesh->ops->view)(mesh, viewer);
328:   return(0);
329: }

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

336:     Collective on Viewer

338:     Input Parameter:
339: .   viewer - The viewer containing the data

341:     Output Parameters:
342: .   mesh - the mesh object

344:     Level: advanced

346: .seealso MeshView()

348: @*/
349: PetscErrorCode  MeshLoad(PetscViewer viewer, Mesh *mesh)
350: {
351:   SETERRQ(PETSC_ERR_SUP, "");
352: }

356: /*@C
357:     MeshGetMesh - Gets the internal mesh object

359:     Not collective

361:     Input Parameter:
362: .    mesh - the mesh object

364:     Output Parameter:
365: .    m - the internal mesh object
366:  
367:     Level: advanced

369: .seealso MeshCreate(), MeshSetMesh()

371: @*/
372: PetscErrorCode  MeshGetMesh(Mesh mesh, ALE::Obj<ALE::Mesh>& m)
373: {
376:   m = mesh->m;
377:   return(0);
378: }

382: /*@C
383:     MeshSetMesh - Sets the internal mesh object

385:     Not collective

387:     Input Parameters:
388: +    mesh - the mesh object
389: -    m - the internal mesh object
390:  
391:     Level: advanced

393: .seealso MeshCreate(), MeshGetMesh()

395: @*/
396: PetscErrorCode  MeshSetMesh(Mesh mesh, const ALE::Obj<ALE::Mesh>& m)
397: {
400:   mesh->m = m;
401:   if (mesh->globalScatter) {

404:     VecScatterDestroy(mesh->globalScatter);
405:     mesh->globalScatter = PETSC_NULL;
406:   }
407:   return(0);
408: }

412: PetscErrorCode  MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
413: {
414:   ALE::Obj<ALE::Mesh> m;
415:   ALE::Obj<ALE::Mesh::real_section_type> s;

419:   MeshGetMesh(mesh, m);
420:   SectionRealGetSection(section, s);
421:   MeshCreateMatrix(m, s, mtype, J);
422:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
423:   return(0);
424: }

428: PetscErrorCode  MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
429: {
430:   SectionReal    section;

434:   MeshGetVertexSectionReal(mesh, 1, &section);
435:   MeshCreateMatrix(mesh, section, mtype, J);
436:   SectionRealDestroy(section);
437:   return(0);
438: }

442: /*@C
443:     MeshGetMatrix - Creates a matrix with the correct parallel layout required for 
444:       computing the Jacobian on a function defined using the informatin in Mesh.

446:     Collective on Mesh

448:     Input Parameter:
449: +   mesh - the mesh object
450: -   mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
451:             or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).

453:     Output Parameters:
454: .   J  - matrix with the correct nonzero preallocation
455:         (obviously without the correct Jacobian values)

457:     Level: advanced

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

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

464: @*/
465: PetscErrorCode  MeshGetMatrix(Mesh mesh, MatType mtype, Mat *J)
466: {
467:   ALE::Obj<ALE::Mesh> m;
468:   PetscTruth          flag;
469:   PetscErrorCode      ierr;

472:   MeshHasSectionReal(mesh, "default", &flag);
473:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
474:   MeshGetMesh(mesh, m);
475:   MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
476:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
477:   return(0);
478: }

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

486:     Collective on MPI_Comm

488:     Input Parameter:
489: .   comm - the processors that will share the global vector

491:     Output Parameters:
492: .   mesh - the mesh object

494:     Level: advanced

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

498: @*/
499: PetscErrorCode  MeshCreate(MPI_Comm comm,Mesh *mesh)
500: {
502:   Mesh         p;

506:   *mesh = PETSC_NULL;
507: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
508:   DMInitializePackage(PETSC_NULL);
509: #endif

511:   PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
512:   p->ops->view               = MeshView_Mesh;
513:   p->ops->destroy            = PETSC_NULL;
514:   p->ops->createglobalvector = MeshCreateGlobalVector;
515:   p->ops->createlocalvector  = MeshCreateLocalVector;
516:   p->ops->getcoloring        = PETSC_NULL;
517:   p->ops->getmatrix          = MeshGetMatrix;
518:   p->ops->getinterpolation   = MeshGetInterpolation_Mesh_New;
519:   p->ops->getinjection       = PETSC_NULL;
520:   p->ops->refine             = MeshRefine_Mesh;
521:   p->ops->coarsen            = PETSC_NULL;
522:   p->ops->refinehierarchy    = PETSC_NULL;
523:   p->ops->coarsenhierarchy   = MeshCoarsenHierarchy_Mesh;

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

527:   p->m             = PETSC_NULL;
528:   p->globalScatter = PETSC_NULL;
529:   p->lf            = PETSC_NULL;
530:   p->lj            = PETSC_NULL;
531:   p->mcompat       = PETSC_NULL;
532:   p->data          = PETSC_NULL;
533:   *mesh = p;
534:   return(0);
535: }

539: /*@
540:     MeshDestroy - Destroys a mesh.

542:     Collective on Mesh

544:     Input Parameter:
545: .   mesh - the mesh object

547:     Level: advanced

549: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
550: @*/
551: PetscErrorCode  MeshDestroy(Mesh mesh)
552: {
553:   PetscErrorCode     ierr;

556:   if (--((PetscObject)mesh)->refct > 0) return(0);
557:   if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
558:   mesh->m = PETSC_NULL;
559:   PetscHeaderDestroy(mesh);
560:   return(0);
561: }

565: /*@C
566:   MeshSetType - Sets the Mesh type

568:   Collective on Mesh

570:   Input Parameters:
571: + mesh - the Mesh context
572: - type - the type

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

578:   Notes:
579:   See "petsc/include/petscmesh.h" for available types (for instance,
580:   MESHCARTESIAN or MESHSIEVE).

582:   Level: intermediate

584: .keywords: Mesh, set, typr
585: .seealso: MeshGetType(), MeshType
586: @*/
587: PetscErrorCode  MeshSetType(Mesh mesh, MeshType type)
588: {
589:   PetscErrorCode ierr,(*r)(Mesh);
590:   PetscTruth     match;


596:   PetscTypeCompare((PetscObject)mesh,type,&match);
597:   if (match) return(0);

599:    PetscFListFind(MeshList,((PetscObject)mesh)->comm,type,(void (**)(void)) &r);
600:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
601:   /* Destroy the previous private Mesh context */
602:   if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
603:   /* Reinitialize function pointers in MeshOps structure */
604:   PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
605:   /* Call the MeshCreate_XXX routine for this particular mesh */
606:   (*r)(mesh);
607:   PetscObjectChangeTypeName((PetscObject) mesh, type);
608:   return(0);
609: }

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

616:   Not Collective

618:   Input Parameter:
619: . mesh - Mesh context 

621:   Output Parameter:
622: . name - name of Mesh type 

624:   Level: intermediate

626: .keywords: Mesh, get, type
627: .seealso: MeshSetType()
628: @*/
629: PetscErrorCode  MeshGetType(Mesh mesh,MeshType *type)
630: {
634:   *type = ((PetscObject)mesh)->type_name;
635:   return(0);
636: }

640: /*@C
641:   MeshRegister - See MeshRegisterDynamic()

643:   Level: advanced
644: @*/
645: PetscErrorCode  MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
646: {
648:   char           fullname[PETSC_MAX_PATH_LEN];

651:   PetscFListConcat(path,name,fullname);
652:   PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
653:   return(0);
654: }

657: EXTERN PetscErrorCode  MeshCreate_Cartesian(Mesh);

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

665:   Not Collective

667:   Level: advanced

669: .keywords: Mesh, register, all
670: .seealso:  MeshRegisterDestroy()
671: @*/
672: PetscErrorCode  MeshRegisterAll(const char path[])
673: {

677:   MeshRegisterAllCalled = PETSC_TRUE;

679:   MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
680:   return(0);
681: }

685: /*@
686:   MeshRegisterDestroy - Frees the list of Mesh types that were
687:   registered by MeshRegister().

689:   Not Collective

691:   Level: advanced

693: .keywords: Mesh, register, destroy
694: .seealso: MeshRegister(), MeshRegisterAll()
695: @*/
696: PetscErrorCode  MeshRegisterDestroy(void)
697: {

701:   PetscFListDestroy(&MeshList);
702:   MeshRegisterAllCalled = PETSC_FALSE;
703:   return(0);
704: }

708: /*@C
709:     MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into 
710:         by the mesh.

712:     Collective on Mesh

714:     Input Parameter:
715: .    mesh - the mesh object

717:     Output Parameters:
718: .   gvec - the global vector

720:     Level: advanced

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

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

726: @*/
727: PetscErrorCode  MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
728: {
729:   ALE::Obj<ALE::Mesh> m;
730:   PetscTruth     flag;

734:   MeshHasSectionReal(mesh, "default", &flag);
735:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
736:   MeshGetMesh(mesh, m);
737:   const ALE::Obj<ALE::Mesh::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));

739:   VecCreate(m->comm(), gvec);
740:   VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
741:   VecSetFromOptions(*gvec);
742:   return(0);
743: }

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

750:     Collective on Mesh

752:     Input Parameter:
753: .    mesh - the mesh object

755:     Output Parameters:
756: .   lvec - the local vector

758:     Level: advanced

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

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

764: @*/
765: PetscErrorCode  MeshCreateLocalVector(Mesh mesh, Vec *lvec)
766: {
767:   ALE::Obj<ALE::Mesh> m;
768:   PetscTruth     flag;

772:   MeshHasSectionReal(mesh, "default", &flag);
773:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
774:   MeshGetMesh(mesh, m);
775:   const int size = m->getRealSection("default")->getStorageSize();

777:   VecCreate(PETSC_COMM_SELF, lvec);
778:   VecSetSizes(*lvec, size, size);
779:   VecSetFromOptions(*lvec);
780:   return(0);
781: }

785: /*@C
786:     MeshGetGlobalIndices - Gets the global indices for all the local entries

788:     Collective on Mesh

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

793:     Output Parameters:
794: .    idx - the individual indices for each packed vector/array
795:  
796:     Level: advanced

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

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

803: @*/
804: PetscErrorCode  MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
805: {
806:   SETERRQ(PETSC_ERR_SUP, "");
807: }

811: PetscErrorCode  MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
812: {
813:   ALE::Obj<ALE::Mesh> m;
814:   ALE::Obj<ALE::Mesh::real_section_type> s;

818:   MeshGetMesh(mesh, m);
819:   SectionRealGetSection(section, s);
820:   MeshCreateGlobalScatter(m, s, scatter);
821:   return(0);
822: }

826: PetscErrorCode  MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
827: {

833:   if (!mesh->globalScatter) {
834:     SectionReal section;

836:     MeshGetSectionReal(mesh, "default", &section);
837:     MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
838:     SectionRealDestroy(section);
839:   }
840:   *scatter = mesh->globalScatter;
841:   return(0);
842: }

846: PetscErrorCode  MeshGetLocalFunction(Mesh mesh, PetscErrorCode (**lf)(Mesh, SectionReal, SectionReal, void *))
847: {
850:   if (lf) *lf = mesh->lf;
851:   return(0);
852: }

856: PetscErrorCode  MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
857: {
860:   mesh->lf = lf;
861:   return(0);
862: }

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

876: PetscErrorCode  MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
877: {
880:   mesh->lj = lj;
881:   return(0);
882: }

886: PetscErrorCode  MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
887: {

894:   if (mesh->lf) {
895:     (*mesh->lf)(mesh, X, F, ctx);
896:   }
897:   return(0);
898: }

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

910:   if (mesh->lj) {
911:     (*mesh->lj)(mesh, X, J, ctx);
912:   }
913:   return(0);
914: }

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

931:   MeshGetMesh(mesh, m);
932:   SectionRealGetSection(section, s);
933:   const Obj<ALE::Mesh::real_section_type>& coordinates = m->getRealSection("coordinates");
934:   int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
935:   int dim      = s->getFiberDimension(*m->depthStratum(0)->begin());

937:   PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
938:   PetscMalloc(numPoints*dim * sizeof(double), &values);
939:   for(int p = 0; p < numPoints; p++) {
940:     double *point = &points[p*embedDim];
941: 
942:     ALE::Mesh::point_type e = m->locatePoint(point);
943:     const ALE::Mesh::real_section_type::value_type *coeff = s->restrictPoint(e);

945:     m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
946:     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;
947:     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;
948:     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;

950:     for(int d = 0; d < dim; d++) {
951:       (*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;
952:     }
953:   }
954:   PetscFree3(v0, J, invJ);
955:   return(0);
956: }

960: /*@
961:   MeshGetMaximumDegree - Return the maximum degree of any mesh vertex

963:   Collective on mesh

965:   Input Parameter:
966: . mesh - The Mesh

968:   Output Parameter:
969: . maxDegree - The maximum number of edges at any vertex

971:    Level: beginner

973: .seealso: MeshCreate()
974: @*/
975: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
976: {
977:   Obj<ALE::Mesh> m;

981:   MeshGetMesh(mesh, m);
982:   const ALE::Obj<ALE::Mesh::label_sequence>& vertices = m->depthStratum(0);
983:   const ALE::Obj<ALE::Mesh::sieve_type>&     sieve    = m->getSieve();
984:   PetscInt                                          maxDeg   = -1;

986:   for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
987:     maxDeg = PetscMax(maxDeg, (PetscInt) sieve->support(*v_iter)->size());
988:   }
989:   *maxDegree = maxDeg;
990:   return(0);
991: }

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

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

1000:   Collective on g

1002:   Input Parameters:
1003: + g - The global vector
1004: . l - The local vector
1005: - mode - either ADD_VALUES or INSERT_VALUES, where
1006:    ADD_VALUES adds values to any existing entries, and
1007:    INSERT_VALUES replaces existing entries with new values

1009:    Level: beginner

1011: .seealso: MatSetOption()
1012: @*/
1013: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1014: {
1015:   VecScatter     injection;

1020:   PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1021:   if (injection) {
1022:     VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
1023:     VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
1024:   } else {
1025:     if (mode == INSERT_VALUES) {
1026:       VecCopy(g, l);
1027:     } else {
1028:       VecAXPY(l, 1.0, g);
1029:     }
1030:   }
1032:   return(0);
1033: }

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

1040:   Collective on g

1042:   Input Parameters:
1043: + g - The global vector
1044: . l - The local vector
1045: - mode - either ADD_VALUES or INSERT_VALUES, where
1046:    ADD_VALUES adds values to any existing entries, and
1047:    INSERT_VALUES replaces existing entries with new values

1049:    Level: beginner

1051: .seealso: MatSetOption()
1052: @*/
1053: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1054: {
1055:   VecScatter     injection;

1060:   PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1061:   if (injection) {
1062:     VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1063:     VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1064:   } else {
1065:     if (mode == INSERT_VALUES) {
1066:       VecCopy(l, g);
1067:     } else {
1068:       VecAXPY(g, 1.0, l);
1069:     }
1070:   }
1072:   return(0);
1073: }

1077: /*@C
1078:   assembleVector - Insert values into a vector

1080:   Collective on A

1082:   Input Parameters:
1083: + b - the vector
1084: . e - The element number
1085: . v - The values
1086: - mode - either ADD_VALUES or INSERT_VALUES, where
1087:    ADD_VALUES adds values to any existing entries, and
1088:    INSERT_VALUES replaces existing entries with new values

1090:    Level: beginner

1092: .seealso: VecSetOption()
1093: @*/
1094: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1095: {
1096:   Mesh                       mesh;
1097:   ALE::Obj<ALE::Mesh> m;
1098:   PetscInt                   firstElement;
1099:   PetscErrorCode             ierr;

1103:   PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1104:   MeshGetMesh(mesh, m);
1105:   //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1106:   firstElement = 0;
1107:   // Must relate b to field
1108:   if (mode == INSERT_VALUES) {
1109:     m->update(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1110:   } else {
1111:     m->updateAdd(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1112:   }
1114:   return(0);
1115: }

1119: PetscErrorCode updateOperator(Mat A, const ALE::Obj<ALE::Mesh>& m, const ALE::Obj<ALE::Mesh::real_section_type>& section, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, const ALE::Mesh::point_type& e, PetscScalar array[], InsertMode mode)
1120: {

1124:   const ALE::Mesh::indices_type indicesBlock = m->getIndices(section, e, globalOrder);
1125:   const PetscInt *indices    = indicesBlock.first;
1126:   const int&      numIndices = indicesBlock.second;

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:   }
1151:   return(0);
1152: }

1156: PetscErrorCode updateOperator(Mat A, const ALE::Obj<ALE::Mesh>& m, const ALE::Obj<ALE::Mesh::real_section_type>& section, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, int tag, int p, PetscScalar array[], InsertMode mode)
1157: {
1158:   const int *offsets, *indices;

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

1166:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1167:   if (ierr) {
1168:     printf("[%d]ERROR in updateOperator: tag %d point num %d\n", section->commRank(), tag, p);
1169:     for(int i = 0; i < numIndices; i++) {
1170:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1171:     }
1172: 
1173:   }
1175:   return(0);
1176: }

1180: PetscErrorCode updateOperatorGeneral(Mat A, const ALE::Obj<ALE::Mesh>& rowM, const ALE::Obj<ALE::Mesh::real_section_type>& rowSection, const ALE::Obj<ALE::Mesh::order_type>& rowGlobalOrder, const ALE::Mesh::point_type& rowE, const ALE::Obj<ALE::Mesh>& colM, const ALE::Obj<ALE::Mesh::real_section_type>& colSection, const ALE::Obj<ALE::Mesh::order_type>& colGlobalOrder, const ALE::Mesh::point_type& colE, PetscScalar array[], InsertMode mode)
1181: {

1185:   const ALE::Mesh::indices_type rowIndicesBlock = rowM->getIndices(rowSection, rowE, rowGlobalOrder);

1187:   const PetscInt *tmpIndices    = rowIndicesBlock.first;
1188:   const int      numRowIndices = rowIndicesBlock.second;
1189:   PetscInt rowIndices[numRowIndices];
1190:   PetscMemcpy(rowIndices, tmpIndices, numRowIndices*sizeof(PetscInt));

1192:   const ALE::Mesh::indices_type colIndicesBlock = colM->getIndices(colSection, colE, colGlobalOrder);

1194:   const PetscInt *colIndices    = colIndicesBlock.first;
1195:   const int      numColIndices = colIndicesBlock.second;

1198:   if (rowSection->debug()) {
1199:     printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1200:     for(int i = 0; i < numRowIndices; i++) {
1201:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1202:     }
1203:   }
1204:   if (colSection->debug()) {
1205:     for(int i = 0; i < numColIndices; i++) {
1206:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1207:     }
1208:     for(int i = 0; i < numRowIndices; i++) {
1209:       printf("[%d]", rowSection->commRank());
1210:       for(int j = 0; j < numColIndices; j++) {
1211:         printf(" %g", array[i*numColIndices+j]);
1212:       }
1213:       printf("\n");
1214:     }
1215:   }
1216:   MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1217:   if (ierr) {
1218:     printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1219:     for(int i = 0; i < numRowIndices; i++) {
1220:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1221:     }
1222:     for(int i = 0; i < numColIndices; i++) {
1223:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1224:     }
1225: 
1226:   }
1228:   return(0);
1229: }

1233: /*@C
1234:   assembleMatrix - Insert values into a matrix

1236:   Collective on A

1238:   Input Parameters:
1239: + A - the matrix
1240: . e - The element number
1241: . v - The values
1242: - mode - either ADD_VALUES or INSERT_VALUES, where
1243:    ADD_VALUES adds values to any existing entries, and
1244:    INSERT_VALUES replaces existing entries with new values

1246:    Level: beginner

1248: .seealso: MatSetOption()
1249: @*/
1250: PetscErrorCode assembleMatrix(Mat A, PetscInt e, PetscScalar v[], InsertMode mode)
1251: {
1252:   Mesh           mesh;

1257:   PetscObjectQuery((PetscObject) A, "mesh", (PetscObject *) &mesh);
1258:   try {
1259:     if (!mesh->mcompat.isNull()) {
1260:       Obj<ALECompat::Mesh> m;

1262:       MeshCompatGetMesh(mesh, m);
1263:       const ALE::Obj<ALECompat::Mesh::topology_type>&     topology    = m->getTopology();
1264:       const ALE::Obj<ALECompat::Mesh::numbering_type>&    cNumbering  = m->getFactory()->getLocalNumbering(topology, 0, topology->depth());
1265:       const ALE::Obj<ALECompat::Mesh::real_section_type>& s           = m->getRealSection("default");
1266:       const ALE::Obj<ALECompat::Mesh::order_type>&        globalOrder = m->getFactory()->getGlobalOrder(topology, 0, "default", s->getAtlas());

1268:       if (m->debug()) {
1269:         std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1270:       }
1271:       updateOperatorCompat(A, s, globalOrder, cNumbering->getPoint(e), v, mode);
1272:     } else {
1273:       Obj<ALE::Mesh> m;

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

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

1294: PetscErrorCode preallocateMatrix(const ALE::Obj<ALE::Mesh>& mesh, const int bs, const ALE::Obj<ALE::Mesh::real_section_type::atlas_type>& atlas, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, Mat A)
1295: {
1296:   return preallocateOperator(mesh, bs, atlas, globalOrder, A);
1297: }

1299: /******************************** C Wrappers **********************************/

1303: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1304: {
1305:   return VTKViewer::writeHeader(viewer);
1306: }

1310: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1311: {
1312:   ALE::Obj<ALE::Mesh> m;

1315:   MeshGetMesh(mesh, m);
1316:   return VTKViewer::writeVertices(m, viewer);
1317: }

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

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

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

1337:   MeshGetMesh(mesh, m);
1338:   return ALE::PCICE::Viewer::writeVertices(m, viewer);
1339: }

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

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

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

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

1365: /*@C
1366:   MeshCreatePFLOTRAN - Create a Mesh from PFLOTRAN HDF5 files.

1368:   Not Collective

1370:   Input Parameters:
1371: + dim - The topological mesh dimension
1372: . hdf5Filename - The HDF5 file containing the vertices for each element and vertex coordinates
1373: . interpolate - The flag for construction of intermediate elements

1375:   Output Parameter:
1376: . mesh - The Mesh object

1378:   Level: beginner

1380: .keywords: mesh, PFLOTRAN
1381: .seealso: MeshCreate()
1382: @*/
1383: PetscErrorCode MeshCreatePFLOTRAN(MPI_Comm comm, const int dim, const char hdf5Filename[], PetscTruth interpolate, Mesh *mesh)
1384: {
1385:   ALE::Obj<ALE::Mesh> m;
1386:   PetscInt            debug = 0;
1387:   PetscTruth          flag;
1388:   PetscErrorCode      ierr;

1391:   MeshCreate(comm, mesh);
1392:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1393:   try {
1394:     m  = ALE::PFLOTRAN::Builder::readMesh(comm, dim, std::string(hdf5Filename), true, interpolate, debug);
1395:     if (debug) {m->view("Mesh");}
1396:   } catch(ALE::Exception e) {
1397:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1398:   }
1399: #if 0
1400:   if (bcFilename) {
1401:     ALE::PFLOTRAN::Builder::readBoundary(m, std::string(bcFilename));
1402:   }
1403: #endif
1404:   MeshSetMesh(*mesh, m);
1405:   return(0);
1406: }

1410: /*@C
1411:   MeshCreatePCICE - Create a Mesh from PCICE files.

1413:   Not Collective

1415:   Input Parameters:
1416: + dim - The topological mesh dimension
1417: . coordFilename - The file containing vertex coordinates
1418: . adjFilename - The file containing the vertices for each element
1419: . interpolate - The flag for construction of intermediate elements
1420: . bcFilename - The file containing the boundary topology and conditions
1421: . numBdFaces - The number of boundary faces (or edges)
1422: - numBdVertices - The number of boundary vertices

1424:   Output Parameter:
1425: . mesh - The Mesh object

1427:   Level: beginner

1429: .keywords: mesh, PCICE
1430: .seealso: MeshCreate()
1431: @*/
1432: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], Mesh *mesh)
1433: {
1434:   ALE::Obj<ALE::Mesh> m;
1435:   PetscInt            debug = 0;
1436:   PetscTruth          flag;
1437:   PetscErrorCode      ierr;

1440:   MeshCreate(comm, mesh);
1441:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1442:   try {
1443:     m  = ALE::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1444:     if (debug) {m->view("Mesh");}
1445:   } catch(ALE::Exception e) {
1446:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1447:   }
1448:   if (bcFilename) {
1449:     ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1450:   }
1451:   MeshSetMesh(*mesh, m);
1452:   return(0);
1453: }

1457: /*@C
1458:   MeshCreatePyLith - Create a Mesh from PyLith files.

1460:   Not Collective

1462:   Input Parameters:
1463: + dim - The topological mesh dimension
1464: . baseFilename - The basename for mesh files
1465: . zeroBase - Use 0 to start numbering
1466: - interpolate - The flag for mesh interpolation

1468:   Output Parameter:
1469: . mesh - The Mesh object

1471:   Level: beginner

1473: .keywords: mesh, PCICE
1474: .seealso: MeshCreate()
1475: @*/
1476: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1477: {
1478:   ALE::Obj<ALE::Mesh> m;
1479:   PetscInt            debug = 0;
1480:   PetscTruth          flag;
1481:   PetscErrorCode      ierr;

1484:   MeshCreate(comm, mesh);
1485:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1486:   try {
1487:     m  = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1488:   } catch(ALE::Exception e) {
1489:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1490:   }
1491:   MeshSetMesh(*mesh, m);
1492:   return(0);
1493: }

1497: /*@C
1498:   MeshGetCoordinates - Creates an array holding the coordinates.

1500:   Not Collective

1502:   Input Parameter:
1503: + mesh - The Mesh object
1504: - columnMajor - Flag for column major order

1506:   Output Parameter:
1507: + numVertices - The number of vertices
1508: . dim - The embedding dimension
1509: - coords - The array holding local coordinates

1511:   Level: intermediate

1513: .keywords: mesh, coordinates
1514: .seealso: MeshCreate()
1515: @*/
1516: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1517: {
1518:   ALE::Obj<ALE::Mesh> m;
1519:   PetscErrorCode      ierr;

1522:   MeshGetMesh(mesh, m);
1523:   ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1524:   return(0);
1525: }

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

1532:   Not Collective

1534:   Input Parameters:
1535: + mesh - The Mesh object
1536: - columnMajor - Flag for column major order

1538:   Output Parameters:
1539: + numElements - The number of elements
1540: . numCorners - The number of vertices per element
1541: - vertices - The array holding vertices on each local element

1543:   Level: intermediate

1545: .keywords: mesh, elements
1546: .seealso: MeshCreate()
1547: @*/
1548: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1549: {
1550:   ALE::Obj<ALE::Mesh> m;
1551:   PetscErrorCode      ierr;

1554:   MeshGetMesh(mesh, m);
1555:   ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1556:   return(0);
1557: }

1561: /*@C
1562:   MeshDistribute - Distributes the mesh and any associated sections.

1564:   Not Collective

1566:   Input Parameter:
1567: + serialMesh  - The original Mesh object
1568: - partitioner - The partitioning package, or NULL for the default

1570:   Output Parameter:
1571: . parallelMesh - The distributed Mesh object

1573:   Level: intermediate

1575: .keywords: mesh, elements

1577: .seealso: MeshCreate(), MeshDistributeByFace()
1578: @*/
1579: PetscErrorCode MeshDistribute(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1580: {
1581:   ALE::Obj<ALE::Mesh> oldMesh;
1582:   PetscErrorCode      ierr;

1585:   MeshGetMesh(serialMesh, oldMesh);
1586:   MeshCreate(oldMesh->comm(), parallelMesh);
1587:   if (partitioner == NULL) {
1588:     ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh);
1589:     MeshSetMesh(*parallelMesh, newMesh);
1590:   } else {
1591:     ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 0, partitioner);
1592:     MeshSetMesh(*parallelMesh, newMesh);
1593:   }
1594:   return(0);
1595: }

1599: /*@C
1600:   MeshDistribute - Distributes the mesh and any associated sections.

1602:   Not Collective

1604:   Input Parameter:
1605: + serialMesh  - The original Mesh object
1606: - partitioner - The partitioning package, or NULL for the default

1608:   Output Parameter:
1609: . parallelMesh - The distributed Mesh object

1611:   Level: intermediate

1613: .keywords: mesh, elements

1615: .seealso: MeshCreate(), MeshDistribute()
1616: @*/
1617: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1618: {
1619:   ALE::Obj<ALE::Mesh> oldMesh;
1620:   PetscErrorCode      ierr;

1623:   MeshGetMesh(serialMesh, oldMesh);
1624:   MeshCreate(oldMesh->comm(), parallelMesh);
1625:   if (partitioner == NULL) {
1626:     ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1);
1627:     MeshSetMesh(*parallelMesh, newMesh);
1628:   } else {
1629:     ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1, partitioner);
1630:     MeshSetMesh(*parallelMesh, newMesh);
1631:   }
1632:   return(0);
1633: }

1637: /*@C
1638:   MeshGenerate - Generates a mesh.

1640:   Not Collective

1642:   Input Parameters:
1643: + boundary - The Mesh boundary object
1644: - interpolate - Flag to create intermediate mesh elements

1646:   Output Parameter:
1647: . mesh - The Mesh object

1649:   Level: intermediate

1651: .keywords: mesh, elements
1652: .seealso: MeshCreate(), MeshRefine()
1653: @*/
1654: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1655: {
1656:   ALE::Obj<ALE::Mesh> mB;
1657:   PetscErrorCode      ierr;

1660:   MeshGetMesh(boundary, mB);
1661:   MeshCreate(mB->comm(), mesh);
1662:   ALE::Obj<ALE::Mesh> m = ALE::Generator::generateMesh(mB, interpolate);
1663:   MeshSetMesh(*mesh, m);
1664:   return(0);
1665: }

1669: /*@C
1670:   MeshRefine - Refines the mesh.

1672:   Not Collective

1674:   Input Parameters:
1675: + mesh - The original Mesh object
1676: . refinementLimit - The maximum size of any cell
1677: - interpolate - Flag to create intermediate mesh elements

1679:   Output Parameter:
1680: . refinedMesh - The refined Mesh object

1682:   Level: intermediate

1684: .keywords: mesh, elements
1685: .seealso: MeshCreate(), MeshGenerate()
1686: @*/
1687: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1688: {
1689:   ALE::Obj<ALE::Mesh> oldMesh;
1690:   PetscErrorCode      ierr;

1693:   MeshGetMesh(mesh, oldMesh);
1694:   MeshCreate(oldMesh->comm(), refinedMesh);
1695:   ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, interpolate);
1696:   MeshSetMesh(*refinedMesh, newMesh);
1697:   return(0);
1698: }

1702: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1703: {
1704:   ALE::Obj<ALE::Mesh> oldMesh;
1705:   double              refinementLimit;
1706:   PetscErrorCode      ierr;

1709:   MeshGetMesh(mesh, oldMesh);
1710:   MeshCreate(comm, refinedMesh);
1711:   refinementLimit = oldMesh->getMaxVolume()/2.0;
1712:   ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, true);
1713:   MeshSetMesh(*refinedMesh, newMesh);
1714:   const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default");
1715:   const Obj<std::set<std::string> >& discs = oldMesh->getDiscretizations();

1717:   for(std::set<std::string>::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter) {
1718:     newMesh->setDiscretization(*f_iter, oldMesh->getDiscretization(*f_iter));
1719:   }
1720:   newMesh->setupField(s);
1721:   return(0);
1722: }


1725: #include "Hierarchy.hh"

1729: /*@C
1730:   MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.

1732:   Not Collective

1734:   Input Parameters:
1735: + mesh - The original Mesh object
1736: . numLevels - The number of 
1737: . coarseningFactor - The expansion factor for coarse meshes
1738: - interpolate - Flag to create intermediate mesh elements

1740:   Output Parameter:
1741: . coarseHierarchy - The coarse Mesh objects

1743:   Level: intermediate

1745: .keywords: mesh, elements
1746: .seealso: MeshCreate(), MeshGenerate()
1747: @*/
1748: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh **coarseHierarchy)
1749: {
1750:   ALE::Obj<ALE::Mesh> oldMesh;
1751:   PetscErrorCode      ierr;

1754:   if (numLevels < 1) {
1755:     *coarseHierarchy = PETSC_NULL;
1756:     return(0);
1757:   }
1758:   MeshGetMesh(mesh, oldMesh);
1759:   PetscMalloc((numLevels+1) * sizeof(Mesh), coarseHierarchy);
1760:   for (int i = 0; i < numLevels+1; i++) {
1761:     MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[i]);
1762:   }
1763:   MeshSpacingFunction(mesh);
1764:   MeshCreateHierarchyLabel_Link(mesh, coarseningFactor, numLevels+1, *coarseHierarchy);
1765: 
1766: #if 0
1767:   if (oldMesh->getDimension() != 2) SETERRQ(PETSC_ERR_SUP, "Coarsening only works in two dimensions right now");
1768:   ALE::Coarsener::IdentifyBoundary(oldMesh, 2);
1769:   ALE::Coarsener::make_coarsest_boundary(oldMesh, 2, numLevels+1);
1770:   ALE::Coarsener::CreateSpacingFunction(oldMesh, 2);
1771:   ALE::Coarsener::CreateCoarsenedHierarchyNew(oldMesh, 2, numLevels, coarseningFactor);
1772:   PetscMalloc(numLevels * sizeof(Mesh),coarseHierarchy);
1773:   for(int l = 0; l < numLevels; l++) {
1774:     ALE::Obj<ALE::Mesh> newMesh = new ALE::Mesh(oldMesh->comm(), oldMesh->debug());
1775:     const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default");

1777:     MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1778:     newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1779:     newMesh->setDiscretization(oldMesh->getDiscretization());
1780:     newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1781:     newMesh->setupField(s);
1782:     MeshSetMesh((*coarseHierarchy)[l], newMesh);
1783:   }
1784: #endif
1785:   return(0);
1786: }

1788: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh **coarseHierarchy)
1789: {
1791:   double cfactor = 1.5;
1793:   PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1794:   MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1795:   return(0);
1796: }


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

1803:   ALE::Obj<ALE::Mesh> fm, cm;
1804:   Mat                 P;
1805:   PetscErrorCode      ierr;

1808:   MeshGetMesh(dmFine, fm);
1809:   MeshGetMesh(dmCoarse, cm);
1810:   ALE::Obj<ALE::Mesh::label_type> coarsetraversal = cm->createLabel("traversal");
1811:   ALE::Obj<ALE::Mesh::label_type> finetraversal   = fm->createLabel ("traversal");
1812:   const int                       debug           = fm->debug();
1813:   if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1814:   const ALE::Obj<ALE::Mesh::real_section_type>& finecoordinates   = fm->getRealSection("coordinates");
1815:   const ALE::Obj<ALE::Mesh::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
1816:   const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse           = cm->getRealSection("default");
1817:   const ALE::Obj<ALE::Mesh::real_section_type>& sFine             = fm->getRealSection("default");
1818:   const ALE::Obj<ALE::Mesh::order_type>&        coarseOrder       = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1819:   const ALE::Obj<ALE::Mesh::order_type>&        fineOrder         = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
1820:   std::list<ALE::Mesh::point_type> travlist;        // store point
1821:   std::list<ALE::Mesh::point_type> travguesslist;   // store guess
1822:   std::list<ALE::Mesh::point_type> eguesslist;      // store the next guesses for the location of the current point.
1823:   static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1824:   if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}

1826:   MatCreate(fm->comm(), &P);
1827:   MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
1828:   MatSetFromOptions(P);

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

1835:   //traversal labels on both layers
1836:   const ALE::Obj<ALE::Mesh::label_sequence>& finevertices = fm->depthStratum(0);
1837:   const ALE::Mesh::label_sequence::iterator  fv_iter_end  = finevertices->end();
1838:   ALE::Mesh::label_sequence::iterator        fv_iter      = finevertices->begin();

1840:   while (fv_iter != fv_iter_end) {
1841:     fm->setValue(finetraversal, *fv_iter, 0);
1842:     fv_iter++;
1843:   }

1845:   const ALE::Obj<ALE::Mesh::label_sequence>& coarseelements = cm->heightStratum(0);
1846:   const ALE::Mesh::label_sequence::iterator  ce_iter_end    = coarseelements->end();
1847:   ALE::Mesh::label_sequence::iterator        ce_iter        = coarseelements->begin();
1848: 
1849:   while (ce_iter != ce_iter_end) {
1850:     cm->setValue(coarsetraversal, *ce_iter, 0);
1851:     ce_iter++;
1852:   }

1854:   double fvCoords[dim], nvCoords[dim];
1855:   bool pointIsInElement;

1857:   if (debug) {PetscPrintf(fm->comm(), "starting iterations\n");}
1858:   fv_iter = finevertices->begin();
1859:   while (fv_iter != fv_iter_end) {
1860:     // locate an initial point.
1861:     if (fm->getValue(finetraversal, *fv_iter) == 0) {
1862:       bool isLocated = false;

1864:       ce_iter = coarseelements->begin();
1865:       PetscMemcpy(fvCoords, finecoordinates->restrictPoint(*fv_iter), dim*sizeof(double));
1866:       while ((ce_iter != ce_iter_end) && (!isLocated)) {
1867:         cm->computeElementGeometry(coarsecoordinates, *ce_iter, v0, J, invJ, detJ);
1868:         // generalized simplicial location for 2D, 3D:
1869:         loc[0] = 1.0;
1870:         pointIsInElement = true;
1871:         for(int i = 0; i < dim; i++) {
1872:           loc[i+1] = 0.0;
1873:           for(int j = 0; j < dim; j++) {
1874:             loc[i+1] += 0.5*invJ[i*dim+j]*(fvCoords[j] - v0[j]);
1875:           }
1876:           loc[0] -= loc[i+1];
1877:           //PetscPrintf(fm->comm(), "%f, ", loc[i+1]);
1878:           if (loc[i+1] < -0.000000000001) pointIsInElement = false;
1879:         }
1880:         //PetscPrintf(fm->comm(), "%f\n", loc[0]);
1881:         if (loc[0] < -0.000000000001) pointIsInElement = false;
1882:         if (pointIsInElement) {
1883:           //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
1884:           //PetscPrintf(fm->comm(), "located by guess.\n");
1885:           isLocated = true;
1886:           updateOperatorGeneral(P, fm, sFine, fineOrder, *fv_iter, cm, sCoarse, coarseOrder, *ce_iter, loc, INSERT_VALUES);
1887:           fm->setValue(finetraversal, *fv_iter, 1);
1888:           const ALE::Obj<ALE::Mesh::sieve_type::coneSet> neighbors  = fm->getSieve()->cone(fm->getSieve()->support(*fv_iter));
1889:           const ALE::Mesh::sieve_type::coneSet::iterator n_iter_end = neighbors->end();
1890:           ALE::Mesh::sieve_type::coneSet::iterator       n_iter     = neighbors->begin();
1891:           while (n_iter != n_iter_end) {
1892:             if (fm->getValue(finetraversal, *n_iter) == 0) {
1893:               travlist.push_back(*n_iter);
1894:               fm->setValue(finetraversal, *n_iter, 1);
1895:               travguesslist.push_back(*ce_iter);
1896:             }
1897:             n_iter++;
1898:           }
1899:           //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.
1900:           while (!travlist.empty()) {
1901:             ALE::Mesh::point_type curVert = *travlist.begin();
1902:             PetscMemcpy(nvCoords, finecoordinates->restrictPoint(curVert), dim*sizeof(double));
1903:             ALE::Mesh::point_type curEle =  *travguesslist.begin();
1904:             travlist.pop_front();
1905:             travguesslist.pop_front();
1906:             eguesslist.push_front(curEle);
1907:             cm->setValue(coarsetraversal, curEle, 1);
1908:             bool locationDiscovered  = false;
1909:             int traversalcomparisons = 0;
1910:             while ((!eguesslist.empty()) && (!locationDiscovered) && traversalcomparisons < maxComparisons) {
1911:               traversalcomparisons = 0;
1912:               ALE::Mesh::point_type curguess = *eguesslist.begin();
1913:               eguesslist.pop_front();
1914:               pointIsInElement = true;
1915:               cm->computeElementGeometry(coarsecoordinates, curguess, v0, J, invJ, detJ);
1916:               loc[0] = 1.0;
1917:               for(int i = 0; i < dim; i++) {
1918:                 loc[i+1] = 0.0;
1919:                 for(int j = 0; j < dim; j++) {
1920:                   loc[i+1] += 0.5*invJ[i*dim+j]*(nvCoords[j] - v0[j]);
1921:                 }
1922:                 loc[0] -= loc[i+1];
1923:                 if (loc[i+1] < -0.00000000001) pointIsInElement = false;
1924:               }
1925:               if (loc[0] < -0.00000000001) pointIsInElement = false;

1927:               if (pointIsInElement) {
1928:                 //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
1929:                 locationDiscovered = true;
1930:                 //PetscPrintf(fm->comm(), "located by traversal.\n");
1931:                 //set the label.
1932:                 //fm->setValue(prolongation, curVert, curguess);
1933:                 updateOperatorGeneral(P, fm, sFine, fineOrder, curVert, cm, sCoarse, coarseOrder, curguess, loc, INSERT_VALUES);
1934:                 //PetscPrintf(fm->comm(), "Point %d located in %d.\n",  curVert, curguess);
1935:                 //stick its neighbors in the queue along with its location as a good guess of the location of its neighbors
1936:                 const ALE::Obj<ALE::Mesh::sieve_type::coneSet> newNeighbors = fm->getSieve()->cone(fm->getSieve()->support(curVert));
1937:                 const ALE::Mesh::sieve_type::coneSet::iterator nn_iter_end  = newNeighbors->end();
1938:                 ALE::Mesh::sieve_type::coneSet::iterator       nn_iter      = newNeighbors->begin();
1939:                 while (nn_iter != nn_iter_end) {
1940:                   if (fm->getValue(finetraversal, *nn_iter) == 0) { //unlocated neighbor
1941:                     travlist.push_back(*nn_iter);
1942:                     travguesslist.push_back(curguess);
1943:                     fm->setValue(finetraversal, *nn_iter, 1);
1944:                   }
1945:                   nn_iter++;
1946:                 }
1947:               } else {
1948:               //add the current guesses neighbors to the comparison queue and start over.
1949:                 const ALE::Obj<ALE::Mesh::sieve_type::supportSet> curguessneighbors = cm->getSieve()->support(cm->getSieve()->cone(curguess));
1950:                 const ALE::Mesh::sieve_type::supportSet::iterator cgn_iter_end      = curguessneighbors->end();
1951:                 ALE::Mesh::sieve_type::supportSet::iterator       cgn_iter          = curguessneighbors->begin();
1952:                 while (cgn_iter != cgn_iter_end) {
1953:                   if (cm->getValue(coarsetraversal, *cgn_iter) == 0) {
1954:                     eguesslist.push_back(*cgn_iter);
1955:                     cm->setValue(coarsetraversal, *cgn_iter, 1);
1956:                   }
1957:                   cgn_iter++;
1958:                 }
1959:               }
1960:             }
1961:             if (!locationDiscovered) {  //if a position for it is not discovered, it doesn't get corrected; complain
1962:               if (fm->debug())PetscPrintf(fm->comm(), "Point %d (%f, %f) not located.\n",  curVert, nvCoords[0], nvCoords[1]);
1963:               fm->setValue(finetraversal, curVert, 2); //don't try again.
1964:             }
1965:             eguesslist.clear(); //we've discovered the location of the point or exhausted our possibilities on this contiguous block of elements.
1966:             //unset the traversed element list
1967:             const ALE::Obj<ALE::Mesh::label_sequence>& traved_elements = cm->getLabelStratum("traversal", 1);
1968:             const ALE::Mesh::label_sequence::iterator  tp_iter_end     = traved_elements->end();
1969:             ALE::Mesh::label_sequence::iterator        tp_iter         = traved_elements->begin();
1970:             //PetscPrintf(cm->comm(), "%d\n", traved_elements->size());
1971:             while (tp_iter != tp_iter_end) {
1972:               eguesslist.push_back(*tp_iter);
1973:               tp_iter++;
1974:             }
1975:             while (!eguesslist.empty()) {
1976:               cm->setValue(coarsetraversal, *eguesslist.begin(), 0);
1977:               eguesslist.pop_front();
1978:             }
1979:           }
1980:         }
1981:         ce_iter++;
1982:       }
1983:       if (!isLocated) {
1984:        if (fm->debug())PetscPrintf(fm->comm(), "NOT located\n");
1985:        fm->setValue(finetraversal, *fv_iter, 2); //don't try again.
1986:       }
1987:     }
1988:     // printf("-");
1989:     fv_iter++;
1990:   }
1991:   MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
1992:   MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
1993:   //MatView(P, PETSC_VIEWER_STDOUT_SELF);
1994:   *interpolation = P;
1995:   if (debug) {PetscPrintf(fm->comm(), "Ending Interpolation Matrix Build\n");}
1996:   return(0);
1997: }


2002: /*
2003:   This method only handle P_1 discretizations at present.
2004: */
2005: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
2006: {
2007:   ALE::Obj<ALE::Mesh> coarse;
2008:   ALE::Obj<ALE::Mesh> fine;
2009:   Mat                 P;
2010:   PetscErrorCode      ierr;

2013:   MeshGetMesh(dmFine,   fine);
2014:   MeshGetMesh(dmCoarse, coarse);
2015:   const ALE::Obj<ALE::Mesh::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
2016:   const ALE::Obj<ALE::Mesh::real_section_type>& fineCoordinates   = fine->getRealSection("coordinates");
2017:   const ALE::Obj<ALE::Mesh::label_sequence>&    vertices          = fine->depthStratum(0);
2018:   const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse           = coarse->getRealSection("default");
2019:   const ALE::Obj<ALE::Mesh::real_section_type>& sFine             = fine->getRealSection("default");
2020:   const ALE::Obj<ALE::Mesh::order_type>&        coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
2021:   const ALE::Obj<ALE::Mesh::order_type>&        fineOrder   = fine->getFactory()->getGlobalOrder(fine, "default", sFine);

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

2027:   MatCreate(fine->comm(), &P);
2028:   MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2029:   MatSetFromOptions(P);
2030:   MatSeqAIJSetPreallocation(P, numDof, PETSC_NULL);
2031:   MatMPIAIJSetPreallocation(P, numDof, PETSC_NULL, numDof, PETSC_NULL);
2032:   PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
2033:   bool hasprolong;
2034:   if (fine->hasLabel("prolongation")) {
2035:     hasprolong = true;
2036:   } else {
2037:     hasprolong = false;
2038:     PetscPrintf(fine->comm(), "WARNING: Point Location Label Does Not Exist");
2039:   }
2040:   ALE::Mesh::label_sequence::iterator v_iter_end = vertices->end();
2041:   ALE::Mesh::real_section_type::value_type coords[dim];

2043:   for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != v_iter_end; ++v_iter) {
2044:     //const ALE::Mesh::real_section_type::value_type *coords     = fineCoordinates->restrictPoint(*v_iter);
2045:     PetscMemcpy(coords, fineCoordinates->restrictPoint(*v_iter), dim*sizeof(double));
2046:     ALE::Mesh::point_type coarseCell;
2047:     ALE::Mesh::point_type cellguess = -1;
2048:     if (hasprolong) {
2049:       cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
2050:       coarseCell = coarse->locatePoint(coords, cellguess);
2051:     } else {
2052:       coarseCell = coarse->locatePoint(coords);
2053:     }
2054: //      coarseCell = coarse->locatePoint(coords);
2055:     if (coarseCell == -1) {
2056:      // do NO CORRECTION!
2057:     } else {
2058:       coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
2059:       for(int d = 0; d < dim; ++d) {
2060:         refCoords[d] = 0.0;
2061:         for(int e = 0; e < dim; ++e) {
2062:           refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
2063:         }
2064:         refCoords[d] -= 1.0;
2065:       }
2066:       values[0] = -(refCoords[0] + refCoords[1])/2.0;
2067:       values[1] = 0.5*(refCoords[0] + 1.0);
2068:       values[2] = 0.5*(refCoords[1] + 1.0);
2069:   //    PetscPrintf(fine->comm(), "%f, %f, %f\n", values[0], values[1], values[2]);
2070:       updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
2071:     }
2072:   }
2073:   PetscFree5(v0,J,invJ,refCoords,values);
2074:   MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2075:   MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2076:   *interpolation = P;
2077:   return(0);
2078: }

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

2085:   Not Collective

2087:   Input Parameters:
2088: + mesh - The Mesh object
2089: - name - The section name

2091:   Output Parameter:
2092: . flag - True if the SectionReal is present in the Mesh

2094:   Level: intermediate

2096: .keywords: mesh, elements
2097: .seealso: MeshCreate()
2098: @*/
2099: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
2100: {
2101:   ALE::Obj<ALE::Mesh> m;
2102:   PetscErrorCode      ierr;

2105:   MeshGetMesh(mesh, m);
2106:   *flag = (PetscTruth) m->hasRealSection(std::string(name));
2107:   return(0);
2108: }

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

2115:   Collective on Mesh

2117:   Input Parameters:
2118: + mesh - The Mesh object
2119: - name - The section name

2121:   Output Parameter:
2122: . section - The SectionReal

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

2126:   Level: intermediate

2128: .keywords: mesh, elements
2129: .seealso: MeshCreate()
2130: @*/
2131: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
2132: {
2133:   ALE::Obj<ALE::Mesh> m;
2134:   PetscErrorCode      ierr;

2137:   MeshGetMesh(mesh, m);
2138:   SectionRealCreate(m->comm(), section);
2139:   PetscObjectSetName((PetscObject) *section, name);
2140:   SectionRealSetSection(*section, m->getRealSection(std::string(name)));
2141:   SectionRealSetBundle(*section, m);
2142:   return(0);
2143: }

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

2150:   Collective on Mesh

2152:   Input Parameters:
2153: + mesh - The Mesh object
2154: - section - The SectionReal

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

2158:   Level: intermediate

2160: .keywords: mesh, elements
2161: .seealso: MeshCreate()
2162: @*/
2163: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
2164: {
2165:   ALE::Obj<ALE::Mesh> m;
2166:   ALE::Obj<ALE::Mesh::real_section_type> s;
2167:   const char         *name;
2168:   PetscErrorCode      ierr;

2171:   MeshGetMesh(mesh, m);
2172:   PetscObjectGetName((PetscObject) section, &name);
2173:   SectionRealGetSection(section, s);
2174:   m->setRealSection(std::string(name), s);
2175:   return(0);
2176: }

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

2183:   Not Collective

2185:   Input Parameters:
2186: + mesh - The Mesh object
2187: - name - The section name

2189:   Output Parameter:
2190: . flag - True if the SectionInt is present in the Mesh

2192:   Level: intermediate

2194: .keywords: mesh, elements
2195: .seealso: MeshCreate()
2196: @*/
2197: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2198: {
2199:   ALE::Obj<ALE::Mesh> m;
2200:   PetscErrorCode      ierr;

2203:   MeshGetMesh(mesh, m);
2204:   *flag = (PetscTruth) m->hasIntSection(std::string(name));
2205:   return(0);
2206: }

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

2213:   Collective on Mesh

2215:   Input Parameters:
2216: + mesh - The Mesh object
2217: - name - The section name

2219:   Output Parameter:
2220: . section - The SectionInt

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

2224:   Level: intermediate

2226: .keywords: mesh, elements
2227: .seealso: MeshCreate()
2228: @*/
2229: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2230: {
2231:   ALE::Obj<ALE::Mesh> m;
2232:   PetscErrorCode      ierr;

2235:   MeshGetMesh(mesh, m);
2236:   SectionIntCreate(m->comm(), section);
2237:   PetscObjectSetName((PetscObject) *section, name);
2238:   SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2239:   SectionIntSetBundle(*section, m);
2240:   return(0);
2241: }

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

2248:   Collective on Mesh

2250:   Input Parameters:
2251: + mesh - The Mesh object
2252: - section - The SectionInt

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

2256:   Level: intermediate

2258: .keywords: mesh, elements
2259: .seealso: MeshCreate()
2260: @*/
2261: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2262: {
2263:   ALE::Obj<ALE::Mesh> m;
2264:   ALE::Obj<ALE::Mesh::int_section_type> s;
2265:   const char         *name;
2266:   PetscErrorCode      ierr;

2269:   MeshGetMesh(mesh, m);
2270:   PetscObjectGetName((PetscObject) section, &name);
2271:   SectionIntGetSection(section, s);
2272:   m->setIntSection(std::string(name), s);
2273:   return(0);
2274: }

2278: /*@C
2279:   SectionGetArray - Returns the array underlying the Section.

2281:   Not Collective

2283:   Input Parameters:
2284: + mesh - The Mesh object
2285: - name - The section name

2287:   Output Parameters:
2288: + numElements - The number of mesh element with values
2289: . fiberDim - The number of values per element
2290: - array - The array

2292:   Level: intermediate

2294: .keywords: mesh, elements
2295: .seealso: MeshCreate()
2296: @*/
2297: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2298: {
2299:   ALE::Obj<ALE::Mesh> m;
2300:   PetscErrorCode      ierr;

2303:   MeshGetMesh(mesh, m);
2304:   const Obj<ALE::Mesh::real_section_type>& section = m->getRealSection(std::string(name));
2305:   if (section->size() == 0) {
2306:     *numElements = 0;
2307:     *fiberDim    = 0;
2308:     *array       = NULL;
2309:     return(0);
2310:   }
2311:   const ALE::Mesh::real_section_type::chart_type& chart = section->getChart();
2312: /*   const int                                  depth   = m->depth(*chart.begin()); */
2313: /*   *numElements = m->depthStratum(depth)->size(); */
2314: /*   *fiberDim    = section->getFiberDimension(*chart.begin()); */
2315: /*   *array       = (PetscScalar *) m->restrict(section); */
2316:   int fiberDimMin = section->getFiberDimension(*chart.begin());
2317:   int numElem     = 0;

2319:   for(ALE::Mesh::real_section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2320:     const int fiberDim = section->getFiberDimension(*c_iter);

2322:     if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2323:   }
2324:   for(ALE::Mesh::real_section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2325:     const int fiberDim = section->getFiberDimension(*c_iter);

2327:     numElem += fiberDim/fiberDimMin;
2328:   }
2329:   *numElements = numElem;
2330:   *fiberDim    = fiberDimMin;
2331:   *array       = (PetscScalar *) section->restrict();
2332:   return(0);
2333: }

2337: PetscErrorCode WritePyLithVertices(Mesh mesh, PetscViewer viewer)
2338: {
2339:   ALE::Obj<ALE::Mesh> m;

2342:   MeshGetMesh(mesh, m);
2343:   return ALE::PyLith::Viewer::writeVertices(m, viewer);
2344: }

2348: PetscErrorCode WritePyLithElements(Mesh mesh, SectionInt material, PetscViewer viewer)
2349: {
2350:   ALE::Obj<ALE::Mesh> m;
2351:   ALE::Obj<ALE::Mesh::int_section_type> s;

2354:   MeshGetMesh(mesh, m);
2355:   SectionIntGetSection(material, s);
2356:   return ALE::PyLith::Viewer::writeElements(m, s, viewer);
2357: }

2361: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2362: {
2363:   ALE::Obj<ALE::Mesh> m;

2366:   MeshGetMesh(mesh, m);
2367:   return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2368: }

2372: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2373: {
2374:   ALE::Obj<ALE::Mesh> m;
2375:   ALE::Obj<ALE::Mesh::int_section_type> s;

2378:   MeshGetMesh(mesh, m);
2379:   SectionIntGetSection(material, s);
2380:   return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2381: }

2383: #if 0
2386: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2387: {
2388:   ALE::Obj<ALE::Mesh> m;

2391:   MeshGetMesh(mesh, m);
2392:   return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2393: }
2394: #endif

2398: /*@C
2399:     MeshCompatGetMesh - Gets the internal mesh object

2401:     Not collective

2403:     Input Parameter:
2404: .    mesh - the mesh object

2406:     Output Parameter:
2407: .    m - the internal mesh object

2409:     Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2410:     developing for that tool.
2411:  
2412:     Level: developer

2414: .seealso MeshCreate(), MeshSetMesh()

2416: @*/
2417: PetscErrorCode  MeshCompatGetMesh(Mesh mesh, ALE::Obj<ALECompat::Mesh>& m)
2418: {
2421:   m = mesh->mcompat;
2422:   return(0);
2423: }

2427: /*@C
2428:     MeshCompatSetMesh - Sets the internal mesh object

2430:     Not collective

2432:     Input Parameters:
2433: +    mesh - the mesh object
2434: -    m - the internal mesh object

2436:     Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2437:     developing for that tool.
2438:  
2439:     Level: developer

2441: .seealso MeshCreate(), MeshGetMesh()

2443: @*/
2444: PetscErrorCode  MeshCompatSetMesh(Mesh mesh, const ALE::Obj<ALECompat::Mesh>& m)
2445: {
2448:   mesh->mcompat = m;
2449:   return(0);
2450: }

2454: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2455: {
2456:   const int end = interval.prefix + interval.index;
2457:   for(int i = interval.index; i < end; i++) {
2458:     indices[indx++] = i;
2459:   }
2460: }

2464: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2465: {
2466:   for(int i = 0; i < interval.prefix; i++) {
2467:     indices[(*indx)++] = interval.index + i;
2468:   }
2469:   for(int i = 0; i < -interval.prefix; i++) {
2470:     indices[(*indx)++] = -1;
2471:   }
2472: }

2476: PetscErrorCode ExpandIntervals(ALE::Obj<ALECompat::Mesh::real_section_type::IndexArray> intervals, PetscInt *indices)
2477: {
2478:   int k = 0;

2481:   for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_itor = intervals->begin(); i_itor != intervals->end(); i_itor++) {
2482:     ExpandInterval_New(*i_itor, indices, &k);
2483:   }
2484:   return(0);
2485: }

2489: template<typename Section>
2490: PetscErrorCode  MeshCompatCreateGlobalScatter(const ALE::Obj<ALECompat::Mesh>& m, const ALE::Obj<Section>& s, VecScatter *scatter)
2491: {
2492:   typedef ALECompat::Mesh::real_section_type::index_type index_type;

2497:   const ALE::Obj<ALECompat::Mesh::topology_type>&                   topology = m->getTopology();
2498:   const ALE::Obj<ALECompat::Mesh::real_section_type::atlas_type>&   atlas    = s->getAtlas();
2499:   const ALECompat::Mesh::real_section_type::patch_type              patch    = 0;
2500:   const ALECompat::Mesh::real_section_type::atlas_type::chart_type& chart    = atlas->getPatch(patch);
2501:   const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(topology, patch, s->getName(), atlas);
2502:   int *localIndices, *globalIndices;
2503:   int  localSize = s->size(patch);
2504:   int  localIndx = 0, globalIndx = 0;
2505:   Vec  globalVec, localVec;
2506:   IS   localIS, globalIS;

2508:   VecCreate(m->comm(), &globalVec);
2509:   VecSetSizes(globalVec, globalOrder->getLocalSize(), PETSC_DETERMINE);
2510:   VecSetFromOptions(globalVec);
2511:   // Loop over all local points
2512:   PetscMalloc(localSize*sizeof(int), &localIndices);
2513:   PetscMalloc(localSize*sizeof(int), &globalIndices);
2514:   for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator p_iter = chart.begin(); p_iter != chart.end(); ++p_iter) {
2515:     const ALECompat::Mesh::real_section_type::index_type& idx = atlas->restrictPoint(patch, *p_iter)[0];

2517:     // Map local indices to global indices
2518:     ExpandInterval(idx, localIndices, localIndx);
2519:     ExpandInterval(index_type(idx.prefix, globalOrder->getIndex(*p_iter)), globalIndices, globalIndx);
2520:   }
2521:   if (localIndx  != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of local indices %d, should be %d", localIndx, localSize);
2522:   if (globalIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of global indices %d, should be %d", globalIndx, localSize);
2523:   if (m->debug()) {
2524:     globalOrder->view("Global Order");
2525:     for(int i = 0; i < localSize; ++i) {
2526:       printf("[%d] localIndex[%d]: %d globalIndex[%d]: %d\n", m->commRank(), i, localIndices[i], i, globalIndices[i]);
2527:     }
2528:   }
2529:   ISCreateGeneral(PETSC_COMM_SELF, localSize, localIndices,  &localIS);
2530:   ISCreateGeneral(PETSC_COMM_SELF, localSize, globalIndices, &globalIS);
2531:   PetscFree(localIndices);
2532:   PetscFree(globalIndices);
2533:   VecCreateSeqWithArray(PETSC_COMM_SELF, localSize, s->restrict(patch), &localVec);
2534:   VecScatterCreate(localVec, localIS, globalVec, globalIS, scatter);
2535:   ISDestroy(globalIS);
2536:   ISDestroy(localIS);
2537:   VecDestroy(localVec);
2538:   VecDestroy(globalVec);
2540:   return(0);
2541: }

2545: PetscErrorCode  MeshCompatGetGlobalScatter(Mesh mesh, VecScatter *scatter)
2546: {

2552:   if (!mesh->globalScatter) {
2553:     ALE::Obj<ALECompat::Mesh> m;

2555:     MeshCompatGetMesh(mesh, m);
2556:     MeshCompatCreateGlobalScatter(m, m->getRealSection("default"), &mesh->globalScatter);
2557:   }
2558:   *scatter = mesh->globalScatter;
2559:   return(0);
2560: }

2564: template<typename Atlas>
2565: PetscErrorCode preallocateOperatorCompat(const ALE::Obj<ALECompat::Mesh::topology_type>& topology, const ALE::Obj<Atlas>& atlas, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, Mat A)
2566: {
2567:   typedef ALECompat::New::NumberingFactory<ALECompat::Mesh::topology_type> NumberingFactory;
2568:   const ALE::Obj<ALECompat::Mesh::sieve_type>     adjGraph    = new ALECompat::Mesh::sieve_type(topology->comm(), topology->debug());
2569:   const ALE::Obj<ALECompat::Mesh::topology_type>  adjTopology = new ALECompat::Mesh::topology_type(topology->comm(), topology->debug());
2570:   const ALECompat::Mesh::real_section_type::patch_type patch  = 0;
2571:   const ALE::Obj<ALECompat::Mesh::sieve_type>&    sieve       = topology->getPatch(patch);
2572:   PetscInt       numLocalRows, firstRow;
2573:   PetscInt      *dnz, *onz;

2577:   adjTopology->setPatch(patch, adjGraph);
2578:   numLocalRows = globalOrder->getLocalSize();
2579:   firstRow     = globalOrder->getGlobalOffsets()[topology->commRank()];
2580:   PetscMalloc2(numLocalRows, PetscInt, &dnz, numLocalRows, PetscInt, &onz);
2581:   /* Create local adjacency graph */
2582:   /*   In general, we need to get FIAT info that attaches dual basis vectors to sieve points */
2583:   const ALECompat::Mesh::real_section_type::atlas_type::chart_type& chart = atlas->getPatch(patch);

2585:   for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2586:     const ALECompat::Mesh::real_section_type::atlas_type::point_type& point = *c_iter;

2588:     adjGraph->addCone(sieve->cone(sieve->support(point)), point);
2589:   }
2590:   /* Distribute adjacency graph */
2591:   topology->constructOverlap(patch);
2592:   const Obj<ALECompat::Mesh::send_overlap_type>& vertexSendOverlap = topology->getSendOverlap();
2593:   const Obj<ALECompat::Mesh::recv_overlap_type>& vertexRecvOverlap = topology->getRecvOverlap();
2594:   const Obj<ALECompat::Mesh::send_overlap_type>  nbrSendOverlap    = new ALECompat::Mesh::send_overlap_type(topology->comm(), topology->debug());
2595:   const Obj<ALECompat::Mesh::recv_overlap_type>  nbrRecvOverlap    = new ALECompat::Mesh::recv_overlap_type(topology->comm(), topology->debug());
2596:   const Obj<ALECompat::Mesh::send_section_type>  sendSection       = new ALECompat::Mesh::send_section_type(topology->comm(), topology->debug());
2597:   const Obj<ALECompat::Mesh::recv_section_type>  recvSection       = new ALECompat::Mesh::recv_section_type(topology->comm(), sendSection->getTag(), topology->debug());

2599:   ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::coneCompletion(vertexSendOverlap, vertexRecvOverlap, adjTopology, sendSection, recvSection);
2600:   /* Distribute indices for new points */
2601:   ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::updateOverlap(sendSection, recvSection, nbrSendOverlap, nbrRecvOverlap);
2602:   NumberingFactory::singleton(topology->debug())->completeOrder(globalOrder, nbrSendOverlap, nbrRecvOverlap, patch, true);
2603:   /* Read out adjacency graph */
2604:   const ALE::Obj<ALECompat::Mesh::sieve_type> graph = adjTopology->getPatch(patch);

2606:   PetscMemzero(dnz, numLocalRows * sizeof(PetscInt));
2607:   PetscMemzero(onz, numLocalRows * sizeof(PetscInt));
2608:   for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2609:     const ALECompat::Mesh::real_section_type::atlas_type::point_type& point = *c_iter;

2611:     if (globalOrder->isLocal(point)) {
2612:       const ALE::Obj<ALECompat::Mesh::sieve_type::traits::coneSequence>& adj   = graph->cone(point);
2613:       const ALECompat::Mesh::order_type::value_type&          rIdx  = globalOrder->restrictPoint(patch, point)[0];
2614:       const int                                               row   = rIdx.prefix;
2615:       const int                                               rSize = rIdx.index;

2617:       for(ALECompat::Mesh::sieve_type::traits::coneSequence::iterator v_iter = adj->begin(); v_iter != adj->end(); ++v_iter) {
2618:         const ALECompat::Mesh::real_section_type::atlas_type::point_type& neighbor = *v_iter;
2619:         const ALECompat::Mesh::order_type::value_type& cIdx     = globalOrder->restrictPoint(patch, neighbor)[0];
2620:         const int&                                     cSize    = cIdx.index;

2622:         if (cSize > 0) {
2623:           if (globalOrder->isLocal(neighbor)) {
2624:             for(int r = 0; r < rSize; ++r) {dnz[row - firstRow + r] += cSize;}
2625:           } else {
2626:             for(int r = 0; r < rSize; ++r) {onz[row - firstRow + r] += cSize;}
2627:           }
2628:         }
2629:       }
2630:     }
2631:   }
2632:   if (topology->debug()) {
2633:     int rank = topology->commRank();
2634:     for(int r = 0; r < numLocalRows; r++) {
2635:       std::cout << "["<<rank<<"]: dnz["<<r<<"]: " << dnz[r] << " onz["<<r<<"]: " << onz[r] << std::endl;
2636:     }
2637:   }
2638:   MatSeqAIJSetPreallocation(A, 0, dnz);
2639:   MatMPIAIJSetPreallocation(A, 0, dnz, 0, onz);
2640:   PetscFree2(dnz, onz);
2641:   MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);
2642:   return(0);
2643: }

2647: PetscErrorCode preallocateMatrixCompat(const ALE::Obj<ALECompat::Mesh::topology_type>& topology, const ALE::Obj<ALECompat::Mesh::real_section_type::atlas_type>& atlas, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, Mat A)
2648: {
2649:   return preallocateOperatorCompat(topology, atlas, globalOrder, A);
2650: }

2654: PetscErrorCode updateOperatorCompat(Mat A, const ALE::Obj<ALECompat::Mesh::real_section_type>& section, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, const ALECompat::Mesh::point_type& e, PetscScalar array[], InsertMode mode)
2655: {
2656:   ALECompat::Mesh::real_section_type::patch_type patch = 0;
2657:   static PetscInt  indicesSize = 0;
2658:   static PetscInt *indices = NULL;
2659:   PetscInt         numIndices = 0;
2660:   PetscErrorCode   ierr;

2663:   const ALE::Obj<ALECompat::Mesh::real_section_type::IndexArray> intervals = section->getIndices(patch, e, globalOrder);

2666:   if (section->debug()) {printf("[%d]mat for element %d\n", section->commRank(), e);}
2667:   for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_iter = intervals->begin(); i_iter != intervals->end(); ++i_iter) {
2668:     numIndices += std::abs(i_iter->prefix);
2669:     if (section->debug()) {
2670:       printf("[%d]mat interval (%d, %d)\n", section->commRank(), i_iter->prefix, i_iter->index);
2671:     }
2672:   }
2673:   if (indicesSize && (indicesSize != numIndices)) {
2674:     PetscFree(indices);
2675:     indices = NULL;
2676:   }
2677:   if (!indices) {
2678:     indicesSize = numIndices;
2679:     PetscMalloc(indicesSize * sizeof(PetscInt), &indices);
2680:   }
2681:   ExpandIntervals(intervals, indices);
2682:   if (section->debug()) {
2683:     for(int i = 0; i < numIndices; i++) {
2684:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2685:     }
2686:     for(int i = 0; i < numIndices; i++) {
2687:       printf("[%d]", section->commRank());
2688:       for(int j = 0; j < numIndices; j++) {
2689:         printf(" %g", array[i*numIndices+j]);
2690:       }
2691:       printf("\n");
2692:     }
2693:   }
2694:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
2695:   if (ierr) {
2696:     printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
2697:     for(int i = 0; i < numIndices; i++) {
2698:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2699:     }
2700: 
2701:   }
2703:   return(0);
2704: }

2708: /*@C
2709:   MeshCompatCreatePyLith - Create a Mesh from PyLith files.

2711:   Not Collective

2713:   Input Parameters:
2714: + dim - The topological mesh dimension
2715: . baseFilename - The basename for mesh files
2716: . zeroBase - Use 0 to start numbering
2717: - interpolate - The flag for mesh interpolation

2719:   Output Parameter:
2720: . mesh - The Mesh object

2722:   Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2723:   developing for that tool.

2725:   Level: developer

2727: .keywords: mesh, PCICE
2728: .seealso: MeshCreate()
2729: @*/
2730: PetscErrorCode MeshCompatCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
2731: {
2732:   ALE::Obj<ALECompat::Mesh> m;
2733:   PetscInt            debug = 0;
2734:   PetscTruth          flag;
2735:   PetscErrorCode      ierr;

2738:   MeshCreate(comm, mesh);
2739:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
2740:   try {
2741:     m  = ALECompat::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
2742:   } catch(ALE::Exception e) {
2743:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
2744:   }
2745:   MeshCompatSetMesh(*mesh, m);
2746:   return(0);
2747: }