Actual source code: mesh.c

  1: 
 2:  #include private/meshimpl.h
  3: #include <Distribution.hh>
  4: #include <Generator.hh>
 5:  #include src/dm/mesh/meshvtk.h
 6:  #include src/dm/mesh/meshpcice.h
 7:  #include src/dm/mesh/meshpylith.h

  9: /* Logging support */
 10: PetscCookie  MESH_COOKIE = 0;
 11: PetscEvent  Mesh_View = 0, Mesh_GetGlobalScatter = 0, Mesh_restrictVector = 0, Mesh_assembleVector = 0,
 12:             Mesh_assembleVectorComplete = 0, Mesh_assembleMatrix = 0, Mesh_updateOperator = 0;

 14: PetscTruth MeshRegisterAllCalled = PETSC_FALSE;
 15: PetscFList MeshList;

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

 22: 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);

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

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


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

 45: PetscErrorCode MeshFinalize()
 46: {
 48:   ALE::Mesh::NumberingFactory::singleton(0, 0, true);
 49:   return(0);
 50: }

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

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

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

 94:     PetscViewerFileGetName(viewer, &filename);

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

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

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

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

144: PetscErrorCode MeshCompatView_Sieve_Ascii(const ALE::Obj<ALECompat::Mesh>& mesh, PetscViewer viewer)
145: {
146:   PetscViewerFormat format;
147:   PetscErrorCode    ierr;

150:   PetscViewerGetFormat(viewer, &format);
151:   if (format == PETSC_VIEWER_ASCII_PYLITH) {
152:     char *filename;
153:     char  connectFilename[2048];
154:     char  coordFilename[2048];

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

180:     PetscViewerFileGetName(viewer, &filename);

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

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

198:     if (mesh->hasPairSection("split")) {
199:       PetscViewer splitViewer;

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

210:     if (mesh->hasRealSection("traction")) {
211:       PetscViewer tractionViewer;

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

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

236: PetscErrorCode MeshView_Sieve(const ALE::Obj<ALE::Mesh>& mesh, PetscViewer viewer)
237: {
238:   PetscTruth     iascii, isbinary, isdraw;

242:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
243:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
244:   PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);

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

260: PetscErrorCode  MeshView_Mesh(Mesh mesh, PetscViewer viewer)
261: {

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

275: /*@C
276:    MeshView - Views a Mesh object. 

278:    Collective on Mesh

280:    Input Parameters:
281: +  mesh - the mesh
282: -  viewer - an optional visualization context

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

292:    You can change the format the mesh is printed using the 
293:    option PetscViewerSetFormat().

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

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

307:    Level: beginner

309:    Concepts: mesh^printing
310:    Concepts: mesh^saving to disk

312: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
313:           MeshLoad(), PetscViewerCreate()
314: @*/
315: PetscErrorCode  MeshView(Mesh mesh, PetscViewer viewer)
316: {

322:   if (!viewer) {
323:     PetscViewerASCIIGetStdout(mesh->comm,&viewer);
324:   }

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

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

339:     Collective on Viewer

341:     Input Parameter:
342: .   viewer - The viewer containing the data

344:     Output Parameters:
345: .   mesh - the mesh object

347:     Level: advanced

349: .seealso MeshView()

351: @*/
352: PetscErrorCode  MeshLoad(PetscViewer viewer, Mesh *mesh)
353: {
354:   SETERRQ(PETSC_ERR_SUP, "");
355: }

359: /*@C
360:     MeshGetMesh - Gets the internal mesh object

362:     Not collective

364:     Input Parameter:
365: .    mesh - the mesh object

367:     Output Parameter:
368: .    m - the internal mesh object
369:  
370:     Level: advanced

372: .seealso MeshCreate(), MeshSetMesh()

374: @*/
375: PetscErrorCode  MeshGetMesh(Mesh mesh, ALE::Obj<ALE::Mesh>& m)
376: {
379:   m = mesh->m;
380:   return(0);
381: }

385: /*@C
386:     MeshSetMesh - Sets the internal mesh object

388:     Not collective

390:     Input Parameters:
391: +    mesh - the mesh object
392: -    m - the internal mesh object
393:  
394:     Level: advanced

396: .seealso MeshCreate(), MeshGetMesh()

398: @*/
399: PetscErrorCode  MeshSetMesh(Mesh mesh, const ALE::Obj<ALE::Mesh>& m)
400: {
403:   mesh->m = m;
404:   return(0);
405: }

409: template<typename Section>
410: PetscErrorCode  MeshCreateMatrix(const Obj<ALE::Mesh>& mesh, const Obj<Section>& section, MatType mtype, Mat *J)
411: {
412:   const ALE::Obj<typename ALE::Mesh::order_type>& order = mesh->getFactory()->getGlobalOrder(mesh, "default", section);
413:   int            localSize  = order->getLocalSize();
414:   int            globalSize = order->getGlobalSize();
415:   PetscTruth     isShell, isBlock, isSeqBlock, isMPIBlock;

419:   MatCreate(mesh->comm(), J);
420:   MatSetSizes(*J, localSize, localSize, globalSize, globalSize);
421:   MatSetType(*J, mtype);
422:   MatSetFromOptions(*J);
423:   PetscStrcmp(mtype, MATSHELL, &isShell);
424:   PetscStrcmp(mtype, MATBAIJ, &isBlock);
425:   PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);
426:   PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);
427:   if (!isShell) {
428:     int bs = 1;

430:     if (isBlock || isSeqBlock || isMPIBlock) {
431:       bs = section->getFiberDimension(*section->getChart().begin());
432:     }
433:     preallocateOperator(mesh, bs, section->getAtlas(), order, *J);
434:   }
435:   return(0);
436: }

440: PetscErrorCode  MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
441: {
442:   ALE::Obj<ALE::Mesh> m;
443:   ALE::Obj<ALE::Mesh::real_section_type> s;

447:   MeshGetMesh(mesh, m);
448:   SectionRealGetSection(section, s);
449:   MeshCreateMatrix(m, s, mtype, J);
450:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
451:   return(0);
452: }

456: PetscErrorCode  MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
457: {
458:   SectionReal    section;

462:   MeshGetVertexSectionReal(mesh, 1, &section);
463:   MeshCreateMatrix(mesh, section, mtype, J);
464:   SectionRealDestroy(section);
465:   return(0);
466: }

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

474:     Collective on Mesh

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

481:     Output Parameters:
482: .   J  - matrix with the correct nonzero preallocation
483:         (obviously without the correct Jacobian values)

485:     Level: advanced

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

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

492: @*/
493: PetscErrorCode  MeshGetMatrix(Mesh mesh, MatType mtype, Mat *J)
494: {
495:   ALE::Obj<ALE::Mesh> m;
496:   PetscTruth          flag;
497:   PetscErrorCode      ierr;

500:   MeshHasSectionReal(mesh, "default", &flag);
501:   if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
502:   MeshGetMesh(mesh, m);
503:   MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
504:   PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
505:   return(0);
506: }

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

514:     Collective on MPI_Comm

516:     Input Parameter:
517: .   comm - the processors that will share the global vector

519:     Output Parameters:
520: .   mesh - the mesh object

522:     Level: advanced

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

526: @*/
527: PetscErrorCode  MeshCreate(MPI_Comm comm,Mesh *mesh)
528: {
530:   Mesh         p;

534:   *mesh = PETSC_NULL;
535: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
536:   DMInitializePackage(PETSC_NULL);
537: #endif

539:   PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
540:   p->ops->view               = MeshView_Mesh;
541:   p->ops->destroy            = PETSC_NULL;
542:   p->ops->createglobalvector = MeshCreateGlobalVector;
543:   p->ops->getcoloring        = PETSC_NULL;
544:   p->ops->getmatrix          = MeshGetMatrix;
545:   p->ops->getinterpolation   = MeshGetInterpolation_Mesh;
546:   p->ops->getinjection       = PETSC_NULL;
547:   p->ops->refine             = MeshRefine_Mesh;
548:   p->ops->coarsen            = PETSC_NULL;
549:   p->ops->refinehierarchy    = PETSC_NULL;
550:   p->ops->coarsenhierarchy   = MeshCoarsenHierarchy_Mesh;

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

554:   p->m             = PETSC_NULL;
555:   p->globalScatter = PETSC_NULL;
556:   p->lf            = PETSC_NULL;
557:   p->lj            = PETSC_NULL;
558:   p->mcompat       = PETSC_NULL;
559:   p->data          = PETSC_NULL;
560:   *mesh = p;
561:   return(0);
562: }

566: /*@
567:     MeshDestroy - Destroys a mesh.

569:     Collective on Mesh

571:     Input Parameter:
572: .   mesh - the mesh object

574:     Level: advanced

576: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
577: @*/
578: PetscErrorCode  MeshDestroy(Mesh mesh)
579: {
580:   PetscErrorCode     ierr;

583:   if (--mesh->refct > 0) return(0);
584:   if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
585:   mesh->m = PETSC_NULL;
586:   PetscHeaderDestroy(mesh);
587:   return(0);
588: }

592: /*@C
593:   MeshSetType - Sets the Mesh type

595:   Collective on Mesh

597:   Input Parameters:
598: + mesh - the Mesh context
599: - type - the type

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

605:   Notes:
606:   See "petsc/include/petscmesh.h" for available types (for instance,
607:   MESHCARTESIAN or MESHSIEVE).

609:   Level: intermediate

611: .keywords: Mesh, set, typr
612: .seealso: MeshGetType(), MeshType
613: @*/
614: PetscErrorCode  MeshSetType(Mesh mesh, MeshType type)
615: {
616:   PetscErrorCode ierr,(*r)(Mesh);
617:   PetscTruth     match;


623:   PetscTypeCompare((PetscObject)mesh,type,&match);
624:   if (match) return(0);

626:    PetscFListFind(MeshList,mesh->comm,type,(void (**)(void)) &r);
627:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
628:   /* Destroy the previous private Mesh context */
629:   if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
630:   /* Reinitialize function pointers in MeshOps structure */
631:   PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
632:   /* Call the MeshCreate_XXX routine for this particular mesh */
633:   (*r)(mesh);
634:   PetscObjectChangeTypeName((PetscObject) mesh, type);
635:   return(0);
636: }

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

643:   Not Collective

645:   Input Parameter:
646: . mesh - Mesh context 

648:   Output Parameter:
649: . name - name of Mesh type 

651:   Level: intermediate

653: .keywords: Mesh, get, type
654: .seealso: MeshSetType()
655: @*/
656: PetscErrorCode  MeshGetType(Mesh mesh,MeshType *type)
657: {
661:   *type = mesh->type_name;
662:   return(0);
663: }

667: /*@C
668:   MeshRegister - See MeshRegisterDynamic()

670:   Level: advanced
671: @*/
672: PetscErrorCode  MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
673: {
675:   char           fullname[PETSC_MAX_PATH_LEN];

678:   PetscFListConcat(path,name,fullname);
679:   PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
680:   return(0);
681: }

684: EXTERN PetscErrorCode  MeshCreate_Cartesian(Mesh);

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

692:   Not Collective

694:   Level: advanced

696: .keywords: Mesh, register, all
697: .seealso:  MeshRegisterDestroy()
698: @*/
699: PetscErrorCode  MeshRegisterAll(const char path[])
700: {

704:   MeshRegisterAllCalled = PETSC_TRUE;

706:   MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
707:   return(0);
708: }

712: /*@
713:   MeshRegisterDestroy - Frees the list of Mesh types that were
714:   registered by MeshRegister().

716:   Not Collective

718:   Level: advanced

720: .keywords: Mesh, register, destroy
721: .seealso: MeshRegister(), MeshRegisterAll()
722: @*/
723: PetscErrorCode  MeshRegisterDestroy(void)
724: {

728:   PetscFListDestroy(&MeshList);
729:   MeshRegisterAllCalled = PETSC_FALSE;
730:   return(0);
731: }

735: /*@C
736:     MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into 
737:         by the mesh.

739:     Collective on Mesh

741:     Input Parameter:
742: .    mesh - the mesh object

744:     Output Parameters:
745: .   gvec - the global vector

747:     Level: advanced

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

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

753: @*/
754: PetscErrorCode  MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
755: {
756:   ALE::Obj<ALE::Mesh> m;
757:   PetscTruth     flag;

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

766:   VecCreate(m->comm(), gvec);
767:   VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
768:   VecSetFromOptions(*gvec);
769:   return(0);
770: }

774: /*@C
775:     MeshGetGlobalIndices - Gets the global indices for all the local entries

777:     Collective on Mesh

779:     Input Parameter:
780: .    mesh - the mesh object

782:     Output Parameters:
783: .    idx - the individual indices for each packed vector/array
784:  
785:     Level: advanced

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

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

792: @*/
793: PetscErrorCode  MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
794: {
795:   SETERRQ(PETSC_ERR_SUP, "");
796: }

800: PetscErrorCode  MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
801: {
802:   ALE::Obj<ALE::Mesh> m;
803:   ALE::Obj<ALE::Mesh::real_section_type> s;

807:   MeshGetMesh(mesh, m);
808:   SectionRealGetSection(section, s);
809:   MeshCreateGlobalScatter(m, s, scatter);
810:   return(0);
811: }

815: template<typename Section>
816: PetscErrorCode  MeshCreateGlobalScatter(const ALE::Obj<ALE::Mesh>& m, const ALE::Obj<Section>& s, VecScatter *scatter)
817: {
818:   typedef ALE::Mesh::real_section_type::index_type index_type;

823:   const ALE::Mesh::real_section_type::chart_type& chart       = s->getChart();
824:   const ALE::Obj<ALE::Mesh::order_type>&          globalOrder = m->getFactory()->getGlobalOrder(m, s->getName(), s);
825:   int *localIndices, *globalIndices;
826:   int  localSize = s->size();
827:   int  localIndx = 0, globalIndx = 0;
828:   Vec  globalVec, localVec;
829:   IS   localIS, globalIS;

831:   VecCreate(m->comm(), &globalVec);
832:   VecSetSizes(globalVec, globalOrder->getLocalSize(), PETSC_DETERMINE);
833:   VecSetFromOptions(globalVec);
834:   // Loop over all local points
835:   PetscMalloc(localSize*sizeof(int), &localIndices);
836:   PetscMalloc(localSize*sizeof(int), &globalIndices);
837:   for(ALE::Mesh::real_section_type::chart_type::const_iterator p_iter = chart.begin(); p_iter != chart.end(); ++p_iter) {
838:     // Map local indices to global indices
839:     s->getIndices(*p_iter, localIndices, &localIndx, 0, true);
840:     s->getIndices(*p_iter, globalOrder, globalIndices, &globalIndx, 0, true);
841:   }
842:   if (localIndx  != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of local indices %d, should be %d", localIndx, localSize);
843:   if (globalIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of global indices %d, should be %d", globalIndx, localSize);
844:   if (m->debug()) {
845:     globalOrder->view("Global Order");
846:     for(int i = 0; i < localSize; ++i) {
847:       printf("[%d] localIndex[%d]: %d globalIndex[%d]: %d\n", m->commRank(), i, localIndices[i], i, globalIndices[i]);
848:     }
849:   }
850:   ISCreateGeneral(PETSC_COMM_SELF, localSize, localIndices,  &localIS);
851:   ISCreateGeneral(PETSC_COMM_SELF, localSize, globalIndices, &globalIS);
852:   PetscFree(localIndices);
853:   PetscFree(globalIndices);
854:   VecCreateSeqWithArray(PETSC_COMM_SELF, s->sizeWithBC(), s->restrict(), &localVec);
855:   VecScatterCreate(localVec, localIS, globalVec, globalIS, scatter);
856:   ISDestroy(globalIS);
857:   ISDestroy(localIS);
858:   VecDestroy(localVec);
859:   VecDestroy(globalVec);
861:   return(0);
862: }

866: PetscErrorCode  MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
867: {

873:   if (!mesh->globalScatter) {
874:     SectionReal section;

876:     MeshGetSectionReal(mesh, "default", &section);
877:     MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
878:     SectionRealDestroy(section);
879:   }
880:   *scatter = mesh->globalScatter;
881:   return(0);
882: }

886: PetscErrorCode  MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
887: {
890:   mesh->lf = lf;
891:   return(0);
892: }

896: PetscErrorCode  MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
897: {
900:   mesh->lj = lj;
901:   return(0);
902: }

906: PetscErrorCode  MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
907: {

914:   if (mesh->lf) {
915:     (*mesh->lf)(mesh, X, F, ctx);
916:   }
917:   return(0);
918: }

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

930:   if (mesh->lj) {
931:     (*mesh->lj)(mesh, X, J, ctx);
932:   }
933:   return(0);
934: }

938: // Here we assume:
939: //  - Assumes 3D and tetrahedron
940: //  - The section takes values on vertices and is P1
941: //  - Points have the same dimension as the mesh
942: //  - All values have the same dimension
943: PetscErrorCode  MeshInterpolatePoints(Mesh mesh, SectionReal section, int numPoints, double *points, double **values)
944: {
945:   Obj<ALE::Mesh> m;
946:   Obj<ALE::Mesh::real_section_type> s;
947:   double        *v0, *J, *invJ, detJ;

951:   MeshGetMesh(mesh, m);
952:   SectionRealGetSection(section, s);
953:   const Obj<ALE::Mesh::real_section_type>& coordinates = m->getRealSection("coordinates");
954:   int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
955:   int dim      = s->getFiberDimension(*m->depthStratum(0)->begin());

957:   PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
958:   PetscMalloc(numPoints*dim * sizeof(double), &values);
959:   for(int p = 0; p < numPoints; p++) {
960:     double *point = &points[p*embedDim];
961:     ALE::Mesh::point_type e = m->locatePoint(point);
962:     const ALE::Mesh::real_section_type::value_type *coeff = s->restrictPoint(e);

964:     m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
965:     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;
966:     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;
967:     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;

969:     for(int d = 0; d < dim; d++) {
970:       (*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;
971:     }
972:   }
973:   PetscFree3(v0, J, invJ);
974:   return(0);
975: }

979: /*@
980:   MeshGetMaximumDegree - Return the maximum degree of any mesh vertex

982:   Collective on mesh

984:   Input Parameter:
985: . mesh - The Mesh

987:   Output Parameter:
988: . maxDegree - The maximum number of edges at any vertex

990:    Level: beginner

992: .seealso: MeshCreate()
993: @*/
994: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
995: {
996:   Obj<ALE::Mesh> m;

1000:   MeshGetMesh(mesh, m);
1001:   const ALE::Obj<ALE::Mesh::label_sequence>& vertices = m->depthStratum(0);
1002:   const ALE::Obj<ALE::Mesh::sieve_type>&     sieve    = m->getSieve();
1003:   PetscInt                                          maxDeg   = -1;

1005:   for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
1006:     maxDeg = PetscMax(maxDeg, (PetscInt) sieve->support(*v_iter)->size());
1007:   }
1008:   *maxDegree = maxDeg;
1009:   return(0);
1010: }

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

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

1019:   Collective on g

1021:   Input Parameters:
1022: + g - The global vector
1023: . l - The local vector
1024: - mode - either ADD_VALUES or INSERT_VALUES, where
1025:    ADD_VALUES adds values to any existing entries, and
1026:    INSERT_VALUES replaces existing entries with new values

1028:    Level: beginner

1030: .seealso: MatSetOption()
1031: @*/
1032: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1033: {
1034:   VecScatter     injection;

1039:   PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1040:   if (injection) {
1041:     VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
1042:     VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
1043:   } else {
1044:     if (mode == INSERT_VALUES) {
1045:       VecCopy(g, l);
1046:     } else {
1047:       VecAXPY(l, 1.0, g);
1048:     }
1049:   }
1051:   return(0);
1052: }

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

1059:   Collective on g

1061:   Input Parameters:
1062: + g - The global vector
1063: . l - The local vector
1064: - mode - either ADD_VALUES or INSERT_VALUES, where
1065:    ADD_VALUES adds values to any existing entries, and
1066:    INSERT_VALUES replaces existing entries with new values

1068:    Level: beginner

1070: .seealso: MatSetOption()
1071: @*/
1072: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1073: {
1074:   VecScatter     injection;

1079:   PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1080:   if (injection) {
1081:     VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1082:     VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1083:   } else {
1084:     if (mode == INSERT_VALUES) {
1085:       VecCopy(l, g);
1086:     } else {
1087:       VecAXPY(g, 1.0, l);
1088:     }
1089:   }
1091:   return(0);
1092: }

1096: /*@C
1097:   assembleVector - Insert values into a vector

1099:   Collective on A

1101:   Input Parameters:
1102: + b - the vector
1103: . e - The element number
1104: . v - The values
1105: - mode - either ADD_VALUES or INSERT_VALUES, where
1106:    ADD_VALUES adds values to any existing entries, and
1107:    INSERT_VALUES replaces existing entries with new values

1109:    Level: beginner

1111: .seealso: VecSetOption()
1112: @*/
1113: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1114: {
1115:   Mesh                       mesh;
1116:   ALE::Obj<ALE::Mesh> m;
1117:   PetscInt                   firstElement;
1118:   PetscErrorCode             ierr;

1122:   PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1123:   MeshGetMesh(mesh, m);
1124:   //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1125:   firstElement = 0;
1126:   // Must relate b to field
1127:   if (mode == INSERT_VALUES) {
1128:     m->update(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1129:   } else {
1130:     m->updateAdd(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1131:   }
1133:   return(0);
1134: }

1138: 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)
1139: {

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

1148:   if (section->debug()) {
1149:     printf("[%d]mat for element %d\n", section->commRank(), e);
1150:     for(int i = 0; i < numIndices; i++) {
1151:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1152:     }
1153:     for(int i = 0; i < numIndices; i++) {
1154:       printf("[%d]", section->commRank());
1155:       for(int j = 0; j < numIndices; j++) {
1156:         printf(" %g", array[i*numIndices+j]);
1157:       }
1158:       printf("\n");
1159:     }
1160:   }
1161:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1162:   if (ierr) {
1163:     printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
1164:     for(int i = 0; i < numIndices; i++) {
1165:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1166:     }
1167: 
1168:   }
1170:   return(0);
1171: }

1175: 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)
1176: {

1180:   const ALE::Mesh::indices_type rowIndicesBlock = rowM->getIndices(rowSection, rowE, rowGlobalOrder);
1181:   const PetscInt *rowIndices    = rowIndicesBlock.first;
1182:   const int&      numRowIndices = rowIndicesBlock.second;
1183:   const ALE::Mesh::indices_type colIndicesBlock = colM->getIndices(colSection, colE, colGlobalOrder);
1184:   const PetscInt *colIndices    = colIndicesBlock.first;
1185:   const int&      numColIndices = colIndicesBlock.second;

1188:   if (rowSection->debug()) {
1189:     printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1190:     for(int i = 0; i < numRowIndices; i++) {
1191:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1192:     }
1193:   }
1194:   if (colSection->debug()) {
1195:     for(int i = 0; i < numColIndices; i++) {
1196:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1197:     }
1198:     for(int i = 0; i < numRowIndices; i++) {
1199:       printf("[%d]", rowSection->commRank());
1200:       for(int j = 0; j < numColIndices; j++) {
1201:         printf(" %g", array[i*numColIndices+j]);
1202:       }
1203:       printf("\n");
1204:     }
1205:   }
1206:   MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1207:   if (ierr) {
1208:     printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1209:     for(int i = 0; i < numRowIndices; i++) {
1210:       printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1211:     }
1212:     for(int i = 0; i < numColIndices; i++) {
1213:       printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1214:     }
1215: 
1216:   }
1218:   return(0);
1219: }

1223: /*@C
1224:   assembleMatrix - Insert values into a matrix

1226:   Collective on A

1228:   Input Parameters:
1229: + A - the matrix
1230: . e - The element number
1231: . v - The values
1232: - mode - either ADD_VALUES or INSERT_VALUES, where
1233:    ADD_VALUES adds values to any existing entries, and
1234:    INSERT_VALUES replaces existing entries with new values

1236:    Level: beginner

1238: .seealso: MatSetOption()
1239: @*/
1240: PetscErrorCode assembleMatrix(Mat A, PetscInt e, PetscScalar v[], InsertMode mode)
1241: {
1242:   Mesh           mesh;

1247:   PetscObjectQuery((PetscObject) A, "mesh", (PetscObject *) &mesh);
1248:   try {
1249:     if (!mesh->mcompat.isNull()) {
1250:       Obj<ALECompat::Mesh> m;

1252:       MeshCompatGetMesh(mesh, m);
1253:       const ALE::Obj<ALECompat::Mesh::topology_type>&     topology    = m->getTopology();
1254:       const ALE::Obj<ALECompat::Mesh::numbering_type>&    cNumbering  = m->getFactory()->getLocalNumbering(topology, 0, topology->depth());
1255:       const ALE::Obj<ALECompat::Mesh::real_section_type>& s           = m->getRealSection("default");
1256:       const ALE::Obj<ALECompat::Mesh::order_type>&        globalOrder = m->getFactory()->getGlobalOrder(topology, 0, "default", s->getAtlas());

1258:       if (m->debug()) {
1259:         std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1260:       }
1261:       updateOperatorCompat(A, s, globalOrder, cNumbering->getPoint(e), v, mode);
1262:     } else {
1263:       Obj<ALE::Mesh> m;

1265:       MeshGetMesh(mesh, m);
1266:       const ALE::Obj<ALE::Mesh::numbering_type>&    cNumbering  = m->getFactory()->getLocalNumbering(m, m->depth());
1267:       const ALE::Obj<ALE::Mesh::real_section_type>& s           = m->getRealSection("default");
1268:       const ALE::Obj<ALE::Mesh::order_type>&        globalOrder = m->getFactory()->getGlobalOrder(m, "default", s);

1270:       if (m->debug()) {
1271:         std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1272:       }
1273:       updateOperator(A, m, s, globalOrder, cNumbering->getPoint(e), v, mode);
1274:     }
1275:   } catch (ALE::Exception e) {
1276:     std::cout << e.msg() << std::endl;
1277:   }
1279:   return(0);
1280: }

1284: template<typename Atlas>
1285: PetscErrorCode preallocateOperator(const ALE::Obj<ALE::Mesh>& mesh, const int bs, const ALE::Obj<Atlas>& atlas, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, Mat A)
1286: {
1287:   typedef ALE::SieveAlg<ALE::Mesh> sieve_alg_type;
1288:   MPI_Comm                              comm      = mesh->comm();
1289:   const ALE::Obj<ALE::Mesh>             adjBundle = new ALE::Mesh(comm, mesh->debug());
1290:   const ALE::Obj<ALE::Mesh::sieve_type> adjGraph  = new ALE::Mesh::sieve_type(comm, mesh->debug());
1291:   PetscInt       numLocalRows, firstRow;
1292:   PetscInt      *dnz, *onz;

1296:   adjBundle->setSieve(adjGraph);
1297:   numLocalRows = globalOrder->getLocalSize();
1298:   firstRow     = globalOrder->getGlobalOffsets()[mesh->commRank()];
1299:   PetscMalloc2(numLocalRows, PetscInt, &dnz, numLocalRows, PetscInt, &onz);
1300:   /* Create local adjacency graph */
1301:   /*   In general, we need to get FIAT info that attaches dual basis vectors to sieve points */
1302:   const typename Atlas::chart_type& chart = atlas->getChart();

1304:   for(typename Atlas::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
1305:     const Obj<typename sieve_alg_type::supportArray>& star = sieve_alg_type::star(mesh, *c_iter);

1307:     for(typename sieve_alg_type::supportArray::const_iterator s_iter = star->begin(); s_iter != star->end(); ++s_iter) {
1308:       const Obj<typename sieve_alg_type::coneArray>& closure = sieve_alg_type::closure(mesh, *s_iter);

1310:       for(typename sieve_alg_type::coneArray::const_iterator cl_iter = closure->begin(); cl_iter != closure->end(); ++cl_iter) {
1311:         adjGraph->addCone(*cl_iter, *c_iter);
1312:       }
1313:     }
1314:   }
1315:   /* Distribute adjacency graph */
1316:   adjBundle->constructOverlap();
1317:   typedef typename ALE::Mesh::sieve_type::point_type point_type;
1318:   typedef typename ALE::Mesh::send_overlap_type send_overlap_type;
1319:   typedef typename ALE::Mesh::recv_overlap_type recv_overlap_type;
1320:   typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, point_type> > send_section_type;
1321:   typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, point_type> > recv_section_type;
1322:   const Obj<send_overlap_type>& vertexSendOverlap = mesh->getSendOverlap();
1323:   const Obj<recv_overlap_type>& vertexRecvOverlap = mesh->getRecvOverlap();
1324:   const Obj<send_overlap_type>  nbrSendOverlap    = new send_overlap_type(comm, mesh->debug());
1325:   const Obj<recv_overlap_type>  nbrRecvOverlap    = new recv_overlap_type(comm, mesh->debug());
1326:   const Obj<send_section_type>  sendSection       = new send_section_type(comm, mesh->debug());
1327:   const Obj<recv_section_type>  recvSection       = new recv_section_type(comm, sendSection->getTag(), mesh->debug());

1329:   ALE::Distribution<ALE::Mesh>::coneCompletion(vertexSendOverlap, vertexRecvOverlap, adjBundle, sendSection, recvSection);
1330:   /* Distribute indices for new points */
1331:   ALE::Distribution<ALE::Mesh>::updateOverlap(sendSection, recvSection, nbrSendOverlap, nbrRecvOverlap);
1332:   mesh->getFactory()->completeOrder(globalOrder, nbrSendOverlap, nbrRecvOverlap, true);
1333:   /* Read out adjacency graph */
1334:   const ALE::Obj<ALE::Mesh::sieve_type> graph = adjBundle->getSieve();

1336:   PetscMemzero(dnz, numLocalRows/bs * sizeof(PetscInt));
1337:   PetscMemzero(onz, numLocalRows/bs * sizeof(PetscInt));
1338:   for(typename Atlas::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
1339:     const typename Atlas::point_type& point = *c_iter;

1341:     if (globalOrder->isLocal(point)) {
1342:       const ALE::Obj<ALE::Mesh::sieve_type::traits::coneSequence>& adj   = graph->cone(point);
1343:       const ALE::Mesh::order_type::value_type&                     rIdx  = globalOrder->restrictPoint(point)[0];
1344:       const int                                                    row   = rIdx.prefix;
1345:       const int                                                    rSize = rIdx.index/bs;

1347:       if (rSize == 0) continue;
1348:       for(ALE::Mesh::sieve_type::traits::coneSequence::iterator v_iter = adj->begin(); v_iter != adj->end(); ++v_iter) {
1349:         const ALE::Mesh::point_type&             neighbor = *v_iter;
1350:         const ALE::Mesh::order_type::value_type& cIdx     = globalOrder->restrictPoint(neighbor)[0];
1351:         const int&                               cSize    = cIdx.index/bs;

1353:         if (cSize > 0) {
1354:           if (globalOrder->isLocal(neighbor)) {
1355:             for(int r = 0; r < rSize; ++r) {dnz[(row - firstRow)/bs + r] += cSize;}
1356:           } else {
1357:             for(int r = 0; r < rSize; ++r) {onz[(row - firstRow)/bs + r] += cSize;}
1358:           }
1359:         }
1360:       }
1361:     }
1362:   }
1363:   if (mesh->debug()) {
1364:     int rank = mesh->commRank();
1365:     for(int r = 0; r < numLocalRows/bs; r++) {
1366:       std::cout << "["<<rank<<"]: dnz["<<r<<"]: " << dnz[r] << " onz["<<r<<"]: " << onz[r] << std::endl;
1367:     }
1368:   }
1369:   MatSeqAIJSetPreallocation(A, 0, dnz);
1370:   MatMPIAIJSetPreallocation(A, 0, dnz, 0, onz);
1371:   MatSeqBAIJSetPreallocation(A, bs, 0, dnz);
1372:   MatMPIBAIJSetPreallocation(A, bs, 0, dnz, 0, onz);
1373:   PetscFree2(dnz, onz);
1374:   MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR);
1375:   return(0);
1376: }

1380: 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)
1381: {
1382:   return preallocateOperator(mesh, bs, atlas, globalOrder, A);
1383: }

1385: /******************************** C Wrappers **********************************/

1389: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1390: {
1391:   return VTKViewer::writeHeader(viewer);
1392: }

1396: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1397: {
1398:   ALE::Obj<ALE::Mesh> m;

1401:   MeshGetMesh(mesh, m);
1402:   return VTKViewer::writeVertices(m, viewer);
1403: }

1407: PetscErrorCode WriteVTKElements(Mesh mesh, PetscViewer viewer)
1408: {
1409:   ALE::Obj<ALE::Mesh> m;

1412:   MeshGetMesh(mesh, m);
1413:   return VTKViewer::writeElements(m, viewer);
1414: }

1418: PetscErrorCode WritePCICEVertices(Mesh mesh, PetscViewer viewer)
1419: {
1420:   ALE::Obj<ALE::Mesh> m;

1423:   MeshGetMesh(mesh, m);
1424:   return ALE::PCICE::Viewer::writeVertices(m, viewer);
1425: }

1429: PetscErrorCode WritePCICEElements(Mesh mesh, PetscViewer viewer)
1430: {
1431:   ALE::Obj<ALE::Mesh> m;

1434:   MeshGetMesh(mesh, m);
1435:   return ALE::PCICE::Viewer::writeElements(m, viewer);
1436: }

1440: PetscErrorCode WritePCICERestart(Mesh mesh, PetscViewer viewer)
1441: {
1442:   ALE::Obj<ALE::Mesh> m;

1445:   MeshGetMesh(mesh, m);
1446:   return ALE::PCICE::Viewer::writeRestart(m, viewer);
1447: }

1451: /*@C
1452:   MeshCreatePCICE - Create a Mesh from PCICE files.

1454:   Not Collective

1456:   Input Parameters:
1457: + dim - The topological mesh dimension
1458: . coordFilename - The file containing vertex coordinates
1459: . adjFilename - The file containing the vertices for each element
1460: . interpolate - The flag for construction of intermediate elements
1461: . bcFilename - The file containing the boundary topology and conditions
1462: . numBdFaces - The number of boundary faces (or edges)
1463: - numBdVertices - The number of boundary vertices

1465:   Output Parameter:
1466: . mesh - The Mesh object

1468:   Level: beginner

1470: .keywords: mesh, PCICE
1471: .seealso: MeshCreate()
1472: @*/
1473: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], Mesh *mesh)
1474: {
1475:   ALE::Obj<ALE::Mesh> m;
1476:   PetscInt            debug = 0;
1477:   PetscTruth          flag;
1478:   PetscErrorCode      ierr;

1481:   MeshCreate(comm, mesh);
1482:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1483:   try {
1484:     m  = ALE::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1485:     if (debug) {m->view("Mesh");}
1486:   } catch(ALE::Exception e) {
1487:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1488:   }
1489:   if (bcFilename) {
1490:     ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1491:   }
1492:   MeshSetMesh(*mesh, m);
1493:   return(0);
1494: }

1498: /*@C
1499:   MeshCreatePyLith - Create a Mesh from PyLith files.

1501:   Not Collective

1503:   Input Parameters:
1504: + dim - The topological mesh dimension
1505: . baseFilename - The basename for mesh files
1506: . zeroBase - Use 0 to start numbering
1507: - interpolate - The flag for mesh interpolation

1509:   Output Parameter:
1510: . mesh - The Mesh object

1512:   Level: beginner

1514: .keywords: mesh, PCICE
1515: .seealso: MeshCreate()
1516: @*/
1517: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1518: {
1519:   ALE::Obj<ALE::Mesh> m;
1520:   PetscInt            debug = 0;
1521:   PetscTruth          flag;
1522:   PetscErrorCode      ierr;

1525:   MeshCreate(comm, mesh);
1526:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1527:   try {
1528:     m  = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1529:   } catch(ALE::Exception e) {
1530:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1531:   }
1532:   MeshSetMesh(*mesh, m);
1533:   return(0);
1534: }

1538: /*@C
1539:   MeshGetCoordinates - Creates an array holding the coordinates.

1541:   Not Collective

1543:   Input Parameter:
1544: + mesh - The Mesh object
1545: - columnMajor - Flag for column major order

1547:   Output Parameter:
1548: + numVertices - The number of vertices
1549: . dim - The embedding dimension
1550: - coords - The array holding local coordinates

1552:   Level: intermediate

1554: .keywords: mesh, coordinates
1555: .seealso: MeshCreate()
1556: @*/
1557: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1558: {
1559:   ALE::Obj<ALE::Mesh> m;
1560:   PetscErrorCode      ierr;

1563:   MeshGetMesh(mesh, m);
1564:   ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1565:   return(0);
1566: }

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

1573:   Not Collective

1575:   Input Parameters:
1576: + mesh - The Mesh object
1577: - columnMajor - Flag for column major order

1579:   Output Parameters:
1580: + numElements - The number of elements
1581: . numCorners - The number of vertices per element
1582: - vertices - The array holding vertices on each local element

1584:   Level: intermediate

1586: .keywords: mesh, elements
1587: .seealso: MeshCreate()
1588: @*/
1589: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1590: {
1591:   ALE::Obj<ALE::Mesh> m;
1592:   PetscErrorCode      ierr;

1595:   MeshGetMesh(mesh, m);
1596:   ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1597:   return(0);
1598: }

1602: /*@C
1603:   MeshDistribute - Distributes the mesh and any associated sections.

1605:   Not Collective

1607:   Input Parameter:
1608: + serialMesh  - The original Mesh object
1609: - partitioner - The partitioning package, or NULL for the default

1611:   Output Parameter:
1612: . parallelMesh - The distributed Mesh object

1614:   Level: intermediate

1616: .keywords: mesh, elements

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

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

1640: /*@C
1641:   MeshDistribute - Distributes the mesh and any associated sections.

1643:   Not Collective

1645:   Input Parameter:
1646: + serialMesh  - The original Mesh object
1647: - partitioner - The partitioning package, or NULL for the default

1649:   Output Parameter:
1650: . parallelMesh - The distributed Mesh object

1652:   Level: intermediate

1654: .keywords: mesh, elements

1656: .seealso: MeshCreate(), MeshDistribute()
1657: @*/
1658: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1659: {
1660:   ALE::Obj<ALE::Mesh> oldMesh;
1661:   PetscErrorCode      ierr;

1664:   MeshGetMesh(serialMesh, oldMesh);
1665:   MeshCreate(oldMesh->comm(), parallelMesh);
1666:   if (partitioner == NULL) {
1667:     ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1);
1668:     MeshSetMesh(*parallelMesh, newMesh);
1669:   } else {
1670:     ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1, partitioner);
1671:     MeshSetMesh(*parallelMesh, newMesh);
1672:   }
1673:   return(0);
1674: }

