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, §ion);
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", §ion);
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: }