Actual source code: mesh.c
1: #include "private/meshimpl.h" /*I "petscmesh.h" I*/
2: #include <petscmesh_viewers.hh>
3: #include <petscmesh_formats.hh>
5: /* Logging support */
6: PetscCookie MESH_COOKIE;
7: PetscLogEvent Mesh_View, Mesh_GetGlobalScatter, Mesh_restrictVector, Mesh_assembleVector,
8: Mesh_assembleVectorComplete, Mesh_assembleMatrix, Mesh_updateOperator;
10: PetscTruth MeshRegisterAllCalled = PETSC_FALSE;
11: PetscFList MeshList;
13: EXTERN PetscErrorCode MeshView_Mesh(Mesh, PetscViewer);
14: EXTERN PetscErrorCode MeshRefine_Mesh(Mesh, MPI_Comm, Mesh *);
15: EXTERN PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh, int, Mesh **);
16: EXTERN PetscErrorCode MeshGetInterpolation_Mesh(Mesh, Mesh, Mat *, Vec *);
17: EXTERN PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh, Mesh, Mat *, Vec *);
22: /*
23: Private routine to delete internal tag storage when a communicator is freed.
25: This is called by MPI, not by users.
29: we do not use PetscFree() since it is unsafe after PetscFinalize()
30: */
31: PetscMPIInt Mesh_DelTag(MPI_Comm comm,PetscMPIInt keyval,void* attr_val,void* extra_state)
32: {
33: free(attr_val);
34: return(MPI_SUCCESS);
35: }
40: PetscErrorCode MeshFinalize()
41: {
43: PETSC_MESH_TYPE::MeshNumberingFactory::singleton(0, 0, true);
44: return(0);
45: }
49: PetscErrorCode MeshView_Sieve_Ascii(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
50: {
51: PetscViewerFormat format;
52: PetscErrorCode ierr;
55: PetscViewerGetFormat(viewer, &format);
56: if (format == PETSC_VIEWER_ASCII_VTK) {
57: VTKViewer::writeHeader(viewer);
58: VTKViewer::writeVertices(mesh, viewer);
59: VTKViewer::writeElements(mesh, viewer);
60: const ALE::Obj<PETSC_MESH_TYPE::int_section_type>& p = mesh->getIntSection("Partition");
61: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& cells = mesh->heightStratum(0);
62: const PETSC_MESH_TYPE::label_sequence::iterator end = cells->end();
63: const int rank = mesh->commRank();
65: #ifdef PETSC_OPT_SIEVE
66: p->setChart(PETSC_MESH_TYPE::int_section_type::chart_type(*cells));
67: #endif
68: p->setFiberDimension(cells, 1);
69: p->allocatePoint();
70: for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin(); c_iter != end; ++c_iter) {
71: p->updatePoint(*c_iter, &rank);
72: }
73: PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_VTK_CELL);
74: SectionView_Sieve_Ascii(mesh, p, "Partition", viewer);
75: PetscViewerPopFormat(viewer);
76: } else if (format == PETSC_VIEWER_ASCII_PYLITH) {
77: char *filename;
78: char connectFilename[2048];
79: char coordFilename[2048];
81: PetscViewerFileGetName(viewer, &filename);
82: PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
83: PetscStrcpy(connectFilename, filename);
84: PetscStrcat(connectFilename, ".connect");
85: PetscViewerFileSetName(viewer, connectFilename);
86: ALE::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
87: PetscStrcpy(coordFilename, filename);
88: PetscStrcat(coordFilename, ".coord");
89: PetscViewerFileSetName(viewer, coordFilename);
90: ALE::PyLith::Viewer::writeVertices(mesh, viewer);
91: PetscViewerFileSetMode(viewer, FILE_MODE_READ);
92: PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
93: if (PetscExceptionValue(ierr)) {
94: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
95: } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
96: 0;
97: }
98:
99: } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
100: PetscViewer connectViewer, coordViewer;
101: char *filename;
102: char localFilename[2048];
103: int rank = mesh->commRank();
105: PetscViewerFileGetName(viewer, &filename);
107: sprintf(localFilename, "%s.%d.connect", filename, rank);
108: PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
109: PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
110: PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
111: PetscViewerFileSetName(connectViewer, localFilename);
112: ALE::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
113: PetscViewerDestroy(connectViewer);
115: sprintf(localFilename, "%s.%d.coord", filename, rank);
116: PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
117: PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
118: PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
119: PetscViewerFileSetName(coordViewer, localFilename);
120: ALE::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
121: PetscViewerDestroy(coordViewer);
122: } else if (format == PETSC_VIEWER_ASCII_PCICE) {
123: char *filename;
124: char coordFilename[2048];
125: PetscTruth isConnect;
126: size_t len;
128: PetscViewerFileGetName(viewer, &filename);
129: PetscStrlen(filename, &len);
130: PetscStrcmp(&(filename[len-5]), ".lcon", &isConnect);
131: if (!isConnect) {
132: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid element connectivity filename: %s", filename);
133: }
134: ALE::PCICE::Viewer::writeElements(mesh, viewer);
135: PetscStrncpy(coordFilename, filename, len-5);
136: coordFilename[len-5] = '\0';
137: PetscStrcat(coordFilename, ".nodes");
138: PetscViewerFileSetName(viewer, coordFilename);
139: ALE::PCICE::Viewer::writeVertices(mesh, viewer);
140: } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
141: mesh->view("");
142: } else {
143: int dim = mesh->getDimension();
145: PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
146: for(int d = 0; d <= dim; d++) {
147: // FIX: Need to globalize
148: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->depthStratum(d)->size(), d);
149: }
150: }
151: PetscViewerFlush(viewer);
152: return(0);
153: }
157: PetscErrorCode MeshView_Sieve(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
158: {
159: PetscTruth iascii, isbinary, isdraw;
163: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
164: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
165: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);
167: if (iascii){
168: MeshView_Sieve_Ascii(mesh, viewer);
169: } else if (isbinary) {
170: SETERRQ(PETSC_ERR_SUP, "Binary viewer not implemented for Mesh");
171: } else if (isdraw){
172: SETERRQ(PETSC_ERR_SUP, "Draw viewer not implemented for Mesh");
173: } else {
174: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
175: }
176: return(0);
177: }
181: PetscErrorCode MeshView_Mesh(Mesh mesh, PetscViewer viewer)
182: {
186: MeshView_Sieve(mesh->m, viewer);
187: return(0);
188: }
192: /*@C
193: MeshView - Views a Mesh object.
195: Collective on Mesh
197: Input Parameters:
198: + mesh - the mesh
199: - viewer - an optional visualization context
201: Notes:
202: The available visualization contexts include
203: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
204: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
205: output where only the first processor opens
206: the file. All other processors send their
207: data to the first processor to print.
209: You can change the format the mesh is printed using the
210: option PetscViewerSetFormat().
212: The user can open alternative visualization contexts with
213: + PetscViewerASCIIOpen() - Outputs mesh to a specified file
214: . PetscViewerBinaryOpen() - Outputs mesh in binary to a
215: specified file; corresponding input uses MeshLoad()
216: . PetscViewerDrawOpen() - Outputs mesh to an X window display
218: The user can call PetscViewerSetFormat() to specify the output
219: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
220: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
221: + PETSC_VIEWER_DEFAULT - default, prints mesh information
222: - PETSC_VIEWER_ASCII_VTK - outputs a VTK file describing the mesh
224: Level: beginner
226: Concepts: mesh^printing
227: Concepts: mesh^saving to disk
229: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
230: MeshLoad(), PetscViewerCreate()
231: @*/
232: PetscErrorCode MeshView(Mesh mesh, PetscViewer viewer)
233: {
239: if (!viewer) {
240: PetscViewerASCIIGetStdout(((PetscObject)mesh)->comm,&viewer);
241: }
245: PetscLogEventBegin(Mesh_View,0,0,0,0);
246: (*mesh->ops->view)(mesh, viewer);
247: PetscLogEventEnd(Mesh_View,0,0,0,0);
248: return(0);
249: }
253: /*@C
254: MeshLoad - Create a mesh topology from the saved data in a viewer.
256: Collective on Viewer
258: Input Parameter:
259: . viewer - The viewer containing the data
261: Output Parameters:
262: . mesh - the mesh object
264: Level: advanced
266: .seealso MeshView()
268: @*/
269: PetscErrorCode MeshLoad(PetscViewer viewer, Mesh *mesh)
270: {
271: SETERRQ(PETSC_ERR_SUP, "");
272: }
276: /*@C
277: MeshGetMesh - Gets the internal mesh object
279: Not collective
281: Input Parameter:
282: . mesh - the mesh object
284: Output Parameter:
285: . m - the internal mesh object
286:
287: Level: advanced
289: .seealso MeshCreate(), MeshSetMesh()
291: @*/
292: PetscErrorCode MeshGetMesh(Mesh mesh, ALE::Obj<PETSC_MESH_TYPE>& m)
293: {
296: m = mesh->m;
297: return(0);
298: }
302: /*@C
303: MeshSetMesh - Sets the internal mesh object
305: Not collective
307: Input Parameters:
308: + mesh - the mesh object
309: - m - the internal mesh object
310:
311: Level: advanced
313: .seealso MeshCreate(), MeshGetMesh()
315: @*/
316: PetscErrorCode MeshSetMesh(Mesh mesh, const ALE::Obj<PETSC_MESH_TYPE>& m)
317: {
320: mesh->m = m;
321: if (mesh->globalScatter) {
324: VecScatterDestroy(mesh->globalScatter);
325: mesh->globalScatter = PETSC_NULL;
326: }
327: return(0);
328: }
332: /*@C
333: MeshCreateMatrix - Creates a matrix with the correct parallel layout required for
334: computing the Jacobian on a function defined using the information in the Section.
336: Collective on Mesh
338: Input Parameters:
339: + mesh - the mesh object
340: . section - the section which determines data layout
341: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
342: or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).
344: Output Parameter:
345: . J - matrix with the correct nonzero preallocation
346: (obviously without the correct Jacobian values)
348: Level: advanced
350: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
351: do not need to do it yourself.
353: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
354: @*/
355: PetscErrorCode MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
356: {
357: ALE::Obj<PETSC_MESH_TYPE> m;
358: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
362: MeshGetMesh(mesh, m);
363: SectionRealGetSection(section, s);
364: MeshCreateMatrix(m, s, mtype, J);
365: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
366: return(0);
367: }
371: PetscErrorCode MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
372: {
373: SectionReal section;
377: MeshGetVertexSectionReal(mesh, 1, §ion);
378: MeshCreateMatrix(mesh, section, mtype, J);
379: SectionRealDestroy(section);
380: return(0);
381: }
385: /*@C
386: MeshGetMatrix - Creates a matrix with the correct parallel layout required for
387: computing the Jacobian on a function defined using the information in Mesh.
389: Collective on Mesh
391: Input Parameters:
392: + mesh - the mesh object
393: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
394: or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).
396: Output Parameter:
397: . J - matrix with the correct nonzero preallocation
398: (obviously without the correct Jacobian values)
400: Level: advanced
402: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
403: do not need to do it yourself.
405: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
407: @*/
408: PetscErrorCode MeshGetMatrix(Mesh mesh, const MatType mtype, Mat *J)
409: {
410: ALE::Obj<PETSC_MESH_TYPE> m;
411: PetscTruth flag;
412: PetscErrorCode ierr;
415: MeshHasSectionReal(mesh, "default", &flag);
416: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
417: MeshGetMesh(mesh, m);
418: MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
419: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
420: return(0);
421: }
425: /*@C
426: MeshCreate - Creates a DM object, used to manage data for an unstructured problem
427: described by a Sieve.
429: Collective on MPI_Comm
431: Input Parameter:
432: . comm - the processors that will share the global vector
434: Output Parameters:
435: . mesh - the mesh object
437: Level: advanced
439: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
441: @*/
442: PetscErrorCode MeshCreate(MPI_Comm comm,Mesh *mesh)
443: {
445: Mesh p;
449: *mesh = PETSC_NULL;
450: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
451: DMInitializePackage(PETSC_NULL);
452: #endif
454: PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
455: p->ops->view = MeshView_Mesh;
456: p->ops->destroy = PETSC_NULL;
457: p->ops->createglobalvector = MeshCreateGlobalVector;
458: p->ops->createlocalvector = MeshCreateLocalVector;
459: p->ops->getcoloring = PETSC_NULL;
460: p->ops->getmatrix = MeshGetMatrix;
461: p->ops->getinterpolation = MeshGetInterpolation_Mesh_New;
462: p->ops->getinjection = PETSC_NULL;
463: p->ops->refine = MeshRefine_Mesh;
464: p->ops->coarsen = PETSC_NULL;
465: p->ops->refinehierarchy = PETSC_NULL;
466: p->ops->coarsenhierarchy = MeshCoarsenHierarchy_Mesh;
468: PetscObjectChangeTypeName((PetscObject) p, "sieve");
470: new(&p->m) ALE::Obj<PETSC_MESH_TYPE>(PETSC_NULL);
471: p->globalScatter = PETSC_NULL;
472: p->lf = PETSC_NULL;
473: p->lj = PETSC_NULL;
474: p->data = PETSC_NULL;
475: *mesh = p;
476: return(0);
477: }
481: /*@
482: MeshDestroy - Destroys a mesh.
484: Collective on Mesh
486: Input Parameter:
487: . mesh - the mesh object
489: Level: advanced
491: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
492: @*/
493: PetscErrorCode MeshDestroy(Mesh mesh)
494: {
495: PetscErrorCode ierr;
498: if (--((PetscObject)mesh)->refct > 0) return(0);
499: if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
500: mesh->m = PETSC_NULL;
501: PetscHeaderDestroy(mesh);
502: return(0);
503: }
507: /*@C
508: MeshSetType - Sets the Mesh type
510: Collective on Mesh
512: Input Parameters:
513: + mesh - the Mesh context
514: - type - the type
516: Options Database Key:
517: . -mesh_type <method> - Sets the type; use -help for a list
518: of available types (for instance, cartesian or sieve)
520: Notes:
521: See "petsc/include/petscmesh.h" for available types (for instance,
522: MESHCARTESIAN or MESHSIEVE).
524: Level: intermediate
526: .keywords: Mesh, set, typr
527: .seealso: MeshGetType(), MeshType
528: @*/
529: PetscErrorCode MeshSetType(Mesh mesh, const MeshType type)
530: {
531: PetscErrorCode ierr,(*r)(Mesh);
532: PetscTruth match;
538: PetscTypeCompare((PetscObject)mesh,type,&match);
539: if (match) return(0);
541: PetscFListFind(MeshList,((PetscObject)mesh)->comm,type,(void (**)(void)) &r);
542: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
543: /* Destroy the previous private Mesh context */
544: if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
545: /* Reinitialize function pointers in MeshOps structure */
546: PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
547: /* Call the MeshCreate_XXX routine for this particular mesh */
548: (*r)(mesh);
549: PetscObjectChangeTypeName((PetscObject) mesh, type);
550: return(0);
551: }
555: /*@C
556: MeshGetType - Gets the Mesh type as a string from the Mesh object.
558: Not Collective
560: Input Parameter:
561: . mesh - Mesh context
563: Output Parameter:
564: . name - name of Mesh type
566: Level: intermediate
568: .keywords: Mesh, get, type
569: .seealso: MeshSetType()
570: @*/
571: PetscErrorCode MeshGetType(Mesh mesh,const MeshType *type)
572: {
576: *type = ((PetscObject)mesh)->type_name;
577: return(0);
578: }
582: /*@C
583: MeshRegister - See MeshRegisterDynamic()
585: Level: advanced
586: @*/
587: PetscErrorCode MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
588: {
590: char fullname[PETSC_MAX_PATH_LEN];
593: PetscFListConcat(path,name,fullname);
594: PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
595: return(0);
596: }
599: EXTERN PetscErrorCode MeshCreate_Cartesian(Mesh);
604: /*@C
605: MeshRegisterAll - Registers all of the Mesh types in the Mesh package.
607: Not Collective
609: Level: advanced
611: .keywords: Mesh, register, all
612: .seealso: MeshRegisterDestroy()
613: @*/
614: PetscErrorCode MeshRegisterAll(const char path[])
615: {
619: MeshRegisterAllCalled = PETSC_TRUE;
621: MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
622: return(0);
623: }
627: /*@C
628: MeshRegisterDestroy - Frees the list of Mesh types that were
629: registered by MeshRegister().
631: Not Collective
633: Level: advanced
635: .keywords: Mesh, register, destroy
636: .seealso: MeshRegister(), MeshRegisterAll()
637: @*/
638: PetscErrorCode MeshRegisterDestroy(void)
639: {
643: PetscFListDestroy(&MeshList);
644: MeshRegisterAllCalled = PETSC_FALSE;
645: return(0);
646: }
650: /*@C
651: MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into
652: by the mesh.
654: Collective on Mesh
656: Input Parameter:
657: . mesh - the mesh object
659: Output Parameters:
660: . gvec - the global vector
662: Level: advanced
664: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
666: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
668: @*/
669: PetscErrorCode MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
670: {
671: ALE::Obj<PETSC_MESH_TYPE> m;
672: PetscTruth flag;
676: MeshHasSectionReal(mesh, "default", &flag);
677: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
678: MeshGetMesh(mesh, m);
679: const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));
681: VecCreate(m->comm(), gvec);
682: VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
683: VecSetFromOptions(*gvec);
684: return(0);
685: }
689: /*@
690: MeshCreateVector - Creates a global vector matching the input section
692: Collective on Mesh
694: Input Parameters:
695: + mesh - the Mesh
696: - section - the Section
698: Output Parameter:
699: . vec - the global vector
701: Level: advanced
703: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
704: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
705: @*/
706: PetscErrorCode MeshCreateVector(Mesh mesh, SectionReal section, Vec *vec)
707: {
708: ALE::Obj<PETSC_MESH_TYPE> m;
709: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
713: MeshGetMesh(mesh, m);
714: SectionRealGetSection(section, s);
715: const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, s->getName(), s);
717: VecCreate(m->comm(), vec);
718: VecSetSizes(*vec, order->getLocalSize(), order->getGlobalSize());
719: VecSetFromOptions(*vec);
720: return(0);
721: }
725: /*@C
726: MeshCreateLocalVector - Creates a vector of the correct size for local computation.
728: Collective on Mesh
730: Input Parameter:
731: . mesh - the mesh object
733: Output Parameters:
734: . lvec - the local vector
736: Level: advanced
738: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
740: .seealso MeshDestroy(), MeshCreate(), MeshCreateGlobalVector()
742: @*/
743: PetscErrorCode MeshCreateLocalVector(Mesh mesh, Vec *lvec)
744: {
745: ALE::Obj<PETSC_MESH_TYPE> m;
746: PetscTruth flag;
750: MeshHasSectionReal(mesh, "default", &flag);
751: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
752: MeshGetMesh(mesh, m);
753: const int size = m->getRealSection("default")->getStorageSize();
755: VecCreate(PETSC_COMM_SELF, lvec);
756: VecSetSizes(*lvec, size, size);
757: VecSetFromOptions(*lvec);
758: return(0);
759: }
763: /*@C
764: MeshGetGlobalIndices - Gets the global indices for all the local entries
766: Collective on Mesh
768: Input Parameter:
769: . mesh - the mesh object
771: Output Parameters:
772: . idx - the individual indices for each packed vector/array
773:
774: Level: advanced
776: Notes:
777: The idx parameters should be freed by the calling routine with PetscFree()
779: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
781: @*/
782: PetscErrorCode MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
783: {
784: SETERRQ(PETSC_ERR_SUP, "");
785: }
789: /*@
790: MeshCreateGlobalScatter - Create a VecScatter which maps from local, overlapping
791: storage in the Section to a global Vec
793: Collective on Mesh
795: Input Parameters:
796: + mesh - the mesh object
797: - section - The Scetion which determines data layout
799: Output Parameter:
800: . scatter - the VecScatter
801:
802: Level: advanced
804: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
805: @*/
806: PetscErrorCode MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
807: {
808: ALE::Obj<PETSC_MESH_TYPE> m;
809: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
813: MeshGetMesh(mesh, m);
814: SectionRealGetSection(section, s);
815: MeshCreateGlobalScatter(m, s, scatter);
816: return(0);
817: }
821: PetscErrorCode MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
822: {
828: if (!mesh->globalScatter) {
829: SectionReal section;
831: MeshGetSectionReal(mesh, "default", §ion);
832: MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
833: SectionRealDestroy(section);
834: }
835: *scatter = mesh->globalScatter;
836: return(0);
837: }
841: PetscErrorCode MeshGetLocalFunction(Mesh mesh, PetscErrorCode (**lf)(Mesh, SectionReal, SectionReal, void *))
842: {
845: if (lf) *lf = mesh->lf;
846: return(0);
847: }
851: PetscErrorCode MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
852: {
855: mesh->lf = lf;
856: return(0);
857: }
861: PetscErrorCode MeshGetLocalJacobian(Mesh mesh, PetscErrorCode (**lj)(Mesh, SectionReal, Mat, void *))
862: {
865: if (lj) *lj = mesh->lj;
866: return(0);
867: }
871: PetscErrorCode MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
872: {
875: mesh->lj = lj;
876: return(0);
877: }
881: PetscErrorCode MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
882: {
889: if (mesh->lf) {
890: (*mesh->lf)(mesh, X, F, ctx);
891: }
892: return(0);
893: }
897: PetscErrorCode MeshFormJacobian(Mesh mesh, SectionReal X, Mat J, void *ctx)
898: {
905: if (mesh->lj) {
906: (*mesh->lj)(mesh, X, J, ctx);
907: }
908: return(0);
909: }
913: // Here we assume:
914: // - Assumes 3D and tetrahedron
915: // - The section takes values on vertices and is P1
916: // - Points have the same dimension as the mesh
917: // - All values have the same dimension
918: PetscErrorCode MeshInterpolatePoints(Mesh mesh, SectionReal section, int numPoints, double *points, double **values)
919: {
920: Obj<PETSC_MESH_TYPE> m;
921: Obj<PETSC_MESH_TYPE::real_section_type> s;
922: double *v0, *J, *invJ, detJ;
926: MeshGetMesh(mesh, m);
927: SectionRealGetSection(section, s);
928: const Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
929: int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
930: int dim = s->getFiberDimension(*m->depthStratum(0)->begin());
932: PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
933: PetscMalloc(numPoints*dim * sizeof(double), &values);
934: for(int p = 0; p < numPoints; p++) {
935: double *point = &points[p*embedDim];
936:
937: PETSC_MESH_TYPE::point_type e = m->locatePoint(point);
938: const PETSC_MESH_TYPE::real_section_type::value_type *coeff = s->restrictPoint(e);
940: m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
941: double xi = (invJ[0*embedDim+0]*(point[0] - v0[0]) + invJ[0*embedDim+1]*(point[1] - v0[1]) + invJ[0*embedDim+2]*(point[2] - v0[2]))*0.5;
942: double eta = (invJ[1*embedDim+0]*(point[0] - v0[0]) + invJ[1*embedDim+1]*(point[1] - v0[1]) + invJ[1*embedDim+2]*(point[2] - v0[2]))*0.5;
943: double zeta = (invJ[2*embedDim+0]*(point[0] - v0[0]) + invJ[2*embedDim+1]*(point[1] - v0[1]) + invJ[2*embedDim+2]*(point[2] - v0[2]))*0.5;
945: for(int d = 0; d < dim; d++) {
946: (*values)[p*dim+d] = coeff[0*dim+d]*(1 - xi - eta - zeta) + coeff[1*dim+d]*xi + coeff[2*dim+d]*eta + coeff[3*dim+d]*zeta;
947: }
948: }
949: PetscFree3(v0, J, invJ);
950: return(0);
951: }
955: /*@C
956: MeshGetMaximumDegree - Return the maximum degree of any mesh vertex
958: Collective on mesh
960: Input Parameter:
961: . mesh - The Mesh
963: Output Parameter:
964: . maxDegree - The maximum number of edges at any vertex
966: Level: beginner
968: .seealso: MeshCreate()
969: @*/
970: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
971: {
972: Obj<PETSC_MESH_TYPE> m;
976: MeshGetMesh(mesh, m);
977: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& vertices = m->depthStratum(0);
978: const ALE::Obj<PETSC_MESH_TYPE::sieve_type>& sieve = m->getSieve();
979: PetscInt maxDeg = -1;
981: for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
982: maxDeg = PetscMax(maxDeg, (PetscInt) sieve->getSupportSize(*v_iter));
983: }
984: *maxDegree = maxDeg;
985: return(0);
986: }
988: EXTERN PetscErrorCode assembleFullField(VecScatter, Vec, Vec, InsertMode);
992: /*@C
993: restrictVector - Insert values from a global vector into a local ghosted vector
995: Collective on g
997: Input Parameters:
998: + g - The global vector
999: . l - The local vector
1000: - mode - either ADD_VALUES or INSERT_VALUES, where
1001: ADD_VALUES adds values to any existing entries, and
1002: INSERT_VALUES replaces existing entries with new values
1004: Level: beginner
1006: .seealso: MatSetOption()
1007: @*/
1008: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1009: {
1010: VecScatter injection;
1014: PetscLogEventBegin(Mesh_restrictVector,0,0,0,0);
1015: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1016: if (injection) {
1017: VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
1018: VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
1019: } else {
1020: if (mode == INSERT_VALUES) {
1021: VecCopy(g, l);
1022: } else {
1023: VecAXPY(l, 1.0, g);
1024: }
1025: }
1026: PetscLogEventEnd(Mesh_restrictVector,0,0,0,0);
1027: return(0);
1028: }
1032: /*@C
1033: assembleVectorComplete - Insert values from a local ghosted vector into a global vector
1035: Collective on g
1037: Input Parameters:
1038: + g - The global vector
1039: . l - The local vector
1040: - mode - either ADD_VALUES or INSERT_VALUES, where
1041: ADD_VALUES adds values to any existing entries, and
1042: INSERT_VALUES replaces existing entries with new values
1044: Level: beginner
1046: .seealso: MatSetOption()
1047: @*/
1048: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1049: {
1050: VecScatter injection;
1054: PetscLogEventBegin(Mesh_assembleVectorComplete,0,0,0,0);
1055: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1056: if (injection) {
1057: VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1058: VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1059: } else {
1060: if (mode == INSERT_VALUES) {
1061: VecCopy(l, g);
1062: } else {
1063: VecAXPY(g, 1.0, l);
1064: }
1065: }
1066: PetscLogEventEnd(Mesh_assembleVectorComplete,0,0,0,0);
1067: return(0);
1068: }
1072: /*@C
1073: assembleVector - Insert values into a vector
1075: Collective on A
1077: Input Parameters:
1078: + b - the vector
1079: . e - The element number
1080: . v - The values
1081: - mode - either ADD_VALUES or INSERT_VALUES, where
1082: ADD_VALUES adds values to any existing entries, and
1083: INSERT_VALUES replaces existing entries with new values
1085: Level: beginner
1087: .seealso: VecSetOption()
1088: @*/
1089: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1090: {
1091: Mesh mesh;
1092: ALE::Obj<PETSC_MESH_TYPE> m;
1093: PetscInt firstElement;
1094: PetscErrorCode ierr;
1097: PetscLogEventBegin(Mesh_assembleVector,0,0,0,0);
1098: PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1099: MeshGetMesh(mesh, m);
1100: //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1101: firstElement = 0;
1102: // Must relate b to field
1103: if (mode == INSERT_VALUES) {
1104: m->update(m->getRealSection(std::string("x")), PETSC_MESH_TYPE::point_type(e + firstElement), v);
1105: } else {
1106: m->updateAdd(m->getRealSection(std::string("x")), PETSC_MESH_TYPE::point_type(e + firstElement), v);
1107: }
1108: PetscLogEventEnd(Mesh_assembleVector,0,0,0,0);
1109: return(0);
1110: }
1114: PetscErrorCode updateOperator(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& section, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, const PETSC_MESH_TYPE::point_type& e, PetscScalar array[], InsertMode mode)
1115: {
1117: #ifdef PETSC_OPT_SIEVE
1118: typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
1119: visitor_type iV(*section, *globalOrder, (int) pow((double) m->getSieve()->getMaxConeSize(), m->depth())*m->getMaxDof(), m->depth() > 1);
1121: PetscErrorCode updateOperator(A, *m->getSieve(), iV, e, array, ADD_VALUES);
1122: #else
1123: const PETSC_MESH_TYPE::indices_type indicesBlock = m->getIndices(section, e, globalOrder);
1124: const PetscInt *indices = indicesBlock.first;
1125: const int& numIndices = indicesBlock.second;
1126: PetscErrorCode ierr;
1128: PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1129: if (section->debug()) {
1130: printf("[%d]mat for element %d\n", section->commRank(), e);
1131: for(int i = 0; i < numIndices; i++) {
1132: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1133: }
1134: for(int i = 0; i < numIndices; i++) {
1135: printf("[%d]", section->commRank());
1136: for(int j = 0; j < numIndices; j++) {
1137: printf(" %g", array[i*numIndices+j]);
1138: }
1139: printf("\n");
1140: }
1141: }
1142: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1143: if (ierr) {
1144: printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
1145: for(int i = 0; i < numIndices; i++) {
1146: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1147: }
1148:
1149: }
1150: PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1151: #endif
1152: return(0);
1153: }
1157: PetscErrorCode updateOperator(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& section, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, int tag, int p, PetscScalar array[], InsertMode mode)
1158: {
1159: #ifdef PETSC_OPT_SIEVE
1160: SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1161: #else
1162: const int *offsets, *indices;
1166: section->getCustomRestrictAtlas(tag, &offsets, &indices);
1167: const int& numIndices = offsets[p+1] - offsets[p];
1169: PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1170: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1171: if (ierr) {
1172: printf("[%d]ERROR in updateOperator: tag %d point num %d\n", section->commRank(), tag, p);
1173: for(int i = 0; i < numIndices; i++) {
1174: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1175: }
1176:
1177: }
1178: PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1179: #endif
1180: return(0);
1181: }
1185: PetscErrorCode updateOperatorGeneral(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& rowM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& rowSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& rowGlobalOrder, const PETSC_MESH_TYPE::point_type& rowE, const ALE::Obj<PETSC_MESH_TYPE>& colM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& colSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& colGlobalOrder, const PETSC_MESH_TYPE::point_type& colE, PetscScalar array[], InsertMode mode)
1186: {
1187: #ifdef PETSC_OPT_SIEVE
1188: SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1189: #else
1193: const PETSC_MESH_TYPE::indices_type rowIndicesBlock = rowM->getIndices(rowSection, rowE, rowGlobalOrder);
1195: const PetscInt *tmpIndices = rowIndicesBlock.first;
1196: const int numRowIndices = rowIndicesBlock.second;
1197: PetscInt *rowIndices = new PetscInt[numRowIndices];
1198: PetscMemcpy(rowIndices, tmpIndices, numRowIndices*sizeof(PetscInt));
1200: const PETSC_MESH_TYPE::indices_type colIndicesBlock = colM->getIndices(colSection, colE, colGlobalOrder);
1202: const PetscInt *colIndices = colIndicesBlock.first;
1203: const int numColIndices = colIndicesBlock.second;
1205: PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1206: if (rowSection->debug()) {
1207: printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1208: for(int i = 0; i < numRowIndices; i++) {
1209: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1210: }
1211: }
1212: if (colSection->debug()) {
1213: for(int i = 0; i < numColIndices; i++) {
1214: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1215: }
1216: for(int i = 0; i < numRowIndices; i++) {
1217: printf("[%d]", rowSection->commRank());
1218: for(int j = 0; j < numColIndices; j++) {
1219: printf(" %g", array[i*numColIndices+j]);
1220: }
1221: printf("\n");
1222: }
1223: }
1224: MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1225: if (ierr) {
1226: printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1227: for(int i = 0; i < numRowIndices; i++) {
1228: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1229: }
1230: for(int i = 0; i < numColIndices; i++) {
1231: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1232: }
1233:
1234: }
1235: PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1236: delete [] rowIndices;
1237: #endif
1238: return(0);
1239: }
1243: /*@C
1244: assembleMatrix - Insert values into a matrix
1246: Collective on A
1248: Input Parameters:
1249: + A - the matrix
1250: . e - The element number
1251: . v - The values
1252: - mode - either ADD_VALUES or INSERT_VALUES, where
1253: ADD_VALUES adds values to any existing entries, and
1254: INSERT_VALUES replaces existing entries with new values
1256: Level: beginner
1258: .seealso: MatSetOption()
1259: @*/
1260: PetscErrorCode assembleMatrix(Mat A, PetscInt e, PetscScalar v[], InsertMode mode)
1261: {
1262: #ifdef PETSC_OPT_SIEVE
1263: SETERRQ(PETSC_ERR_SUP, "I am being lazy, bug me.");
1264: #else
1265: Mesh mesh;
1269: PetscLogEventBegin(Mesh_assembleMatrix,0,0,0,0);
1270: PetscObjectQuery((PetscObject) A, "mesh", (PetscObject *) &mesh);
1271: try {
1272: Obj<PETSC_MESH_TYPE> m;
1274: MeshGetMesh(mesh, m);
1275: const ALE::Obj<PETSC_MESH_TYPE::numbering_type>& cNumbering = m->getFactory()->getLocalNumbering(m, m->depth());
1276: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = m->getRealSection("default");
1277: const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, "default", s);
1279: if (m->debug()) {
1280: std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1281: }
1282: updateOperator(A, m, s, globalOrder, cNumbering->getPoint(e), v, mode);
1283: } catch (ALE::Exception e) {
1284: std::cout << e.msg() << std::endl;
1285: }
1286: PetscLogEventEnd(Mesh_assembleMatrix,0,0,0,0);
1287: #endif
1288: return(0);
1289: }
1293: PetscErrorCode preallocateMatrix(const ALE::Obj<PETSC_MESH_TYPE>& mesh, const int bs, const ALE::Obj<PETSC_MESH_TYPE::real_section_type::atlas_type>& atlas, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, Mat A)
1294: {
1295: #ifdef PETSC_OPT_SIEVE
1296: SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1297: #else
1298: PetscInt localSize = globalOrder->getLocalSize();
1299: PetscInt *dnz, *onz;
1303: PetscMalloc2(localSize, PetscInt, &dnz, localSize, PetscInt, &onz);
1304: preallocateOperator(mesh, bs, atlas, globalOrder, dnz, onz, A);
1305: PetscFree2(dnz, onz);
1306: return(0);
1307: #endif
1308: }
1310: /******************************** C Wrappers **********************************/
1314: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1315: {
1316: return VTKViewer::writeHeader(viewer);
1317: }
1321: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1322: {
1323: ALE::Obj<PETSC_MESH_TYPE> m;
1326: MeshGetMesh(mesh, m);
1327: return VTKViewer::writeVertices(m, viewer);
1328: }
1332: PetscErrorCode WriteVTKElements(Mesh mesh, PetscViewer viewer)
1333: {
1334: ALE::Obj<PETSC_MESH_TYPE> m;
1337: MeshGetMesh(mesh, m);
1338: return VTKViewer::writeElements(m, viewer);
1339: }
1343: PetscErrorCode WritePCICEVertices(Mesh mesh, PetscViewer viewer)
1344: {
1345: ALE::Obj<PETSC_MESH_TYPE> m;
1348: MeshGetMesh(mesh, m);
1349: return ALE::PCICE::Viewer::writeVertices(m, viewer);
1350: }
1354: PetscErrorCode WritePCICEElements(Mesh mesh, PetscViewer viewer)
1355: {
1356: ALE::Obj<PETSC_MESH_TYPE> m;
1359: MeshGetMesh(mesh, m);
1360: return ALE::PCICE::Viewer::writeElements(m, viewer);
1361: }
1365: PetscErrorCode WritePCICERestart(Mesh mesh, PetscViewer viewer)
1366: {
1367: ALE::Obj<PETSC_MESH_TYPE> m;
1370: MeshGetMesh(mesh, m);
1371: return ALE::PCICE::Viewer::writeRestart(m, viewer);
1372: }
1376: /*@C
1377: MeshCreatePFLOTRAN - Create a Mesh from PFLOTRAN HDF5 files.
1379: Not Collective
1381: Input Parameters:
1382: + dim - The topological mesh dimension
1383: . hdf5Filename - The HDF5 file containing the vertices for each element and vertex coordinates
1384: . interpolate - The flag for construction of intermediate elements
1386: Output Parameter:
1387: . mesh - The Mesh object
1389: Level: beginner
1391: .keywords: mesh, PFLOTRAN
1392: .seealso: MeshCreate()
1393: @*/
1394: PetscErrorCode MeshCreatePFLOTRAN(MPI_Comm comm, const int dim, const char hdf5Filename[], PetscTruth interpolate, Mesh *mesh)
1395: {
1396: ALE::Obj<PETSC_MESH_TYPE> m;
1397: PetscInt debug = 0;
1398: PetscTruth flag;
1399: PetscErrorCode ierr;
1402: MeshCreate(comm, mesh);
1403: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1404: try {
1405: m = ALE::PFLOTRAN::Builder::readMesh(comm, dim, std::string(hdf5Filename), true, interpolate, debug);
1406: if (debug) {m->view("Mesh");}
1407: } catch(ALE::Exception e) {
1408: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1409: }
1410: #if 0
1411: if (bcFilename) {
1412: ALE::PFLOTRAN::Builder::readBoundary(m, std::string(bcFilename));
1413: }
1414: #endif
1415: MeshSetMesh(*mesh, m);
1416: return(0);
1417: }
1421: /*@C
1422: MeshCreatePCICE - Create a Mesh from PCICE files.
1424: Not Collective
1426: Input Parameters:
1427: + dim - The topological mesh dimension
1428: . coordFilename - The file containing vertex coordinates
1429: . adjFilename - The file containing the vertices for each element
1430: . interpolate - The flag for construction of intermediate elements
1431: . bcFilename - The file containing the boundary topology and conditions
1432: . numBdFaces - The number of boundary faces (or edges)
1433: - numBdVertices - The number of boundary vertices
1435: Output Parameter:
1436: . mesh - The Mesh object
1438: Level: beginner
1440: .keywords: mesh, PCICE
1441: .seealso: MeshCreate()
1442: @*/
1443: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], Mesh *mesh)
1444: {
1445: ALE::Obj<PETSC_MESH_TYPE> m;
1446: PetscInt debug = 0;
1447: PetscTruth flag;
1448: PetscErrorCode ierr;
1451: MeshCreate(comm, mesh);
1452: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1453: try {
1454: m = ALE::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1455: if (debug) {m->view("Mesh");}
1456: } catch(ALE::Exception e) {
1457: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1458: }
1459: if (bcFilename) {
1460: ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1461: }
1462: MeshSetMesh(*mesh, m);
1463: return(0);
1464: }
1468: /*@C
1469: MeshCreatePyLith - Create a Mesh from PyLith files.
1471: Not Collective
1473: Input Parameters:
1474: + dim - The topological mesh dimension
1475: . baseFilename - The basename for mesh files
1476: . zeroBase - Use 0 to start numbering
1477: - interpolate - The flag for mesh interpolation
1479: Output Parameter:
1480: . mesh - The Mesh object
1482: Level: beginner
1484: .keywords: mesh, PCICE
1485: .seealso: MeshCreate()
1486: @*/
1487: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1488: {
1489: ALE::Obj<PETSC_MESH_TYPE> m;
1490: PetscInt debug = 0;
1491: PetscTruth flag;
1492: PetscErrorCode ierr;
1495: MeshCreate(comm, mesh);
1496: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1497: try {
1498: m = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1499: } catch(ALE::Exception e) {
1500: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1501: }
1502: MeshSetMesh(*mesh, m);
1503: return(0);
1504: }
1508: /*@C
1509: MeshGetCoordinates - Creates an array holding the coordinates.
1511: Not Collective
1513: Input Parameter:
1514: + mesh - The Mesh object
1515: - columnMajor - Flag for column major order
1517: Output Parameter:
1518: + numVertices - The number of vertices
1519: . dim - The embedding dimension
1520: - coords - The array holding local coordinates
1522: Level: intermediate
1524: .keywords: mesh, coordinates
1525: .seealso: MeshCreate()
1526: @*/
1527: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1528: {
1529: ALE::Obj<PETSC_MESH_TYPE> m;
1530: PetscErrorCode ierr;
1533: MeshGetMesh(mesh, m);
1534: ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1535: return(0);
1536: }
1540: /*@C
1541: MeshGetElements - Creates an array holding the vertices on each element.
1543: Not Collective
1545: Input Parameters:
1546: + mesh - The Mesh object
1547: - columnMajor - Flag for column major order
1549: Output Parameters:
1550: + numElements - The number of elements
1551: . numCorners - The number of vertices per element
1552: - vertices - The array holding vertices on each local element
1554: Level: intermediate
1556: .keywords: mesh, elements
1557: .seealso: MeshCreate()
1558: @*/
1559: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1560: {
1561: ALE::Obj<PETSC_MESH_TYPE> m;
1562: PetscErrorCode ierr;
1565: MeshGetMesh(mesh, m);
1566: ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1567: return(0);
1568: }
1572: /*@C
1573: MeshDistribute - Distributes the mesh and any associated sections.
1575: Not Collective
1577: Input Parameter:
1578: + serialMesh - The original Mesh object
1579: - partitioner - The partitioning package, or NULL for the default
1581: Output Parameter:
1582: . parallelMesh - The distributed Mesh object
1584: Level: intermediate
1586: .keywords: mesh, elements
1588: .seealso: MeshCreate(), MeshDistributeByFace()
1589: @*/
1590: PetscErrorCode MeshDistribute(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1591: {
1592: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1593: PetscErrorCode ierr;
1596: MeshGetMesh(serialMesh, oldMesh);
1597: MeshCreate(oldMesh->comm(), parallelMesh);
1598: #ifdef PETSC_OPT_SIEVE
1599: const Obj<PETSC_MESH_TYPE> newMesh = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->getDimension(), oldMesh->debug());
1600: const Obj<PETSC_MESH_TYPE::sieve_type> newSieve = new PETSC_MESH_TYPE::sieve_type(oldMesh->comm(), oldMesh->debug());
1602: newMesh->setSieve(newSieve);
1603: ALE::DistributionNew<PETSC_MESH_TYPE>::distributeMeshAndSectionsV(oldMesh, newMesh);
1604: MeshSetMesh(*parallelMesh, newMesh);
1605: #else
1606: if (partitioner == NULL) {
1607: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh);
1608: MeshSetMesh(*parallelMesh, newMesh);
1609: } else {
1610: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 0, partitioner);
1611: MeshSetMesh(*parallelMesh, newMesh);
1612: }
1613: #endif
1614: return(0);
1615: }
1619: /*@C
1620: MeshDistribute - Distributes the mesh and any associated sections.
1622: Not Collective
1624: Input Parameter:
1625: + serialMesh - The original Mesh object
1626: - partitioner - The partitioning package, or NULL for the default
1628: Output Parameter:
1629: . parallelMesh - The distributed Mesh object
1631: Level: intermediate
1633: .keywords: mesh, elements
1635: .seealso: MeshCreate(), MeshDistribute()
1636: @*/
1637: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1638: {
1639: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1640: PetscErrorCode ierr;
1643: MeshGetMesh(serialMesh, oldMesh);
1644: MeshCreate(oldMesh->comm(), parallelMesh);
1645: #ifdef PETSC_OPT_SIEVE
1646: SETERRQ(PETSC_ERR_SUP, "I am being lazy, bug me.");
1647: #else
1648: if (partitioner == NULL) {
1649: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1);
1650: MeshSetMesh(*parallelMesh, newMesh);
1651: } else {
1652: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1, partitioner);
1653: MeshSetMesh(*parallelMesh, newMesh);
1654: }
1655: #endif
1656: return(0);
1657: }
1661: /*@C
1662: MeshGenerate - Generates a mesh.
1664: Not Collective
1666: Input Parameters:
1667: + boundary - The Mesh boundary object
1668: - interpolate - Flag to create intermediate mesh elements
1670: Output Parameter:
1671: . mesh - The Mesh object
1673: Level: intermediate
1675: .keywords: mesh, elements
1676: .seealso: MeshCreate(), MeshRefine()
1677: @*/
1678: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1679: {
1680: ALE::Obj<PETSC_MESH_TYPE> mB;
1681: PetscErrorCode ierr;
1684: MeshGetMesh(boundary, mB);
1685: MeshCreate(mB->comm(), mesh);
1686: #ifdef PETSC_OPT_SIEVE
1687: ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMeshV(mB, interpolate);
1688: #else
1689: ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMesh(mB, interpolate);
1690: #endif
1691: MeshSetMesh(*mesh, m);
1692: return(0);
1693: }
1697: /*@C
1698: MeshRefine - Refines the mesh.
1700: Not Collective
1702: Input Parameters:
1703: + mesh - The original Mesh object
1704: . refinementLimit - The maximum size of any cell
1705: - interpolate - Flag to create intermediate mesh elements
1707: Output Parameter:
1708: . refinedMesh - The refined Mesh object
1710: Level: intermediate
1712: .keywords: mesh, elements
1713: .seealso: MeshCreate(), MeshGenerate()
1714: @*/
1715: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1716: {
1717: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1718: PetscErrorCode ierr;
1721: MeshGetMesh(mesh, oldMesh);
1722: MeshCreate(oldMesh->comm(), refinedMesh);
1723: #ifdef PETSC_OPT_SIEVE
1724: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, interpolate);
1725: #else
1726: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, interpolate);
1727: #endif
1728: MeshSetMesh(*refinedMesh, newMesh);
1729: return(0);
1730: }
1734: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1735: {
1736: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1737: double refinementLimit;
1738: PetscErrorCode ierr;
1741: MeshGetMesh(mesh, oldMesh);
1742: MeshCreate(comm, refinedMesh);
1743: refinementLimit = oldMesh->getMaxVolume()/2.0;
1744: #ifdef PETSC_OPT_SIEVE
1745: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, true);
1746: #else
1747: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, true);
1748: #endif
1749: MeshSetMesh(*refinedMesh, newMesh);
1750: #ifndef PETSC_OPT_SIEVE
1751: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");
1752: const Obj<std::set<std::string> >& discs = oldMesh->getDiscretizations();
1754: for(std::set<std::string>::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter) {
1755: newMesh->setDiscretization(*f_iter, oldMesh->getDiscretization(*f_iter));
1756: }
1757: newMesh->setupField(s);
1758: #endif
1759: return(0);
1760: }
1762: #ifndef PETSC_OPT_SIEVE
1764: #include "Hierarchy_New.hh"
1770: #include "Hierarchy.hh"
1774: /*@C
1775: MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.
1777: Not Collective
1779: Input Parameters:
1780: + mesh - The original Mesh object
1781: . numLevels - The number of
1782: . coarseningFactor - The expansion factor for coarse meshes
1783: - interpolate - Flag to create intermediate mesh elements
1785: Output Parameter:
1786: . coarseHierarchy - The coarse Mesh objects
1788: Level: intermediate
1790: .keywords: mesh, elements
1791: .seealso: MeshCreate(), MeshGenerate()
1792: @*/
1793: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh **coarseHierarchy)
1794: {
1795: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1796: PetscErrorCode ierr;
1799: if (numLevels < 1) {
1800: *coarseHierarchy = PETSC_NULL;
1801: return(0);
1802: }
1803: MeshGetMesh(mesh, oldMesh);
1804: PetscMalloc((numLevels+1) * sizeof(Mesh), coarseHierarchy);
1805: for (int i = 0; i < numLevels+1; i++) {
1806: MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[i]);
1807: }
1808: MeshSpacingFunction(mesh);
1809: MeshCreateHierarchyLabel_Link(mesh, coarseningFactor, numLevels+1, *coarseHierarchy);
1810:
1811: #if 0
1812: if (oldMesh->getDimension() != 2) SETERRQ(PETSC_ERR_SUP, "Coarsening only works in two dimensions right now");
1813: ALE::Coarsener::IdentifyBoundary(oldMesh, 2);
1814: ALE::Coarsener::make_coarsest_boundary(oldMesh, 2, numLevels+1);
1815: ALE::Coarsener::CreateSpacingFunction(oldMesh, 2);
1816: ALE::Coarsener::CreateCoarsenedHierarchyNew(oldMesh, 2, numLevels, coarseningFactor);
1817: PetscMalloc(numLevels * sizeof(Mesh),coarseHierarchy);
1818: for(int l = 0; l < numLevels; l++) {
1819: ALE::Obj<PETSC_MESH_TYPE> newMesh = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->debug());
1820: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");
1822: MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1823: newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1824: newMesh->setDiscretization(oldMesh->getDiscretization());
1825: newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1826: newMesh->setupField(s);
1827: MeshSetMesh((*coarseHierarchy)[l], newMesh);
1828: }
1829: #endif
1830: return(0);
1831: }
1833: #endif
1835: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh **coarseHierarchy)
1836: {
1838: double cfactor = 1.5;
1840: PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1841: #ifdef PETSC_OPT_SIEVE
1842: SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
1843: #else
1844: MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1845: #endif
1846: return(0);
1847: }
1849: #if 0
1854: //Interpolate between two meshes whenever the unknowns can be evaluated at points.
1856: PetscErrorCode MeshGetInterpolation_Mesh_General(Mesh coarse_mesh, Mesh fine_mesh, Mat *interpolation, Vec *scaling) {
1857: ALE::Obj<PETSC_MESH_TYPE> fm, cm;
1858: Mat P;
1859: PetscErrorCode ierr;
1860:
1862: //Stages:
1863: // 1. Create a section on the fine mesh describing the location in the fine mesh of the assorted unknowns.
1864: // 2. Fill in this section by traversing across the mesh via cones and supports, transforming the coordinates of the assorted functional points
1865: // 3. Preallocate the matrix rows/columns
1866: // 4. Assemble the matrix by writing evaluating each unknown as the point
1867: MeshGetMesh(dmFine, fm);
1868: MeshGetMesh(dmCoarse, cm);
1869: // ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
1870: // ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal = fm->createLabel ("traversal");
1871: const int debug = fm->debug();
1872: if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1873: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates = fm->getRealSection("coordinates");
1874: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
1876: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse = cm->getRealSection("default");
1877: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine = fm->getRealSection("default");
1879: const ALE::Obj<PETSC_MESH_TYPE::order_type>& coarseOrder = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1880: const ALE::Obj<PETSC_MESH_TYPE::order_type>& fineOrder = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
1882: std::list<PETSC_MESH_TYPE::point_type> travlist; // store point
1883: std::list<PETSC_MESH_TYPE::point_type> travguesslist; // store guess
1884: std::list<PETSC_MESH_TYPE::point_type> eguesslist; // store the next guesses for the location of the current point.
1886: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1887: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1888: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> covering_points = PETSC_MESH_TYPE::sieve_type::supportSet();
1890: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> uncorrected_points = PETSC_MESH_TYPE::sieve_type::supportSet();
1891: static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1892: if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}
1894: //set up the new section holding the names of the contained points.
1896: const ALE::Obj<PETSC_MESH_TYPE::int_section_type> & node_locations = fm->getIntSection("node_locations");
1897: const ALE::Obj<PETSC_MESH_TYPE::real_section_type> & fine_default = fm->getRealSection("default");
1898: int total_dimension
1899: for (int i = 0; i < dim; i++) {
1900: const ALE::Obj<PETSC_MESH_TYPE::label_sequence> & present_level = fm->depthStratum(i);
1901: int current_dimension = fine_default->getFiberDimension(*present_level->begin());
1902: node_locations->setFiberDimension(present_level, current_dimension);
1903: }
1904: node_locations->allocate();
1905: //traverse!
1907:
1909: ALE::Obj<PETSC_MESH_TYPE::label_sequence> fine_cells = fm->heightStratum(0);
1910: ALE::Obj<PETSC_MESH_TYPE::label_sequence> coarse_cells = cm->heightStratum(0);
1912: PETSC_MESH_TYPE::label_sequence::iterator fc_iter = fine_cells->begin();
1913: PETSC_MESH_TYPE::label_sequence::iterator fc_iter_end = fine_cells->end();
1914: while (fc_iter != fc_iter_end) {
1915: //locate an initial coarse cell that overlaps with this fine cell in terms of their bounding boxes;
1916: PETSC_MESH_TYPE::label_sequence::iterator cc_iter = coarse_cells->begin();
1917: PETSC_MESH_TYPE::label_sequence::iterator cc_iter_end = coarse_cells->end();
1918: while (cc_iter != cc_iter_end) {
1919:
1920: cc_iter++;
1921: }
1922: fc_iter++;
1923: }
1924: }
1926: #endif
1931: PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling) {
1933: #ifdef PETSC_OPT_SIEVE
1934: SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
1935: #else
1936: ALE::Obj<PETSC_MESH_TYPE> fm, cm;
1937: Mat P;
1938: PetscErrorCode ierr;
1941: MeshGetMesh(dmFine, fm);
1942: MeshGetMesh(dmCoarse, cm);
1943: // ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
1944: // ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal = fm->createLabel ("traversal");
1945: const int debug = fm->debug();
1946: if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1947: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates = fm->getRealSection("coordinates");
1948: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
1949: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse = cm->getRealSection("default");
1950: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine = fm->getRealSection("default");
1951: const ALE::Obj<PETSC_MESH_TYPE::order_type>& coarseOrder = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1952: const ALE::Obj<PETSC_MESH_TYPE::order_type>& fineOrder = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
1953: std::list<PETSC_MESH_TYPE::point_type> travlist; // store point
1954: std::list<PETSC_MESH_TYPE::point_type> travguesslist; // store guess
1955: std::list<PETSC_MESH_TYPE::point_type> eguesslist; // store the next guesses for the location of the current point.
1956: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1957: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1958: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> uncorrected_points = PETSC_MESH_TYPE::sieve_type::supportSet();
1959: static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1960: if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}
1962: MatCreate(fm->comm(), &P);
1963: MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
1964: MatSeqAIJSetPreallocation(P,10,PETSC_NULL);
1965: MatSetFromOptions(P);
1967: const int dim = fm->getDimension();
1968: int maxComparisons = 60; //point is considered a lost cause beyond this many comparisons with volumes
1969: if (dim == 3) maxComparisons = 1000; //3D is odd
1970: if (dim != cm->getDimension()) throw ALE::Exception("Dimensions of the fine and coarse meshes do not match");
1972: //traversal labels on both layers
1973: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& finevertices = fm->depthStratum(0);
1974: const PETSC_MESH_TYPE::label_sequence::iterator fv_iter_end = finevertices->end();
1975: PETSC_MESH_TYPE::label_sequence::iterator fv_iter = finevertices->begin();
1977: // while (fv_iter != fv_iter_end) {
1978: // fm->setValue(finetraversal, *fv_iter, 0);
1979: // fv_iter++;
1980: // }
1982: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& coarseelements = cm->heightStratum(0);
1983: const PETSC_MESH_TYPE::label_sequence::iterator ce_iter_end = coarseelements->end();
1984: PETSC_MESH_TYPE::label_sequence::iterator ce_iter = coarseelements->begin();
1985:
1986: // while (ce_iter != ce_iter_end) {
1987: // cm->setValue(coarsetraversal, *ce_iter, 0);
1988: // ce_iter++;
1989: // }
1991: double *fvCoords = new double[dim], *nvCoords = new double[dim];
1992: bool pointIsInElement;
1994: if (debug) {PetscPrintf(fm->comm(), "starting iterations\n");}
1995: fv_iter = finevertices->begin();
1996: while (fv_iter != fv_iter_end) {
1997: // locate an initial point.
1998: // if (fm->getValue(finetraversal, *fv_iter) == 0) {
1999: if ((fine_traversal->find(*fv_iter) == fine_traversal->end()) && (uncorrected_points->find(*fv_iter) == uncorrected_points->end())) {
2000: bool isLocated = false;
2002: ce_iter = coarseelements->begin();
2003: PetscMemcpy(fvCoords, finecoordinates->restrictPoint(*fv_iter), dim*sizeof(double));
2004: while ((ce_iter != ce_iter_end) && (!isLocated)) {
2005: cm->computeElementGeometry(coarsecoordinates, *ce_iter, v0, J, invJ, detJ);
2006: // generalized simplicial location for 2D, 3D:
2007: loc[0] = 1.0;
2008: pointIsInElement = true;
2009: for(int i = 0; i < dim; i++) {
2010: loc[i+1] = 0.0;
2011: for(int j = 0; j < dim; j++) {
2012: loc[i+1] += 0.5*invJ[i*dim+j]*(fvCoords[j] - v0[j]);
2013: }
2014: loc[0] -= loc[i+1];
2015: //PetscPrintf(fm->comm(), "%f, ", loc[i+1]);
2016: if (loc[i+1] < -0.000000000001) pointIsInElement = false;
2017: }
2018: //PetscPrintf(fm->comm(), "%f\n", loc[0]);
2019: if (loc[0] < -0.000000000001) pointIsInElement = false;
2020: if (pointIsInElement) {
2021: //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2022: //PetscPrintf(fm->comm(), "located by guess.\n");
2023: isLocated = true;
2024: updateOperatorGeneral(P, fm, sFine, fineOrder, *fv_iter, cm, sCoarse, coarseOrder, *ce_iter, loc, INSERT_VALUES);
2025: //fm->setValue(finetraversal, *fv_iter, 1);
2026: fine_traversal->insert(*fv_iter);
2027: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> & neighbors = fm->getSieve()->cone(fm->getSieve()->support(*fv_iter));
2028: const PETSC_MESH_TYPE::sieve_type::coneSet::iterator n_iter_end = neighbors->end();
2029: PETSC_MESH_TYPE::sieve_type::coneSet::iterator n_iter = neighbors->begin();
2030: while (n_iter != n_iter_end) {
2031: // if (fm->getValue(finetraversal, *n_iter) == 0) {
2032: if (fine_traversal->find(*n_iter) != fine_traversal->end()) {
2033: travlist.push_back(*n_iter);
2034: // fm->setValue(finetraversal, *n_iter, 1);
2035: fine_traversal->insert(*n_iter);
2036: travguesslist.push_back(*ce_iter);
2037: }
2038: n_iter++;
2039: }
2040: //do a DFS across the finemesh with BFSes on the coarse mesh for each point using assumed regularity of edgelength as a justification for guessing neighboring point's locations.
2041: while (!travlist.empty()) {
2042: PETSC_MESH_TYPE::point_type curVert = *travlist.begin();
2043: PetscMemcpy(nvCoords, finecoordinates->restrictPoint(curVert), dim*sizeof(double));
2044: PETSC_MESH_TYPE::point_type curEle = *travguesslist.begin();
2045: travlist.pop_front();
2046: travguesslist.pop_front();
2047: eguesslist.push_front(curEle);
2048: //cm->setValue(coarsetraversal, curEle, 1);
2049: coarse_traversal->insert(curEle);
2050: bool locationDiscovered = false;
2051: //int traversalcomparisons = 0;
2052: while ((!eguesslist.empty()) && (!locationDiscovered) && (int)coarse_traversal->size() < maxComparisons) {
2053: //traversalcomparisons = 0;
2054: PETSC_MESH_TYPE::point_type curguess = *eguesslist.begin();
2055: eguesslist.pop_front();
2056: pointIsInElement = true;
2057: cm->computeElementGeometry(coarsecoordinates, curguess, v0, J, invJ, detJ);
2058: loc[0] = 1.0;
2059: for(int i = 0; i < dim; i++) {
2060: loc[i+1] = 0.0;
2061: for(int j = 0; j < dim; j++) {
2062: loc[i+1] += 0.5*invJ[i*dim+j]*(nvCoords[j] - v0[j]);
2063: }
2064: loc[0] -= loc[i+1];
2065: if (loc[i+1] < -0.00000000001) pointIsInElement = false;
2066: }
2067: if (loc[0] < -0.00000000001) pointIsInElement = false;
2069: if (pointIsInElement) {
2070: //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2071: locationDiscovered = true;
2072: //PetscPrintf(fm->comm(), "located by traversal.\n");
2073: //set the label.
2074: //fm->setValue(prolongation, curVert, curguess);
2075: updateOperatorGeneral(P, fm, sFine, fineOrder, curVert, cm, sCoarse, coarseOrder, curguess, loc, INSERT_VALUES);
2076: //PetscPrintf(fm->comm(), "Point %d located in %d.\n", curVert, curguess);
2077: //stick its neighbors in the queue along with its location as a good guess of the location of its neighbors
2078: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> newNeighbors = fm->getSieve()->cone(fm->getSieve()->support(curVert));
2079: const PETSC_MESH_TYPE::sieve_type::coneSet::iterator nn_iter_end = newNeighbors->end();
2080: PETSC_MESH_TYPE::sieve_type::coneSet::iterator nn_iter = newNeighbors->begin();
2081: while (nn_iter != nn_iter_end) {
2082: //if (fm->getValue(finetraversal, *nn_iter) == 0) { //unlocated neighbor
2083: if (fine_traversal->find(*nn_iter) == fine_traversal->end()) {
2084: travlist.push_back(*nn_iter);
2085: travguesslist.push_back(curguess);
2086: //fm->setValue(finetraversal, *nn_iter, 1);
2087: fine_traversal->insert(*nn_iter);
2088: }
2089: nn_iter++;
2090: }
2091: } else {
2092: //add the current guesses neighbors to the comparison queue and start over.
2093: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> & curguessneighbors = cm->getSieve()->support(cm->getSieve()->cone(curguess));
2094: const PETSC_MESH_TYPE::sieve_type::supportSet::iterator cgn_iter_end = curguessneighbors->end();
2095: PETSC_MESH_TYPE::sieve_type::supportSet::iterator cgn_iter = curguessneighbors->begin();
2096: while (cgn_iter != cgn_iter_end) {
2097: //if (cm->getValue(coarsetraversal, *cgn_iter) == 0) {
2098: if (coarse_traversal->find(*cgn_iter) == coarse_traversal->end()) {
2099: eguesslist.push_back(*cgn_iter);
2100: //cm->setValue(coarsetraversal, *cgn_iter, 1);
2101: coarse_traversal->insert(*cgn_iter);
2102: }
2103: cgn_iter++;
2104: }
2105: }
2106: }
2107: coarse_traversal->clear();
2108: if (!locationDiscovered) { //if a position for it is not discovered, it doesn't get corrected; complain
2109: if (fm->debug())PetscPrintf(fm->comm(), "Point %d (%f, %f) not located.\n", curVert, nvCoords[0], nvCoords[1]);
2110: //fm->setValue(finetraversal, curVert, 2); //don't try again.
2111: uncorrected_points->insert(curVert);
2112: }
2113: eguesslist.clear(); //we've discovered the location of the point or exhausted our possibilities on this contiguous block of elements.
2114: //unset the traversed element list
2115: //const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& traved_elements = cm->getLabelStratum("traversal", 1);
2116: //const PETSC_MESH_TYPE::label_sequence::iterator tp_iter_end = traved_elements->end();
2117: //PETSC_MESH_TYPE::label_sequence::iterator tp_iter = traved_elements->begin();
2118: //PetscPrintf(cm->comm(), "%d\n", traved_elements->size());
2119: //while (tp_iter != tp_iter_end) {
2120: // eguesslist.push_back(*tp_iter);
2121: // tp_iter++;
2122: //}
2123: //while (!eguesslist.empty()) {
2124: // cm->setValue(coarsetraversal, *eguesslist.begin(), 0);
2125: // eguesslist.pop_front();
2126: //}
2127:
2128: }
2129: }
2130: ce_iter++;
2131: }
2132: if (!isLocated) {
2133: if (fm->debug())PetscPrintf(fm->comm(), "NOT located\n");
2134: //fm->setValue(finetraversal, *fv_iter, 2); //don't try again.
2135: uncorrected_points->insert(*fv_iter);
2136: }
2137: }
2138: // printf("-");
2139: fv_iter++;
2140: }
2141: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2142: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2143: //MatView(P, PETSC_VIEWER_STDOUT_SELF);
2144: delete [] fvCoords; delete [] nvCoords;
2145: *interpolation = P;
2146: if (debug) {PetscPrintf(fm->comm(), "Ending Interpolation Matrix Build\n");}
2147: return(0);
2148: #endif
2149: }
2154: /*
2155: This method only handle P_1 discretizations at present.
2156: */
2157: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
2158: {
2159: #ifdef PETSC_OPT_SIEVE
2160: SETERRQ(PETSC_ERR_SUP, "This has been superceded.");
2161: #else
2162: ALE::Obj<PETSC_MESH_TYPE> coarse;
2163: ALE::Obj<PETSC_MESH_TYPE> fine;
2164: Mat P;
2165: PetscErrorCode ierr;
2168: MeshGetMesh(dmFine, fine);
2169: MeshGetMesh(dmCoarse, coarse);
2170: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
2171: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& fineCoordinates = fine->getRealSection("coordinates");
2172: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& vertices = fine->depthStratum(0);
2173: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse = coarse->getRealSection("default");
2174: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine = fine->getRealSection("default");
2175: const ALE::Obj<PETSC_MESH_TYPE::order_type>& coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
2176: const ALE::Obj<PETSC_MESH_TYPE::order_type>& fineOrder = fine->getFactory()->getGlobalOrder(fine, "default", sFine);
2178: const int dim = coarse->getDimension();
2179: const int numDof = fine->getDiscretization()->getNumDof(fine->getDimension());
2180: double *v0, *J, *invJ, detJ, *refCoords, *values;
2182: MatCreate(fine->comm(), &P);
2183: MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2184: MatSetFromOptions(P);
2185: MatSeqAIJSetPreallocation(P, numDof, PETSC_NULL);
2186: MatMPIAIJSetPreallocation(P, numDof, PETSC_NULL, numDof, PETSC_NULL);
2187: PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
2188: bool hasprolong;
2189: if (fine->hasLabel("prolongation")) {
2190: hasprolong = true;
2191: } else {
2192: hasprolong = false;
2193: PetscPrintf(fine->comm(), "WARNING: Point Location Label Does Not Exist");
2194: }
2195: PETSC_MESH_TYPE::label_sequence::iterator v_iter_end = vertices->end();
2196: PETSC_MESH_TYPE::real_section_type::value_type *coords = new PETSC_MESH_TYPE::real_section_type::value_type[dim];
2198: for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != v_iter_end; ++v_iter) {
2199: //const PETSC_MESH_TYPE::real_section_type::value_type *coords = fineCoordinates->restrictPoint(*v_iter);
2200: PetscMemcpy(coords, fineCoordinates->restrictPoint(*v_iter), dim*sizeof(double));
2201: PETSC_MESH_TYPE::point_type coarseCell;
2202: PETSC_MESH_TYPE::point_type cellguess = -1;
2203: if (hasprolong) {
2204: cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
2205: coarseCell = coarse->locatePoint(coords, cellguess);
2206: } else {
2207: coarseCell = coarse->locatePoint(coords);
2208: }
2209: // coarseCell = coarse->locatePoint(coords);
2210: if (coarseCell == -1) {
2211: // do NO CORRECTION!
2212: } else {
2213: coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
2214: for(int d = 0; d < dim; ++d) {
2215: refCoords[d] = 0.0;
2216: for(int e = 0; e < dim; ++e) {
2217: refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
2218: }
2219: refCoords[d] -= 1.0;
2220: }
2221: values[0] = -(refCoords[0] + refCoords[1])/2.0;
2222: values[1] = 0.5*(refCoords[0] + 1.0);
2223: values[2] = 0.5*(refCoords[1] + 1.0);
2224: // PetscPrintf(fine->comm(), "%f, %f, %f\n", values[0], values[1], values[2]);
2225: updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
2226: }
2227: }
2228: PetscFree5(v0,J,invJ,refCoords,values);
2229: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2230: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2231: delete [] coords;
2232: *interpolation = P;
2233: return(0);
2234: #endif
2235: }
2239: /*@C
2240: MeshHasSectionReal - Determines whether this mesh has a SectionReal with the given name.
2242: Not Collective
2244: Input Parameters:
2245: + mesh - The Mesh object
2246: - name - The section name
2248: Output Parameter:
2249: . flag - True if the SectionReal is present in the Mesh
2251: Level: intermediate
2253: .keywords: mesh, elements
2254: .seealso: MeshCreate()
2255: @*/
2256: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
2257: {
2258: ALE::Obj<PETSC_MESH_TYPE> m;
2259: PetscErrorCode ierr;
2262: MeshGetMesh(mesh, m);
2263: *flag = (PetscTruth) m->hasRealSection(std::string(name));
2264: return(0);
2265: }
2269: /*@C
2270: MeshGetSectionReal - Returns a SectionReal of the given name from the Mesh.
2272: Collective on Mesh
2274: Input Parameters:
2275: + mesh - The Mesh object
2276: - name - The section name
2278: Output Parameter:
2279: . section - The SectionReal
2281: Note: The section is a new object, and must be destroyed by the user
2283: Level: intermediate
2285: .keywords: mesh, elements
2286: .seealso: MeshCreate()
2287: @*/
2288: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
2289: {
2290: ALE::Obj<PETSC_MESH_TYPE> m;
2291: PetscErrorCode ierr;
2294: MeshGetMesh(mesh, m);
2295: SectionRealCreate(m->comm(), section);
2296: PetscObjectSetName((PetscObject) *section, name);
2297: SectionRealSetSection(*section, m->getRealSection(std::string(name)));
2298: SectionRealSetBundle(*section, m);
2299: return(0);
2300: }
2304: /*@C
2305: MeshSetSectionReal - Puts a SectionReal of the given name into the Mesh.
2307: Collective on Mesh
2309: Input Parameters:
2310: + mesh - The Mesh object
2311: - section - The SectionReal
2313: Note: This takes the section name from the PETSc object
2315: Level: intermediate
2317: .keywords: mesh, elements
2318: .seealso: MeshCreate()
2319: @*/
2320: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
2321: {
2322: ALE::Obj<PETSC_MESH_TYPE> m;
2323: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2324: const char *name;
2325: PetscErrorCode ierr;
2328: MeshGetMesh(mesh, m);
2329: PetscObjectGetName((PetscObject) section, &name);
2330: SectionRealGetSection(section, s);
2331: m->setRealSection(std::string(name), s);
2332: return(0);
2333: }
2337: /*@C
2338: MeshHasSectionInt - Determines whether this mesh has a SectionInt with the given name.
2340: Not Collective
2342: Input Parameters:
2343: + mesh - The Mesh object
2344: - name - The section name
2346: Output Parameter:
2347: . flag - True if the SectionInt is present in the Mesh
2349: Level: intermediate
2351: .keywords: mesh, elements
2352: .seealso: MeshCreate()
2353: @*/
2354: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2355: {
2356: ALE::Obj<PETSC_MESH_TYPE> m;
2357: PetscErrorCode ierr;
2360: MeshGetMesh(mesh, m);
2361: *flag = (PetscTruth) m->hasIntSection(std::string(name));
2362: return(0);
2363: }
2367: /*@C
2368: MeshGetSectionInt - Returns a SectionInt of the given name from the Mesh.
2370: Collective on Mesh
2372: Input Parameters:
2373: + mesh - The Mesh object
2374: - name - The section name
2376: Output Parameter:
2377: . section - The SectionInt
2379: Note: The section is a new object, and must be destroyed by the user
2381: Level: intermediate
2383: .keywords: mesh, elements
2384: .seealso: MeshCreate()
2385: @*/
2386: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2387: {
2388: ALE::Obj<PETSC_MESH_TYPE> m;
2389: PetscErrorCode ierr;
2392: MeshGetMesh(mesh, m);
2393: SectionIntCreate(m->comm(), section);
2394: PetscObjectSetName((PetscObject) *section, name);
2395: SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2396: SectionIntSetBundle(*section, m);
2397: return(0);
2398: }
2402: /*@C
2403: MeshSetSectionInt - Puts a SectionInt of the given name into the Mesh.
2405: Collective on Mesh
2407: Input Parameters:
2408: + mesh - The Mesh object
2409: - section - The SectionInt
2411: Note: This takes the section name from the PETSc object
2413: Level: intermediate
2415: .keywords: mesh, elements
2416: .seealso: MeshCreate()
2417: @*/
2418: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2419: {
2420: ALE::Obj<PETSC_MESH_TYPE> m;
2421: ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2422: const char *name;
2423: PetscErrorCode ierr;
2426: MeshGetMesh(mesh, m);
2427: PetscObjectGetName((PetscObject) section, &name);
2428: SectionIntGetSection(section, s);
2429: m->setIntSection(std::string(name), s);
2430: return(0);
2431: }
2435: /*@C
2436: SectionGetArray - Returns the array underlying the Section.
2438: Not Collective
2440: Input Parameters:
2441: + mesh - The Mesh object
2442: - name - The section name
2444: Output Parameters:
2445: + numElements - The number of mesh element with values
2446: . fiberDim - The number of values per element
2447: - array - The array
2449: Level: intermediate
2451: .keywords: mesh, elements
2452: .seealso: MeshCreate()
2453: @*/
2454: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2455: {
2456: ALE::Obj<PETSC_MESH_TYPE> m;
2457: PetscErrorCode ierr;
2460: MeshGetMesh(mesh, m);
2461: const Obj<PETSC_MESH_TYPE::real_section_type>& section = m->getRealSection(std::string(name));
2462: if (section->size() == 0) {
2463: *numElements = 0;
2464: *fiberDim = 0;
2465: *array = NULL;
2466: return(0);
2467: }
2468: const PETSC_MESH_TYPE::real_section_type::chart_type& chart = section->getChart();
2469: /* const int depth = m->depth(*chart.begin()); */
2470: /* *numElements = m->depthStratum(depth)->size(); */
2471: /* *fiberDim = section->getFiberDimension(*chart.begin()); */
2472: /* *array = (PetscScalar *) m->restrict(section); */
2473: int fiberDimMin = section->getFiberDimension(*chart.begin());
2474: int numElem = 0;
2476: for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2477: const int fiberDim = section->getFiberDimension(*c_iter);
2479: if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2480: }
2481: for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2482: const int fiberDim = section->getFiberDimension(*c_iter);
2484: numElem += fiberDim/fiberDimMin;
2485: }
2486: *numElements = numElem;
2487: *fiberDim = fiberDimMin;
2488: *array = (PetscScalar *) section->restrictSpace();
2489: return(0);
2490: }
2494: /*@C
2495: MeshRestrictClosure - Returns an array with the values in a given closure
2497: Not Collective
2499: Input Parameters:
2500: + mesh - The Mesh object
2501: . section - The section
2502: . point - The sieve point
2503: . n - The array size
2504: - array - The array to fill up
2506: Output Parameter:
2507: . array - The array full of values in the closure
2509: Level: intermediate
2511: .keywords: mesh, elements
2512: .seealso: MeshCreate()
2513: @*/
2514: PetscErrorCode MeshRestrictClosure(Mesh mesh, SectionReal section, PetscInt point, PetscInt n, PetscScalar values[])
2515: {
2516: ALE::Obj<PETSC_MESH_TYPE> m;
2517: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2518: PetscErrorCode ierr;
2521: MeshGetMesh(mesh, m);
2522: SectionRealGetSection(section, s);
2523: m->restrictClosure(s, point, values, n);
2524: return(0);
2525: }
2529: /*@C
2530: MeshUpdateClosure - Updates the values in a given closure from the array
2532: Not Collective
2534: Input Parameters:
2535: + mesh - The Mesh object
2536: . section - The section
2537: . point - The sieve point
2538: - array - The array to fill up
2540: Output Parameter:
2541: . array - The array full of values in the closure
2543: Level: intermediate
2545: .keywords: mesh, elements
2546: .seealso: MeshCreate()
2547: @*/
2548: PetscErrorCode MeshUpdateClosure(Mesh mesh, SectionReal section, PetscInt point, PetscScalar values[])
2549: {
2550: ALE::Obj<PETSC_MESH_TYPE> m;
2551: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2552: PetscErrorCode ierr;
2555: MeshGetMesh(mesh, m);
2556: SectionRealGetSection(section, s);
2557: m->update(s, point, values);
2558: return(0);
2559: }
2563: PetscErrorCode WritePyLithVertices(Mesh mesh, PetscViewer viewer)
2564: {
2565: ALE::Obj<PETSC_MESH_TYPE> m;
2568: MeshGetMesh(mesh, m);
2569: return ALE::PyLith::Viewer::writeVertices(m, viewer);
2570: }
2574: PetscErrorCode WritePyLithElements(Mesh mesh, SectionInt material, PetscViewer viewer)
2575: {
2576: ALE::Obj<PETSC_MESH_TYPE> m;
2577: ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2580: MeshGetMesh(mesh, m);
2581: SectionIntGetSection(material, s);
2582: return ALE::PyLith::Viewer::writeElements(m, s, viewer);
2583: }
2587: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2588: {
2589: ALE::Obj<PETSC_MESH_TYPE> m;
2592: MeshGetMesh(mesh, m);
2593: return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2594: }
2598: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2599: {
2600: ALE::Obj<PETSC_MESH_TYPE> m;
2601: ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2604: MeshGetMesh(mesh, m);
2605: SectionIntGetSection(material, s);
2606: return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2607: }
2609: #if 0
2612: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2613: {
2614: ALE::Obj<PETSC_MESH_TYPE> m;
2617: MeshGetMesh(mesh, m);
2618: return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2619: }
2620: #endif
2624: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2625: {
2626: const int end = interval.prefix + interval.index;
2627: for(int i = interval.index; i < end; i++) {
2628: indices[indx++] = i;
2629: }
2630: }
2634: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2635: {
2636: for(int i = 0; i < interval.prefix; i++) {
2637: indices[(*indx)++] = interval.index + i;
2638: }
2639: for(int i = 0; i < -interval.prefix; i++) {
2640: indices[(*indx)++] = -1;
2641: }
2642: }