1678: /*@C
1679:   MeshGenerate - Generates a mesh.

1681:   Not Collective

1683:   Input Parameters:
1684: + boundary - The Mesh boundary object
1685: - interpolate - Flag to create intermediate mesh elements

1687:   Output Parameter:
1688: . mesh - The Mesh object

1690:   Level: intermediate

1692: .keywords: mesh, elements
1693: .seealso: MeshCreate(), MeshRefine()
1694: @*/
1695: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1696: {
1697:   ALE::Obj<ALE::Mesh> mB;
1698:   PetscErrorCode      ierr;

1701:   MeshGetMesh(boundary, mB);
1702:   MeshCreate(mB->comm(), mesh);
1703:   ALE::Obj<ALE::Mesh> m = ALE::Generator::generateMesh(mB, interpolate);
1704:   MeshSetMesh(*mesh, m);
1705:   return(0);
1706: }

1710: /*@C
1711:   MeshRefine - Refines the mesh.

1713:   Not Collective

1715:   Input Parameters:
1716: + mesh - The original Mesh object
1717: . refinementLimit - The maximum size of any cell
1718: - interpolate - Flag to create intermediate mesh elements

1720:   Output Parameter:
1721: . refinedMesh - The refined Mesh object

1723:   Level: intermediate

1725: .keywords: mesh, elements
1726: .seealso: MeshCreate(), MeshGenerate()
1727: @*/
1728: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1729: {
1730:   ALE::Obj<ALE::Mesh> oldMesh;
1731:   PetscErrorCode      ierr;

1734:   MeshGetMesh(mesh, oldMesh);
1735:   MeshCreate(oldMesh->comm(), refinedMesh);
1736:   ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, interpolate);
1737:   MeshSetMesh(*refinedMesh, newMesh);
1738:   return(0);
1739: }

1743: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1744: {
1745:   ALE::Obj<ALE::Mesh> oldMesh;
1746:   double              refinementLimit;
1747:   PetscErrorCode      ierr;

1750:   MeshGetMesh(mesh, oldMesh);
1751:   MeshCreate(comm, refinedMesh);
1752:   refinementLimit = oldMesh->getMaxVolume()/2.0;
1753:   ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, true);
1754:   MeshSetMesh(*refinedMesh, newMesh);
1755:   const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default");

1757:   newMesh->setDiscretization(oldMesh->getDiscretization());
1758:   newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1759:   newMesh->setupField(s);
1760:   return(0);
1761: }

1763: #include "Hierarchy.hh"

1767: /*@C
1768:   MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.

1770:   Not Collective

1772:   Input Parameters:
1773: + mesh - The original Mesh object
1774: . numLevels - The number of 
1775: . coarseningFactor - The expansion factor for coarse meshes
1776: - interpolate - Flag to create intermediate mesh elements

1778:   Output Parameter:
1779: . coarseHierarchy - The coarse Mesh objects

1781:   Level: intermediate

1783: .keywords: mesh, elements
1784: .seealso: MeshCreate(), MeshGenerate()
1785: @*/
1786: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh **coarseHierarchy)
1787: {
1788:   ALE::Obj<ALE::Mesh> oldMesh;
1789:   PetscErrorCode      ierr;

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

1815:     MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1816:     newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1817:     newMesh->setDiscretization(oldMesh->getDiscretization());
1818:     newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1819:     newMesh->setupField(s);
1820:     MeshSetMesh((*coarseHierarchy)[l], newMesh);
1821:   }
1822: #endif
1823:   return(0);
1824: }

1826: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh **coarseHierarchy)
1827: {
1829:   double cfactor = 1.5;
1831:   PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1832:   MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1833:   return(0);
1834: }

1838: /*
1839:   This method only handle P_1 discretizations at present.
1840: */
1841: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
1842: {
1843:   ALE::Obj<ALE::Mesh> coarse;
1844:   ALE::Obj<ALE::Mesh> fine;
1845:   Mesh coarseMesh = (Mesh) dmCoarse;
1846:   Mesh fineMesh   = (Mesh) dmFine;
1847:   Mat  P;

1851:   MeshGetMesh(fineMesh,   fine);
1852:   MeshGetMesh(coarseMesh, coarse);
1853:   const ALE::Obj<ALE::Mesh::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
1854:   const ALE::Obj<ALE::Mesh::real_section_type>& fineCoordinates   = fine->getRealSection("coordinates");
1855:   const ALE::Obj<ALE::Mesh::label_sequence>&    vertices          = fine->depthStratum(0);
1856:   const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse           = coarse->getRealSection("default");
1857:   const ALE::Obj<ALE::Mesh::real_section_type>& sFine             = fine->getRealSection("default");
1858:   const ALE::Obj<ALE::Mesh::order_type>&        coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
1859:   const ALE::Obj<ALE::Mesh::order_type>&        fineOrder   = fine->getFactory()->getGlobalOrder(fine, "default", sFine);

1861:   const int dim = coarse->getDimension();
1862:   double *v0, *J, *invJ, detJ, *refCoords, *values;

1864:   MatCreate(fine->comm(), &P);
1865:   MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
1866:   MatSetFromOptions(P);
1867:   MatSetUpPreallocation(P);
1868:   PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
1869:   for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
1870:     const ALE::Mesh::real_section_type::value_type *coords     = fineCoordinates->restrictPoint(*v_iter);

1872:     ALE::Mesh::point_type coarseCell;
1873:     ALE::Mesh::point_type cellguess = -1;
1874:     if (fine->hasLabel("prolongation")) {
1875:       cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
1876:       coarseCell = coarse->locatePoint(coords, cellguess);
1877:     } else {
1878:       coarseCell = coarse->locatePoint(coords);
1879:     }
1880: //      coarseCell = coarse->locatePoint(coords);
1881:     if (coarseCell == -1) {
1882:      // do NO CORRECTION!
1883:     } else {
1884:       coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
1885:       for(int d = 0; d < dim; ++d) {
1886:         refCoords[d] = 0.0;
1887:         for(int e = 0; e < dim; ++e) {
1888:           refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
1889:         }
1890:         refCoords[d] -= 1.0;
1891:       }
1892:       values[0] = -(refCoords[0] + refCoords[1])/2.0;
1893:       values[1] = 0.5*(refCoords[0] + 1.0);
1894:       values[2] = 0.5*(refCoords[1] + 1.0);
1895:       updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
1896:     }
1897:   }
1898:   PetscFree5(v0,J,invJ,refCoords,values);
1899:   MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
1900:   MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
1901:   *interpolation = P;
1902:   return(0);
1903: }

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

1910:   Not Collective

1912:   Input Parameters:
1913: + mesh - The Mesh object
1914: - name - The section name

1916:   Output Parameter:
1917: . flag - True if the SectionReal is present in the Mesh

1919:   Level: intermediate

1921: .keywords: mesh, elements
1922: .seealso: MeshCreate()
1923: @*/
1924: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
1925: {
1926:   ALE::Obj<ALE::Mesh> m;
1927:   PetscErrorCode      ierr;

1930:   MeshGetMesh(mesh, m);
1931:   *flag = (PetscTruth) m->hasRealSection(std::string(name));
1932:   return(0);
1933: }

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

1940:   Collective on Mesh

1942:   Input Parameters:
1943: + mesh - The Mesh object
1944: - name - The section name

1946:   Output Parameter:
1947: . section - The SectionReal

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

1951:   Level: intermediate

1953: .keywords: mesh, elements
1954: .seealso: MeshCreate()
1955: @*/
1956: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
1957: {
1958:   ALE::Obj<ALE::Mesh> m;
1959:   PetscErrorCode      ierr;

1962:   MeshGetMesh(mesh, m);
1963:   SectionRealCreate(m->comm(), section);
1964:   PetscObjectSetName((PetscObject) *section, name);
1965:   SectionRealSetSection(*section, m->getRealSection(std::string(name)));
1966:   SectionRealSetBundle(*section, m);
1967:   return(0);
1968: }

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

1975:   Collective on Mesh

1977:   Input Parameters:
1978: + mesh - The Mesh object
1979: - section - The SectionReal

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

1983:   Level: intermediate

1985: .keywords: mesh, elements
1986: .seealso: MeshCreate()
1987: @*/
1988: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
1989: {
1990:   ALE::Obj<ALE::Mesh> m;
1991:   ALE::Obj<ALE::Mesh::real_section_type> s;
1992:   const char         *name;
1993:   PetscErrorCode      ierr;

1996:   MeshGetMesh(mesh, m);
1997:   PetscObjectGetName((PetscObject) section, &name);
1998:   SectionRealGetSection(section, s);
1999:   m->setRealSection(std::string(name), s);
2000:   return(0);
2001: }

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

2008:   Not Collective

2010:   Input Parameters:
2011: + mesh - The Mesh object
2012: - name - The section name

2014:   Output Parameter:
2015: . flag - True if the SectionInt is present in the Mesh

2017:   Level: intermediate

2019: .keywords: mesh, elements
2020: .seealso: MeshCreate()
2021: @*/
2022: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2023: {
2024:   ALE::Obj<ALE::Mesh> m;
2025:   PetscErrorCode      ierr;

2028:   MeshGetMesh(mesh, m);
2029:   *flag = (PetscTruth) m->hasIntSection(std::string(name));
2030:   return(0);
2031: }

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

2038:   Collective on Mesh

2040:   Input Parameters:
2041: + mesh - The Mesh object
2042: - name - The section name

2044:   Output Parameter:
2045: . section - The SectionInt

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

2049:   Level: intermediate

2051: .keywords: mesh, elements
2052: .seealso: MeshCreate()
2053: @*/
2054: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2055: {
2056:   ALE::Obj<ALE::Mesh> m;
2057:   PetscErrorCode      ierr;

2060:   MeshGetMesh(mesh, m);
2061:   SectionIntCreate(m->comm(), section);
2062:   PetscObjectSetName((PetscObject) *section, name);
2063:   SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2064:   SectionIntSetBundle(*section, m);
2065:   return(0);
2066: }

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

2073:   Collective on Mesh

2075:   Input Parameters:
2076: + mesh - The Mesh object
2077: - section - The SectionInt

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

2081:   Level: intermediate

2083: .keywords: mesh, elements
2084: .seealso: MeshCreate()
2085: @*/
2086: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2087: {
2088:   ALE::Obj<ALE::Mesh> m;
2089:   ALE::Obj<ALE::Mesh::int_section_type> s;
2090:   const char         *name;
2091:   PetscErrorCode      ierr;

2094:   MeshGetMesh(mesh, m);
2095:   PetscObjectGetName((PetscObject) section, &name);
2096:   SectionIntGetSection(section, s);
2097:   m->setIntSection(std::string(name), s);
2098:   return(0);
2099: }

2103: /*@C
2104:   SectionGetArray - Returns the array underlying the Section.

2106:   Not Collective

2108:   Input Parameters:
2109: + mesh - The Mesh object
2110: - name - The section name

2112:   Output Parameters:
2113: + numElements - The number of mesh element with values
2114: . fiberDim - The number of values per element
2115: - array - The array

2117:   Level: intermediate

2119: .keywords: mesh, elements
2120: .seealso: MeshCreate()
2121: @*/
2122: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2123: {
2124:   ALE::Obj<ALE::Mesh> m;
2125:   PetscErrorCode      ierr;

2128:   MeshGetMesh(mesh, m);
2129:   const Obj<ALE::Mesh::real_section_type>& section = m->getRealSection(std::string(name));
2130:   if (section->size() == 0) {
2131:     *numElements = 0;
2132:     *fiberDim    = 0;
2133:     *array       = NULL;
2134:     return(0);
2135:   }
2136:   const ALE::Mesh::real_section_type::chart_type& chart = section->getChart();
2137: /*   const int                                  depth   = m->depth(*chart.begin()); */
2138: /*   *numElements = m->depthStratum(depth)->size(); */
2139: /*   *fiberDim    = section->getFiberDimension(*chart.begin()); */
2140: /*   *array       = (PetscScalar *) m->restrict(section); */
2141:   int fiberDimMin = section->getFiberDimension(*chart.begin());
2142:   int numElem     = 0;

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

2147:     if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2148:   }
2149:   for(ALE::Mesh::real_section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2150:     const int fiberDim = section->getFiberDimension(*c_iter);

2152:     numElem += fiberDim/fiberDimMin;
2153:   }
2154:   *numElements = numElem;
2155:   *fiberDim    = fiberDimMin;
2156:   *array       = (PetscScalar *) section->restrict();
2157:   return(0);
2158: }

2162: PetscErrorCode WritePyLithVertices(Mesh mesh, PetscViewer viewer)
2163: {
2164:   ALE::Obj<ALE::Mesh> m;

2167:   MeshGetMesh(mesh, m);
2168:   return ALE::PyLith::Viewer::writeVertices(m, viewer);
2169: }

2173: PetscErrorCode WritePyLithElements(Mesh mesh, SectionInt material, PetscViewer viewer)
2174: {
2175:   ALE::Obj<ALE::Mesh> m;
2176:   ALE::Obj<ALE::Mesh::int_section_type> s;

2179:   MeshGetMesh(mesh, m);
2180:   SectionIntGetSection(material, s);
2181:   return ALE::PyLith::Viewer::writeElements(m, s, viewer);
2182: }

2186: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2187: {
2188:   ALE::Obj<ALE::Mesh> m;

2191:   MeshGetMesh(mesh, m);
2192:   return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2193: }

2197: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2198: {
2199:   ALE::Obj<ALE::Mesh> m;
2200:   ALE::Obj<ALE::Mesh::int_section_type> s;

2203:   MeshGetMesh(mesh, m);
2204:   SectionIntGetSection(material, s);
2205:   return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2206: }

2208: #if 0
2211: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2212: {
2213:   ALE::Obj<ALE::Mesh> m;

2216:   MeshGetMesh(mesh, m);
2217:   return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2218: }
2219: #endif

2223: /*@C
2224:     MeshCompatGetMesh - Gets the internal mesh object

2226:     Not collective

2228:     Input Parameter:
2229: .    mesh - the mesh object

2231:     Output Parameter:
2232: .    m - the internal mesh object

2234:     Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2235:     developing for that tool.
2236:  
2237:     Level: developer

2239: .seealso MeshCreate(), MeshSetMesh()

2241: @*/
2242: PetscErrorCode  MeshCompatGetMesh(Mesh mesh, ALE::Obj<ALECompat::Mesh>& m)
2243: {
2246:   m = mesh->mcompat;
2247:   return(0);
2248: }

2252: /*@C
2253:     MeshCompatSetMesh - Sets the internal mesh object

2255:     Not collective

2257:     Input Parameters:
2258: +    mesh - the mesh object
2259: -    m - the internal mesh object

2261:     Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2262:     developing for that tool.
2263:  
2264:     Level: developer

2266: .seealso MeshCreate(), MeshGetMesh()

2268: @*/
2269: PetscErrorCode  MeshCompatSetMesh(Mesh mesh, const ALE::Obj<ALECompat::Mesh>& m)
2270: {
2273:   mesh->mcompat = m;
2274:   return(0);
2275: }

2279: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2280: {
2281:   const int end = interval.prefix + interval.index;
2282:   for(int i = interval.index; i < end; i++) {
2283:     indices[indx++] = i;
2284:   }
2285: }

2289: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2290: {
2291:   for(int i = 0; i < interval.prefix; i++) {
2292:     indices[(*indx)++] = interval.index + i;
2293:   }
2294:   for(int i = 0; i < -interval.prefix; i++) {
2295:     indices[(*indx)++] = -1;
2296:   }
2297: }

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

2306:   for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_itor = intervals->begin(); i_itor != intervals->end(); i_itor++) {
2307:     ExpandInterval_New(*i_itor, indices, &k);
2308:   }
2309:   return(0);
2310: }

2314: template<typename Section>
2315: PetscErrorCode  MeshCompatCreateGlobalScatter(const ALE::Obj<ALECompat::Mesh>& m, const ALE::Obj<Section>& s, VecScatter *scatter)
2316: {
2317:   typedef ALECompat::Mesh::real_section_type::index_type index_type;

2322:   const ALE::Obj<ALECompat::Mesh::topology_type>&                   topology = m->getTopology();
2323:   const ALE::Obj<ALECompat::Mesh::real_section_type::atlas_type>&   atlas    = s->getAtlas();
2324:   const ALECompat::Mesh::real_section_type::patch_type              patch    = 0;
2325:   const ALECompat::Mesh::real_section_type::atlas_type::chart_type& chart    = atlas->getPatch(patch);
2326:   const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(topology, patch, s->getName(), atlas);
2327:   int *localIndices, *globalIndices;
2328:   int  localSize = s->size(patch);
2329:   int  localIndx = 0, globalIndx = 0;
2330:   Vec  globalVec, localVec;
2331:   IS   localIS, globalIS;

2333:   VecCreate(m->comm(), &globalVec);
2334:   VecSetSizes(globalVec, globalOrder->getLocalSize(), PETSC_DETERMINE);
2335:   VecSetFromOptions(globalVec);
2336:   // Loop over all local points
2337:   PetscMalloc(localSize*sizeof(int), &localIndices);
2338:   PetscMalloc(localSize*sizeof(int), &globalIndices);
2339:   for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator p_iter = chart.begin(); p_iter != chart.end(); ++p_iter) {
2340:     const ALECompat::Mesh::real_section_type::index_type& idx = atlas->restrictPoint(patch, *p_iter)[0];

2342:     // Map local indices to global indices
2343:     ExpandInterval(idx, localIndices, localIndx);
2344:     ExpandInterval(index_type(idx.prefix, globalOrder->getIndex(*p_iter)), globalIndices, globalIndx);
2345:   }
2346:   if (localIndx  != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of local indices %d, should be %d", localIndx, localSize);
2347:   if (globalIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of global indices %d, should be %d", globalIndx, localSize);
2348:   if (m->debug()) {
2349:     globalOrder->view("Global Order");
2350:     for(int i = 0; i < localSize; ++i) {
2351:       printf("[%d] localIndex[%d]: %d globalIndex[%d]: %d\n", m->commRank(), i, localIndices[i], i, globalIndices[i]);
2352:     }
2353:   }
2354:   ISCreateGeneral(PETSC_COMM_SELF, localSize, localIndices,  &localIS);
2355:   ISCreateGeneral(PETSC_COMM_SELF, localSize, globalIndices, &globalIS);
2356:   PetscFree(localIndices);
2357:   PetscFree(globalIndices);
2358:   VecCreateSeqWithArray(PETSC_COMM_SELF, localSize, s->restrict(patch), &localVec);
2359:   VecScatterCreate(localVec, localIS, globalVec, globalIS, scatter);
2360:   ISDestroy(globalIS);
2361:   ISDestroy(localIS);
2362:   VecDestroy(localVec);
2363:   VecDestroy(globalVec);
2365:   return(0);
2366: }

2370: PetscErrorCode  MeshCompatGetGlobalScatter(Mesh mesh, VecScatter *scatter)
2371: {

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

2380:     MeshCompatGetMesh(mesh, m);
2381:     MeshCompatCreateGlobalScatter(m, m->getRealSection("default"), &mesh->globalScatter);
2382:   }
2383:   *scatter = mesh->globalScatter;
2384:   return(0);
2385: }

2389: template<typename Atlas>
2390: 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)
2391: {
2392:   typedef ALECompat::New::NumberingFactory<ALECompat::Mesh::topology_type> NumberingFactory;
2393:   const ALE::Obj<ALECompat::Mesh::sieve_type>     adjGraph    = new ALECompat::Mesh::sieve_type(topology->comm(), topology->debug());
2394:   const ALE::Obj<ALECompat::Mesh::topology_type>  adjTopology = new ALECompat::Mesh::topology_type(topology->comm(), topology->debug());
2395:   const ALECompat::Mesh::real_section_type::patch_type patch  = 0;
2396:   const ALE::Obj<ALECompat::Mesh::sieve_type>&    sieve       = topology->getPatch(patch);
2397:   PetscInt       numLocalRows, firstRow;
2398:   PetscInt      *dnz, *onz;

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

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

2413:     adjGraph->addCone(sieve->cone(sieve->support(point)), point);
2414:   }
2415:   /* Distribute adjacency graph */
2416:   topology->constructOverlap(patch);
2417:   const Obj<ALECompat::Mesh::send_overlap_type>& vertexSendOverlap = topology->getSendOverlap();
2418:   const Obj<ALECompat::Mesh::recv_overlap_type>& vertexRecvOverlap = topology->getRecvOverlap();
2419:   const Obj<ALECompat::Mesh::send_overlap_type>  nbrSendOverlap    = new ALECompat::Mesh::send_overlap_type(topology->comm(), topology->debug());
2420:   const Obj<ALECompat::Mesh::recv_overlap_type>  nbrRecvOverlap    = new ALECompat::Mesh::recv_overlap_type(topology->comm(), topology->debug());
2421:   const Obj<ALECompat::Mesh::send_section_type>  sendSection       = new ALECompat::Mesh::send_section_type(topology->comm(), topology->debug());
2422:   const Obj<ALECompat::Mesh::recv_section_type>  recvSection       = new ALECompat::Mesh::recv_section_type(topology->comm(), sendSection->getTag(), topology->debug());

2424:   ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::coneCompletion(vertexSendOverlap, vertexRecvOverlap, adjTopology, sendSection, recvSection);
2425:   /* Distribute indices for new points */
2426:   ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::updateOverlap(sendSection, recvSection, nbrSendOverlap, nbrRecvOverlap);
2427:   NumberingFactory::singleton(topology->debug())->completeOrder(globalOrder, nbrSendOverlap, nbrRecvOverlap, patch, true);
2428:   /* Read out adjacency graph */
2429:   const ALE::Obj<ALECompat::Mesh::sieve_type> graph = adjTopology->getPatch(patch);

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

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

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

2447:         if (cSize > 0) {
2448:           if (globalOrder->isLocal(neighbor)) {
2449:             for(int r = 0; r < rSize; ++r) {dnz[row - firstRow + r] += cSize;}
2450:           } else {
2451:             for(int r = 0; r < rSize; ++r) {onz[row - firstRow + r] += cSize;}
2452:           }
2453:         }
2454:       }
2455:     }
2456:   }
2457:   if (topology->debug()) {
2458:     int rank = topology->commRank();
2459:     for(int r = 0; r < numLocalRows; r++) {
2460:       std::cout << "["<<rank<<"]: dnz["<<r<<"]: " << dnz[r] << " onz["<<r<<"]: " << onz[r] << std::endl;
2461:     }
2462:   }
2463:   MatSeqAIJSetPreallocation(A, 0, dnz);
2464:   MatMPIAIJSetPreallocation(A, 0, dnz, 0, onz);
2465:   PetscFree2(dnz, onz);
2466:   MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR);
2467:   return(0);
2468: }

2472: 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)
2473: {
2474:   return preallocateOperatorCompat(topology, atlas, globalOrder, A);
2475: }

2479: 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)
2480: {
2481:   ALECompat::Mesh::real_section_type::patch_type patch = 0;
2482:   static PetscInt  indicesSize = 0;
2483:   static PetscInt *indices = NULL;
2484:   PetscInt         numIndices = 0;
2485:   PetscErrorCode   ierr;

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

2491:   if (section->debug()) {printf("[%d]mat for element %d\n", section->commRank(), e);}
2492:   for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_iter = intervals->begin(); i_iter != intervals->end(); ++i_iter) {
2493:     numIndices += std::abs(i_iter->prefix);
2494:     if (section->debug()) {
2495:       printf("[%d]mat interval (%d, %d)\n", section->commRank(), i_iter->prefix, i_iter->index);
2496:     }
2497:   }
2498:   if (indicesSize && (indicesSize != numIndices)) {
2499:     PetscFree(indices);
2500:     indices = NULL;
2501:   }
2502:   if (!indices) {
2503:     indicesSize = numIndices;
2504:     PetscMalloc(indicesSize * sizeof(PetscInt), &indices);
2505:   }
2506:   ExpandIntervals(intervals, indices);
2507:   if (section->debug()) {
2508:     for(int i = 0; i < numIndices; i++) {
2509:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2510:     }
2511:     for(int i = 0; i < numIndices; i++) {
2512:       printf("[%d]", section->commRank());
2513:       for(int j = 0; j < numIndices; j++) {
2514:         printf(" %g", array[i*numIndices+j]);
2515:       }
2516:       printf("\n");
2517:     }
2518:   }
2519:   MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
2520:   if (ierr) {
2521:     printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
2522:     for(int i = 0; i < numIndices; i++) {
2523:       printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2524:     }
2525: 
2526:   }
2528:   return(0);
2529: }

2533: /*@C
2534:   MeshCompatCreatePyLith - Create a Mesh from PyLith files.

2536:   Not Collective

2538:   Input Parameters:
2539: + dim - The topological mesh dimension
2540: . baseFilename - The basename for mesh files
2541: . zeroBase - Use 0 to start numbering
2542: - interpolate - The flag for mesh interpolation

2544:   Output Parameter:
2545: . mesh - The Mesh object

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

2550:   Level: developer

2552: .keywords: mesh, PCICE
2553: .seealso: MeshCreate()
2554: @*/
2555: PetscErrorCode MeshCompatCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
2556: {
2557:   ALE::Obj<ALECompat::Mesh> m;
2558:   PetscInt            debug = 0;
2559:   PetscTruth          flag;
2560:   PetscErrorCode      ierr;

2563:   MeshCreate(comm, mesh);
2564:   PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
2565:   try {
2566:     m  = ALECompat::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
2567:   } catch(ALE::Exception e) {
2568:     SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
2569:   }
2570:   MeshCompatSetMesh(*mesh, m);
2571:   return(0);
2572: }