Actual source code: mesh.c
1: #include "private/meshimpl.h" /*I "petscmesh.h" I*/
2: #include <petscmesh_viewers.hh>
3: #include <petscmesh_formats.hh>
5: /* Logging support */
6: PetscCookie MESH_COOKIE;
7: PetscLogEvent Mesh_View, Mesh_GetGlobalScatter, Mesh_restrictVector, Mesh_assembleVector,
8: Mesh_assembleVectorComplete, Mesh_assembleMatrix, Mesh_updateOperator;
10: PetscTruth MeshRegisterAllCalled = PETSC_FALSE;
11: PetscFList MeshList;
13: #if PETSC_HAVE_SIEVE
14: ALE::MemoryLogger Petsc_MemoryLogger;
15: #endif
17: EXTERN PetscErrorCode MeshView_Mesh(Mesh, PetscViewer);
18: EXTERN PetscErrorCode MeshRefine_Mesh(Mesh, MPI_Comm, Mesh *);
19: EXTERN PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh, int, Mesh *);
20: EXTERN PetscErrorCode MeshGetInterpolation_Mesh(Mesh, Mesh, Mat *, Vec *);
21: EXTERN PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh, Mesh, Mat *, Vec *);
26: /*
27: Private routine to delete internal tag storage when a communicator is freed.
29: This is called by MPI, not by users.
33: we do not use PetscFree() since it is unsafe after PetscFinalize()
34: */
35: PetscMPIInt Mesh_DelTag(MPI_Comm comm,PetscMPIInt keyval,void* attr_val,void* extra_state)
36: {
37: free(attr_val);
38: return(MPI_SUCCESS);
39: }
44: PetscErrorCode MeshFinalize()
45: {
47: PETSC_MESH_TYPE::MeshNumberingFactory::singleton(0, 0, true);
48: return(0);
49: }
53: PetscErrorCode MeshView_Sieve_Ascii(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
54: {
55: PetscViewerFormat format;
56: PetscErrorCode ierr;
59: PetscViewerGetFormat(viewer, &format);
60: if (format == PETSC_VIEWER_ASCII_VTK) {
61: VTKViewer::writeHeader(viewer);
62: VTKViewer::writeVertices(mesh, viewer);
63: VTKViewer::writeElements(mesh, viewer);
64: const ALE::Obj<PETSC_MESH_TYPE::int_section_type>& p = mesh->getIntSection("Partition");
65: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& cells = mesh->heightStratum(0);
66: const PETSC_MESH_TYPE::label_sequence::iterator end = cells->end();
67: const int rank = mesh->commRank();
69: #ifdef PETSC_OPT_SIEVE
70: p->setChart(PETSC_MESH_TYPE::int_section_type::chart_type(*cells));
71: #endif
72: p->setFiberDimension(cells, 1);
73: p->allocatePoint();
74: for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin(); c_iter != end; ++c_iter) {
75: p->updatePoint(*c_iter, &rank);
76: }
77: PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_VTK_CELL);
78: SectionView_Sieve_Ascii(mesh, p, "Partition", viewer);
79: PetscViewerPopFormat(viewer);
80: } else if (format == PETSC_VIEWER_ASCII_PYLITH) {
81: char *filename;
82: char connectFilename[2048];
83: char coordFilename[2048];
85: PetscViewerFileGetName(viewer, &filename);
86: PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
87: PetscStrcpy(connectFilename, filename);
88: PetscStrcat(connectFilename, ".connect");
89: PetscViewerFileSetName(viewer, connectFilename);
90: ALE::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
91: PetscStrcpy(coordFilename, filename);
92: PetscStrcat(coordFilename, ".coord");
93: PetscViewerFileSetName(viewer, coordFilename);
94: ALE::PyLith::Viewer::writeVertices(mesh, viewer);
95: PetscViewerFileSetMode(viewer, FILE_MODE_READ);
96: PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
97: if (PetscExceptionValue(ierr)) {
98: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
99: } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
100: 0;
101: }
102:
103: } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
104: PetscViewer connectViewer, coordViewer;
105: char *filename;
106: char localFilename[2048];
107: int rank = mesh->commRank();
109: PetscViewerFileGetName(viewer, &filename);
111: sprintf(localFilename, "%s.%d.connect", filename, rank);
112: PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
113: PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
114: PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
115: PetscViewerFileSetName(connectViewer, localFilename);
116: ALE::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
117: PetscViewerDestroy(connectViewer);
119: sprintf(localFilename, "%s.%d.coord", filename, rank);
120: PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
121: PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
122: PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
123: PetscViewerFileSetName(coordViewer, localFilename);
124: ALE::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
125: PetscViewerDestroy(coordViewer);
126: } else if (format == PETSC_VIEWER_ASCII_PCICE) {
127: char *filename;
128: char coordFilename[2048];
129: PetscTruth isConnect;
130: size_t len;
132: PetscViewerFileGetName(viewer, &filename);
133: PetscStrlen(filename, &len);
134: PetscStrcmp(&(filename[len-5]), ".lcon", &isConnect);
135: if (!isConnect) {
136: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid element connectivity filename: %s", filename);
137: }
138: ALE::PCICE::Viewer::writeElements(mesh, viewer);
139: PetscStrncpy(coordFilename, filename, len-5);
140: coordFilename[len-5] = '\0';
141: PetscStrcat(coordFilename, ".nodes");
142: PetscViewerFileSetName(viewer, coordFilename);
143: ALE::PCICE::Viewer::writeVertices(mesh, viewer);
144: } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
145: mesh->view("");
146: } else {
147: int dim = mesh->getDimension();
149: PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
150: for(int d = 0; d <= dim; d++) {
151: // FIX: Need to globalize
152: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->depthStratum(d)->size(), d);
153: }
154: }
155: PetscViewerFlush(viewer);
156: return(0);
157: }
162: PetscErrorCode MeshView_Sieve_Binary(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
163: {
164: char *filename;
165: PetscErrorCode ierr;
168: PetscViewerFileGetName(viewer, &filename);
169: ALE::MeshSerializer::writeMesh(filename, *mesh);
170: return(0);
171: }
175: PetscErrorCode MeshView_Sieve(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
176: {
177: PetscTruth iascii, isbinary, isdraw;
181: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
182: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
183: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);
185: if (iascii){
186: MeshView_Sieve_Ascii(mesh, viewer);
187: } else if (isbinary) {
188: MeshView_Sieve_Binary(mesh, viewer);
189: } else if (isdraw){
190: SETERRQ(PETSC_ERR_SUP, "Draw viewer not implemented for Mesh");
191: } else {
192: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
193: }
194: return(0);
195: }
199: PetscErrorCode MeshView_Mesh(Mesh mesh, PetscViewer viewer)
200: {
204: MeshView_Sieve(mesh->m, viewer);
205: return(0);
206: }
210: /*@C
211: MeshView - Views a Mesh object.
213: Collective on Mesh
215: Input Parameters:
216: + mesh - the mesh
217: - viewer - an optional visualization context
219: Notes:
220: The available visualization contexts include
221: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
222: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
223: output where only the first processor opens
224: the file. All other processors send their
225: data to the first processor to print.
227: You can change the format the mesh is printed using the
228: option PetscViewerSetFormat().
230: The user can open alternative visualization contexts with
231: + PetscViewerASCIIOpen() - Outputs mesh to a specified file
232: . PetscViewerBinaryOpen() - Outputs mesh in binary to a
233: specified file; corresponding input uses MeshLoad()
234: . PetscViewerDrawOpen() - Outputs mesh to an X window display
236: The user can call PetscViewerSetFormat() to specify the output
237: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
238: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
239: + PETSC_VIEWER_DEFAULT - default, prints mesh information
240: - PETSC_VIEWER_ASCII_VTK - outputs a VTK file describing the mesh
242: Level: beginner
244: Concepts: mesh^printing
245: Concepts: mesh^saving to disk
247: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
248: MeshLoad(), PetscViewerCreate()
249: @*/
250: PetscErrorCode MeshView(Mesh mesh, PetscViewer viewer)
251: {
257: if (!viewer) {
258: PetscViewerASCIIGetStdout(((PetscObject)mesh)->comm,&viewer);
259: }
263: PetscLogEventBegin(Mesh_View,0,0,0,0);
264: (*mesh->ops->view)(mesh, viewer);
265: PetscLogEventEnd(Mesh_View,0,0,0,0);
266: return(0);
267: }
271: /*@C
272: MeshLoad - Create a mesh topology from the saved data in a viewer.
274: Collective on Viewer
276: Input Parameter:
277: . viewer - The viewer containing the data
279: Output Parameters:
280: . mesh - the mesh object
282: Level: advanced
284: .seealso MeshView()
286: @*/
287: PetscErrorCode MeshLoad(PetscViewer viewer, Mesh mesh)
288: {
289: char *filename;
290: PetscErrorCode ierr;
293: if (!mesh->m) {
294: MPI_Comm comm;
296: PetscObjectGetComm((PetscObject) viewer, &comm);
297: ALE::Obj<PETSC_MESH_TYPE> m = new PETSC_MESH_TYPE(comm, 1);
299: MeshSetMesh(mesh, m);
300: }
301: PetscViewerFileGetName(viewer, &filename);
302: ALE::MeshSerializer::loadMesh(filename, *mesh->m);
303: return(0);
304: }
308: /*@C
309: MeshGetMesh - Gets the internal mesh object
311: Not collective
313: Input Parameter:
314: . mesh - the mesh object
316: Output Parameter:
317: . m - the internal mesh object
318:
319: Level: advanced
321: .seealso MeshCreate(), MeshSetMesh()
323: @*/
324: PetscErrorCode MeshGetMesh(Mesh mesh, ALE::Obj<PETSC_MESH_TYPE>& m)
325: {
328: m = mesh->m;
329: return(0);
330: }
334: /*@C
335: MeshSetMesh - Sets the internal mesh object
337: Not collective
339: Input Parameters:
340: + mesh - the mesh object
341: - m - the internal mesh object
342:
343: Level: advanced
345: .seealso MeshCreate(), MeshGetMesh()
347: @*/
348: PetscErrorCode MeshSetMesh(Mesh mesh, const ALE::Obj<PETSC_MESH_TYPE>& m)
349: {
352: mesh->m = m;
353: if (mesh->globalScatter) {
356: VecScatterDestroy(mesh->globalScatter);
357: mesh->globalScatter = PETSC_NULL;
358: }
359: return(0);
360: }
364: /*@C
365: MeshCreateMatrix - Creates a matrix with the correct parallel layout required for
366: computing the Jacobian on a function defined using the information in the Section.
368: Collective on Mesh
370: Input Parameters:
371: + mesh - the mesh object
372: . section - the section which determines data layout
373: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
374: or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).
376: Output Parameter:
377: . J - matrix with the correct nonzero preallocation
378: (obviously without the correct Jacobian values)
380: Level: advanced
382: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
383: do not need to do it yourself.
385: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
386: @*/
387: PetscErrorCode MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
388: {
389: ALE::Obj<PETSC_MESH_TYPE> m;
390: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
394: MeshGetMesh(mesh, m);
395: SectionRealGetSection(section, s);
396: try {
397: MeshCreateMatrix(m, s, mtype, J);
398: } catch(ALE::Exception e) {
399: SETERRQ(PETSC_ERR_LIB, e.message());
400: }
401: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
402: return(0);
403: }
407: PetscErrorCode MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
408: {
409: SectionReal section;
413: MeshGetVertexSectionReal(mesh, "default", 1, §ion);
414: MeshCreateMatrix(mesh, section, mtype, J);
415: SectionRealDestroy(section);
416: return(0);
417: }
421: /*@C
422: MeshGetMatrix - Creates a matrix with the correct parallel layout required for
423: computing the Jacobian on a function defined using the information in Mesh.
425: Collective on Mesh
427: Input Parameters:
428: + mesh - the mesh object
429: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
430: or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).
432: Output Parameter:
433: . J - matrix with the correct nonzero preallocation
434: (obviously without the correct Jacobian values)
436: Level: advanced
438: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
439: do not need to do it yourself.
441: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
443: @*/
444: PetscErrorCode MeshGetMatrix(Mesh mesh, const MatType mtype, Mat *J)
445: {
446: ALE::Obj<PETSC_MESH_TYPE> m;
447: PetscTruth flag;
448: PetscErrorCode ierr;
451: MeshHasSectionReal(mesh, "default", &flag);
452: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
453: MeshGetMesh(mesh, m);
454: MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
455: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
456: return(0);
457: }
461: /*@C
462: MeshCreate - Creates a DM object, used to manage data for an unstructured problem
463: described by a Sieve.
465: Collective on MPI_Comm
467: Input Parameter:
468: . comm - the processors that will share the global vector
470: Output Parameters:
471: . mesh - the mesh object
473: Level: advanced
475: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
477: @*/
478: PetscErrorCode MeshCreate(MPI_Comm comm,Mesh *mesh)
479: {
481: Mesh p;
485: *mesh = PETSC_NULL;
486: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
487: DMInitializePackage(PETSC_NULL);
488: #endif
490: PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
491: p->ops->view = MeshView_Mesh;
492: p->ops->destroy = PETSC_NULL;
493: p->ops->createglobalvector = MeshCreateGlobalVector;
494: p->ops->createlocalvector = MeshCreateLocalVector;
495: p->ops->getcoloring = PETSC_NULL;
496: p->ops->getmatrix = MeshGetMatrix;
497: p->ops->getinterpolation = MeshGetInterpolation_Mesh_New;
498: p->ops->getinjection = PETSC_NULL;
499: p->ops->refine = MeshRefine_Mesh;
500: p->ops->coarsen = PETSC_NULL;
501: p->ops->refinehierarchy = PETSC_NULL;
502: p->ops->coarsenhierarchy = MeshCoarsenHierarchy_Mesh;
504: PetscObjectChangeTypeName((PetscObject) p, "sieve");
506: new(&p->m) ALE::Obj<PETSC_MESH_TYPE>(PETSC_NULL);
507: p->globalScatter = PETSC_NULL;
508: p->lf = PETSC_NULL;
509: p->lj = PETSC_NULL;
510: p->data = PETSC_NULL;
511: *mesh = p;
512: return(0);
513: }
517: /*@
518: MeshDestroy - Destroys a mesh.
520: Collective on Mesh
522: Input Parameter:
523: . mesh - the mesh object
525: Level: advanced
527: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
528: @*/
529: PetscErrorCode MeshDestroy(Mesh mesh)
530: {
531: PetscErrorCode ierr;
534: if (--((PetscObject)mesh)->refct > 0) return(0);
535: PETSc::Log::Event("MeshDestroy").begin();
536: if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
537: mesh->m = PETSC_NULL;
538: PetscHeaderDestroy(mesh);
539: PETSc::Log::Event("MeshDestroy").end();
540: return(0);
541: }
545: /*@C
546: MeshSetType - Sets the Mesh type
548: Collective on Mesh
550: Input Parameters:
551: + mesh - the Mesh context
552: - type - the type
554: Options Database Key:
555: . -mesh_type <method> - Sets the type; use -help for a list
556: of available types (for instance, cartesian or sieve)
558: Notes:
559: See "petsc/include/petscmesh.h" for available types (for instance,
560: MESHCARTESIAN or MESHSIEVE).
562: Level: intermediate
564: .keywords: Mesh, set, typr
565: .seealso: MeshGetType(), MeshType
566: @*/
567: PetscErrorCode MeshSetType(Mesh mesh, const MeshType type)
568: {
569: PetscErrorCode ierr,(*r)(Mesh);
570: PetscTruth match;
576: PetscTypeCompare((PetscObject)mesh,type,&match);
577: if (match) return(0);
579: PetscFListFind(MeshList,((PetscObject)mesh)->comm,type,(void (**)(void)) &r);
580: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
581: /* Destroy the previous private Mesh context */
582: if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
583: /* Reinitialize function pointers in MeshOps structure */
584: PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
585: /* Call the MeshCreate_XXX routine for this particular mesh */
586: (*r)(mesh);
587: PetscObjectChangeTypeName((PetscObject) mesh, type);
588: return(0);
589: }
593: /*@C
594: MeshGetType - Gets the Mesh type as a string from the Mesh object.
596: Not Collective
598: Input Parameter:
599: . mesh - Mesh context
601: Output Parameter:
602: . name - name of Mesh type
604: Level: intermediate
606: .keywords: Mesh, get, type
607: .seealso: MeshSetType()
608: @*/
609: PetscErrorCode MeshGetType(Mesh mesh,const MeshType *type)
610: {
614: *type = ((PetscObject)mesh)->type_name;
615: return(0);
616: }
620: /*@C
621: MeshRegister - See MeshRegisterDynamic()
623: Level: advanced
624: @*/
625: PetscErrorCode MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
626: {
628: char fullname[PETSC_MAX_PATH_LEN];
631: PetscFListConcat(path,name,fullname);
632: PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
633: return(0);
634: }
637: EXTERN PetscErrorCode MeshCreate_Cartesian(Mesh);
642: /*@C
643: MeshRegisterAll - Registers all of the Mesh types in the Mesh package.
645: Not Collective
647: Level: advanced
649: .keywords: Mesh, register, all
650: .seealso: MeshRegisterDestroy()
651: @*/
652: PetscErrorCode MeshRegisterAll(const char path[])
653: {
657: MeshRegisterAllCalled = PETSC_TRUE;
659: MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
660: return(0);
661: }
665: /*@C
666: MeshRegisterDestroy - Frees the list of Mesh types that were
667: registered by MeshRegister().
669: Not Collective
671: Level: advanced
673: .keywords: Mesh, register, destroy
674: .seealso: MeshRegister(), MeshRegisterAll()
675: @*/
676: PetscErrorCode MeshRegisterDestroy(void)
677: {
681: PetscFListDestroy(&MeshList);
682: MeshRegisterAllCalled = PETSC_FALSE;
683: return(0);
684: }
688: /*@C
689: MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into
690: by the mesh.
692: Collective on Mesh
694: Input Parameter:
695: . mesh - the mesh object
697: Output Parameters:
698: . gvec - the global vector
700: Level: advanced
702: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
704: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
706: @*/
707: PetscErrorCode MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
708: {
709: ALE::Obj<PETSC_MESH_TYPE> m;
710: PetscTruth flag;
714: MeshHasSectionReal(mesh, "default", &flag);
715: if (!flag) {SETERRQ1(PETSC_ERR_ARG_WRONGSTATE, "Must set default section for mesh %p", m.objPtr);}
716: MeshGetMesh(mesh, m);
717: const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));
719: VecCreate(m->comm(), gvec);
720: VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
721: VecSetFromOptions(*gvec);
722: return(0);
723: }
727: /*@
728: MeshCreateVector - Creates a global vector matching the input section
730: Collective on Mesh
732: Input Parameters:
733: + mesh - the Mesh
734: - section - the Section
736: Output Parameter:
737: . vec - the global vector
739: Level: advanced
741: Notes: The vector can safely be destroyed using VecDestroy().
742: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
743: @*/
744: PetscErrorCode MeshCreateVector(Mesh mesh, SectionReal section, Vec *vec)
745: {
746: ALE::Obj<PETSC_MESH_TYPE> m;
747: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
751: MeshGetMesh(mesh, m);
752: SectionRealGetSection(section, s);
753: const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, s->getName(), s);
755: VecCreate(m->comm(), vec);
756: VecSetSizes(*vec, order->getLocalSize(), order->getGlobalSize());
757: VecSetFromOptions(*vec);
758: return(0);
759: }
763: /*@C
764: MeshCreateLocalVector - Creates a vector of the correct size for local computation.
766: Collective on Mesh
768: Input Parameter:
769: . mesh - the mesh object
771: Output Parameters:
772: . lvec - the local vector
774: Level: advanced
776: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
778: .seealso MeshDestroy(), MeshCreate(), MeshCreateGlobalVector()
780: @*/
781: PetscErrorCode MeshCreateLocalVector(Mesh mesh, Vec *lvec)
782: {
783: ALE::Obj<PETSC_MESH_TYPE> m;
784: PetscTruth flag;
788: MeshHasSectionReal(mesh, "default", &flag);
789: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
790: MeshGetMesh(mesh, m);
791: const int size = m->getRealSection("default")->getStorageSize();
793: VecCreate(PETSC_COMM_SELF, lvec);
794: VecSetSizes(*lvec, size, size);
795: VecSetFromOptions(*lvec);
796: return(0);
797: }
801: /*@C
802: MeshGetGlobalIndices - Gets the global indices for all the local entries
804: Collective on Mesh
806: Input Parameter:
807: . mesh - the mesh object
809: Output Parameters:
810: . idx - the individual indices for each packed vector/array
811:
812: Level: advanced
814: Notes:
815: The idx parameters should be freed by the calling routine with PetscFree()
817: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
819: @*/
820: PetscErrorCode MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
821: {
822: SETERRQ(PETSC_ERR_SUP, "");
823: }
827: /*@
828: MeshCreateGlobalScatter - Create a VecScatter which maps from local, overlapping
829: storage in the Section to a global Vec
831: Collective on Mesh
833: Input Parameters:
834: + mesh - the mesh object
835: - section - The Scetion which determines data layout
837: Output Parameter:
838: . scatter - the VecScatter
839:
840: Level: advanced
842: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
843: @*/
844: PetscErrorCode MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
845: {
846: ALE::Obj<PETSC_MESH_TYPE> m;
847: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
851: MeshGetMesh(mesh, m);
852: SectionRealGetSection(section, s);
853: MeshCreateGlobalScatter(m, s, scatter);
854: return(0);
855: }
859: PetscErrorCode MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
860: {
866: if (!mesh->globalScatter) {
867: SectionReal section;
869: MeshGetSectionReal(mesh, "default", §ion);
870: MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
871: SectionRealDestroy(section);
872: }
873: *scatter = mesh->globalScatter;
874: return(0);
875: }
879: PetscErrorCode MeshGetLocalFunction(Mesh mesh, PetscErrorCode (**lf)(Mesh, SectionReal, SectionReal, void *))
880: {
883: if (lf) *lf = mesh->lf;
884: return(0);
885: }
889: PetscErrorCode MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
890: {
893: mesh->lf = lf;
894: return(0);
895: }
899: PetscErrorCode MeshGetLocalJacobian(Mesh mesh, PetscErrorCode (**lj)(Mesh, SectionReal, Mat, void *))
900: {
903: if (lj) *lj = mesh->lj;
904: return(0);
905: }
909: PetscErrorCode MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
910: {
913: mesh->lj = lj;
914: return(0);
915: }
919: PetscErrorCode MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
920: {
927: if (mesh->lf) {
928: (*mesh->lf)(mesh, X, F, ctx);
929: }
930: return(0);
931: }
935: PetscErrorCode MeshFormJacobian(Mesh mesh, SectionReal X, Mat J, void *ctx)
936: {
943: if (mesh->lj) {
944: (*mesh->lj)(mesh, X, J, ctx);
945: }
946: return(0);
947: }
951: // Here we assume:
952: // - Assumes 3D and tetrahedron
953: // - The section takes values on vertices and is P1
954: // - Points have the same dimension as the mesh
955: // - All values have the same dimension
956: PetscErrorCode MeshInterpolatePoints(Mesh mesh, SectionReal section, int numPoints, double *points, double **values)
957: {
958: Obj<PETSC_MESH_TYPE> m;
959: Obj<PETSC_MESH_TYPE::real_section_type> s;
960: double *v0, *J, *invJ, detJ;
964: MeshGetMesh(mesh, m);
965: SectionRealGetSection(section, s);
966: const Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
967: int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
968: int dim = s->getFiberDimension(*m->depthStratum(0)->begin());
970: PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
971: PetscMalloc(numPoints*dim * sizeof(double), &values);
972: for(int p = 0; p < numPoints; p++) {
973: double *point = &points[p*embedDim];
974:
975: PETSC_MESH_TYPE::point_type e = m->locatePoint(point);
976: const PETSC_MESH_TYPE::real_section_type::value_type *coeff = s->restrictPoint(e);
978: m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
979: double xi = (invJ[0*embedDim+0]*(point[0] - v0[0]) + invJ[0*embedDim+1]*(point[1] - v0[1]) + invJ[0*embedDim+2]*(point[2] - v0[2]))*0.5;
980: double eta = (invJ[1*embedDim+0]*(point[0] - v0[0]) + invJ[1*embedDim+1]*(point[1] - v0[1]) + invJ[1*embedDim+2]*(point[2] - v0[2]))*0.5;
981: double zeta = (invJ[2*embedDim+0]*(point[0] - v0[0]) + invJ[2*embedDim+1]*(point[1] - v0[1]) + invJ[2*embedDim+2]*(point[2] - v0[2]))*0.5;
983: for(int d = 0; d < dim; d++) {
984: (*values)[p*dim+d] = coeff[0*dim+d]*(1 - xi - eta - zeta) + coeff[1*dim+d]*xi + coeff[2*dim+d]*eta + coeff[3*dim+d]*zeta;
985: }
986: }
987: PetscFree3(v0, J, invJ);
988: return(0);
989: }
993: /*@C
994: MeshGetMaximumDegree - Return the maximum degree of any mesh vertex
996: Collective on mesh
998: Input Parameter:
999: . mesh - The Mesh
1001: Output Parameter:
1002: . maxDegree - The maximum number of edges at any vertex
1004: Level: beginner
1006: .seealso: MeshCreate()
1007: @*/
1008: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
1009: {
1010: Obj<PETSC_MESH_TYPE> m;
1014: MeshGetMesh(mesh, m);
1015: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& vertices = m->depthStratum(0);
1016: const ALE::Obj<PETSC_MESH_TYPE::sieve_type>& sieve = m->getSieve();
1017: PetscInt maxDeg = -1;
1019: for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
1020: maxDeg = PetscMax(maxDeg, (PetscInt) sieve->getSupportSize(*v_iter));
1021: }
1022: *maxDegree = maxDeg;
1023: return(0);
1024: }
1026: EXTERN PetscErrorCode assembleFullField(VecScatter, Vec, Vec, InsertMode);
1030: /*@C
1031: restrictVector - Insert values from a global vector into a local ghosted vector
1033: Collective on g
1035: Input Parameters:
1036: + g - The global vector
1037: . l - The local vector
1038: - mode - either ADD_VALUES or INSERT_VALUES, where
1039: ADD_VALUES adds values to any existing entries, and
1040: INSERT_VALUES replaces existing entries with new values
1042: Level: beginner
1044: .seealso: MatSetOption()
1045: @*/
1046: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1047: {
1048: VecScatter injection;
1052: PetscLogEventBegin(Mesh_restrictVector,0,0,0,0);
1053: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1054: if (injection) {
1055: VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
1056: VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
1057: } else {
1058: if (mode == INSERT_VALUES) {
1059: VecCopy(g, l);
1060: } else {
1061: VecAXPY(l, 1.0, g);
1062: }
1063: }
1064: PetscLogEventEnd(Mesh_restrictVector,0,0,0,0);
1065: return(0);
1066: }
1070: /*@C
1071: assembleVectorComplete - Insert values from a local ghosted vector into a global vector
1073: Collective on g
1075: Input Parameters:
1076: + g - The global vector
1077: . l - The local vector
1078: - mode - either ADD_VALUES or INSERT_VALUES, where
1079: ADD_VALUES adds values to any existing entries, and
1080: INSERT_VALUES replaces existing entries with new values
1082: Level: beginner
1084: .seealso: MatSetOption()
1085: @*/
1086: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1087: {
1088: VecScatter injection;
1092: PetscLogEventBegin(Mesh_assembleVectorComplete,0,0,0,0);
1093: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1094: if (injection) {
1095: VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1096: VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1097: } else {
1098: if (mode == INSERT_VALUES) {
1099: VecCopy(l, g);
1100: } else {
1101: VecAXPY(g, 1.0, l);
1102: }
1103: }
1104: PetscLogEventEnd(Mesh_assembleVectorComplete,0,0,0,0);
1105: return(0);
1106: }
1110: /*@C
1111: assembleVector - Insert values into a vector
1113: Collective on A
1115: Input Parameters:
1116: + b - the vector
1117: . e - The element number
1118: . v - The values
1119: - mode - either ADD_VALUES or INSERT_VALUES, where
1120: ADD_VALUES adds values to any existing entries, and
1121: INSERT_VALUES replaces existing entries with new values
1123: Level: beginner
1125: .seealso: VecSetOption()
1126: @*/
1127: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1128: {
1129: Mesh mesh;
1130: SectionReal section;
1134: PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1135: MeshGetSectionReal(mesh, "x", §ion);
1136: assembleVector(b, mesh, section, e, v, mode);
1137: SectionRealDestroy(section);
1138: return(0);
1139: }
1141: PetscErrorCode assembleVector(Vec b, Mesh mesh, SectionReal section, PetscInt e, PetscScalar v[], InsertMode mode)
1142: {
1143: ALE::Obj<PETSC_MESH_TYPE> m;
1144: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
1145: PetscInt firstElement;
1146: PetscErrorCode ierr;
1149: PetscLogEventBegin(Mesh_assembleVector,0,0,0,0);
1150: MeshGetMesh(mesh, m);
1151: SectionRealGetSection(section, s);
1152: //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1153: firstElement = 0;
1154: #ifdef PETSC_USE_COMPLEX
1155: SETERRQ(PETSC_ERR_SUP, "SectionReal does not support complex update");
1156: #else
1157: if (mode == INSERT_VALUES) {
1158: m->update(s, PETSC_MESH_TYPE::point_type(e + firstElement), v);
1159: } else {
1160: m->updateAdd(s, PETSC_MESH_TYPE::point_type(e + firstElement), v);
1161: }
1162: #endif
1163: PetscLogEventEnd(Mesh_assembleVector,0,0,0,0);
1164: return(0);
1165: }
1169: PetscErrorCode updateOperator(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& section, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, const PETSC_MESH_TYPE::point_type& e, PetscScalar array[], InsertMode mode)
1170: {
1172: #ifdef PETSC_OPT_SIEVE
1173: typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
1174: visitor_type iV(*section, *globalOrder, (int) pow((double) m->getSieve()->getMaxConeSize(), m->depth())*m->getMaxDof(), m->depth() > 1);
1176: PetscErrorCode updateOperator(A, *m->getSieve(), iV, e, array, mode);
1177: #else
1178: const PETSC_MESH_TYPE::indices_type indicesBlock = m->getIndices(section, e, globalOrder);
1179: const PetscInt *indices = indicesBlock.first;
1180: const int& numIndices = indicesBlock.second;
1181: PetscErrorCode ierr;
1183: PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1184: if (section->debug()) {
1185: printf("[%d]mat for element %d\n", section->commRank(), e);
1186: for(int i = 0; i < numIndices; i++) {
1187: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1188: }
1189: for(int i = 0; i < numIndices; i++) {
1190: printf("[%d]", section->commRank());
1191: for(int j = 0; j < numIndices; j++) {
1192: printf(" %g", array[i*numIndices+j]);
1193: }
1194: printf("\n");
1195: }
1196: }
1197: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1198: if (ierr) {
1199: printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
1200: for(int i = 0; i < numIndices; i++) {
1201: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1202: }
1203:
1204: }
1205: PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1206: #endif
1207: return(0);
1208: }
1212: PetscErrorCode updateOperator(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& section, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, int tag, int p, PetscScalar array[], InsertMode mode)
1213: {
1214: #ifdef PETSC_OPT_SIEVE
1215: SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1216: #else
1217: const int *offsets, *indices;
1221: section->getCustomRestrictAtlas(tag, &offsets, &indices);
1222: const int& numIndices = offsets[p+1] - offsets[p];
1224: PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1225: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1226: if (ierr) {
1227: printf("[%d]ERROR in updateOperator: tag %d point num %d\n", section->commRank(), tag, p);
1228: for(int i = 0; i < numIndices; i++) {
1229: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1230: }
1231:
1232: }
1233: PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1234: #endif
1235: return(0);
1236: }
1240: PetscErrorCode updateOperatorGeneral(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& rowM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& rowSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& rowGlobalOrder, const PETSC_MESH_TYPE::point_type& rowE, const ALE::Obj<PETSC_MESH_TYPE>& colM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& colSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& colGlobalOrder, const PETSC_MESH_TYPE::point_type& colE, PetscScalar array[], InsertMode mode)
1241: {
1242: #ifdef PETSC_OPT_SIEVE
1243: typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
1244: visitor_type iVr(*rowSection, *rowGlobalOrder, (int) pow((double) rowM->getSieve()->getMaxConeSize(), rowM->depth())*rowM->getMaxDof(), rowM->depth() > 1);
1245: visitor_type iVc(*colSection, *colGlobalOrder, (int) pow((double) colM->getSieve()->getMaxConeSize(), colM->depth())*colM->getMaxDof(), colM->depth() > 1);
1247: PetscErrorCode updateOperator(A, *rowM->getSieve(), iVr, rowE, *colM->getSieve(), iVc, colE, array, mode);
1248: #else
1252: const PETSC_MESH_TYPE::indices_type rowIndicesBlock = rowM->getIndices(rowSection, rowE, rowGlobalOrder);
1254: const PetscInt *tmpIndices = rowIndicesBlock.first;
1255: const int numRowIndices = rowIndicesBlock.second;
1256: PetscInt *rowIndices = new PetscInt[numRowIndices];
1257: PetscMemcpy(rowIndices, tmpIndices, numRowIndices*sizeof(PetscInt));
1259: const PETSC_MESH_TYPE::indices_type colIndicesBlock = colM->getIndices(colSection, colE, colGlobalOrder);
1261: const PetscInt *colIndices = colIndicesBlock.first;
1262: const int numColIndices = colIndicesBlock.second;
1264: PetscLogEventBegin(Mesh_updateOperator,0,0,0,0);
1265: if (rowSection->debug()) {
1266: printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1267: for(int i = 0; i < numRowIndices; i++) {
1268: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1269: }
1270: }
1271: if (colSection->debug()) {
1272: for(int i = 0; i < numColIndices; i++) {
1273: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1274: }
1275: for(int i = 0; i < numRowIndices; i++) {
1276: printf("[%d]", rowSection->commRank());
1277: for(int j = 0; j < numColIndices; j++) {
1278: printf(" %g", array[i*numColIndices+j]);
1279: }
1280: printf("\n");
1281: }
1282: }
1283: MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1284: if (ierr) {
1285: printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1286: for(int i = 0; i < numRowIndices; i++) {
1287: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1288: }
1289: for(int i = 0; i < numColIndices; i++) {
1290: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1291: }
1292:
1293: }
1294: PetscLogEventEnd(Mesh_updateOperator,0,0,0,0);
1295: delete [] rowIndices;
1296: #endif
1297: return(0);
1298: }
1302: /*@
1303: MeshSetMaxDof - Sets the maximum number of degrees of freedom on any sieve point
1305: Collective on A
1307: Input Parameters:
1308: + A - the matrix
1309: . mesh - Mesh needed for orderings
1310: . section - A Section which describes the layout
1311: . e - The element number
1312: . v - The values
1313: - mode - either ADD_VALUES or INSERT_VALUES, where
1314: ADD_VALUES adds values to any existing entries, and
1315: INSERT_VALUES replaces existing entries with new values
1317: Notes: This is used by routines like updateOperator() to bound buffer sizes
1319: Level: developer
1321: .seealso: updateOperator(), assembleMatrix()
1322: @*/
1323: PetscErrorCode MeshSetMaxDof(Mesh mesh, PetscInt maxDof)
1324: {
1325: Obj<PETSC_MESH_TYPE> m;
1326: PetscErrorCode ierr;
1329: MeshGetMesh(mesh, m);
1330: m->setMaxDof(maxDof);
1331: return(0);
1332: }
1336: /*@
1337: assembleMatrix - Insert values into a matrix
1339: Collective on A
1341: Input Parameters:
1342: + A - the matrix
1343: . mesh - Mesh needed for orderings
1344: . section - A Section which describes the layout
1345: . e - The element
1346: . v - The values
1347: - mode - either ADD_VALUES or INSERT_VALUES, where
1348: ADD_VALUES adds values to any existing entries, and
1349: INSERT_VALUES replaces existing entries with new values
1351: Level: beginner
1353: .seealso: MatSetOption()
1354: @*/
1355: PetscErrorCode assembleMatrix(Mat A, Mesh mesh, SectionReal section, PetscInt e, PetscScalar v[], InsertMode mode)
1356: {
1360: PetscLogEventBegin(Mesh_assembleMatrix,0,0,0,0);
1361: try {
1362: Obj<PETSC_MESH_TYPE> m;
1363: Obj<PETSC_MESH_TYPE::real_section_type> s;
1365: MeshGetMesh(mesh, m);
1366: SectionRealGetSection(section, s);
1367: const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, s->getName(), s);
1369: if (m->debug()) {
1370: std::cout << "Assembling matrix for element number " << e << " --> point " << e << std::endl;
1371: }
1372: updateOperator(A, m, s, globalOrder, e, v, mode);
1373: } catch (ALE::Exception e) {
1374: std::cout << e.msg() << std::endl;
1375: }
1376: PetscLogEventEnd(Mesh_assembleMatrix,0,0,0,0);
1377: return(0);
1378: }
1382: PetscErrorCode preallocateMatrix(const ALE::Obj<PETSC_MESH_TYPE>& mesh, const int bs, const ALE::Obj<PETSC_MESH_TYPE::real_section_type::atlas_type>& atlas, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, Mat A)
1383: {
1384: #ifdef PETSC_OPT_SIEVE
1385: SETERRQ(PETSC_ERR_SUP, "This is not applicable for optimized sieves");
1386: #else
1387: PetscInt localSize = globalOrder->getLocalSize();
1388: PetscInt *dnz, *onz;
1392: PetscMalloc2(localSize, PetscInt, &dnz, localSize, PetscInt, &onz);
1393: preallocateOperator(mesh, bs, atlas, globalOrder, dnz, onz, A);
1394: PetscFree2(dnz, onz);
1395: return(0);
1396: #endif
1397: }
1399: /******************************** C Wrappers **********************************/
1403: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1404: {
1405: return VTKViewer::writeHeader(viewer);
1406: }
1410: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1411: {
1412: ALE::Obj<PETSC_MESH_TYPE> m;
1415: MeshGetMesh(mesh, m);
1416: return VTKViewer::writeVertices(m, viewer);
1417: }
1421: PetscErrorCode WriteVTKElements(Mesh mesh, PetscViewer viewer)
1422: {
1423: ALE::Obj<PETSC_MESH_TYPE> m;
1426: MeshGetMesh(mesh, m);
1427: return VTKViewer::writeElements(m, viewer);
1428: }
1432: PetscErrorCode WritePCICEVertices(Mesh mesh, PetscViewer viewer)
1433: {
1434: ALE::Obj<PETSC_MESH_TYPE> m;
1437: MeshGetMesh(mesh, m);
1438: return ALE::PCICE::Viewer::writeVertices(m, viewer);
1439: }
1443: PetscErrorCode WritePCICEElements(Mesh mesh, PetscViewer viewer)
1444: {
1445: ALE::Obj<PETSC_MESH_TYPE> m;
1448: MeshGetMesh(mesh, m);
1449: return ALE::PCICE::Viewer::writeElements(m, viewer);
1450: }
1454: PetscErrorCode WritePCICERestart(Mesh mesh, PetscViewer viewer)
1455: {
1456: ALE::Obj<PETSC_MESH_TYPE> m;
1459: MeshGetMesh(mesh, m);
1460: return ALE::PCICE::Viewer::writeRestart(m, viewer);
1461: }
1465: /*@C
1466: MeshCreatePCICE - Create a Mesh from PCICE files.
1468: Not Collective
1470: Input Parameters:
1471: + dim - The topological mesh dimension
1472: . coordFilename - The file containing vertex coordinates
1473: . adjFilename - The file containing the vertices for each element
1474: . interpolate - The flag for construction of intermediate elements
1475: . bcFilename - The file containing the boundary topology and conditions
1476: . numBdFaces - The number of boundary faces (or edges)
1477: - numBdVertices - The number of boundary vertices
1479: Output Parameter:
1480: . mesh - The Mesh object
1482: Level: beginner
1484: .keywords: mesh, PCICE
1485: .seealso: MeshCreate()
1486: @*/
1487: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], Mesh *mesh)
1488: {
1489: ALE::Obj<PETSC_MESH_TYPE> m;
1490: PetscInt debug = 0;
1491: PetscTruth flag;
1492: PetscErrorCode ierr;
1495: MeshCreate(comm, mesh);
1496: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1497: try {
1498: m = ALE::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1499: if (debug) {m->view("Mesh");}
1500: } catch(ALE::Exception e) {
1501: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1502: }
1503: if (bcFilename) {
1504: ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1505: }
1506: MeshSetMesh(*mesh, m);
1507: return(0);
1508: }
1512: /*@C
1513: MeshCreatePyLith - Create a Mesh from PyLith files.
1515: Not Collective
1517: Input Parameters:
1518: + dim - The topological mesh dimension
1519: . baseFilename - The basename for mesh files
1520: . zeroBase - Use 0 to start numbering
1521: - interpolate - The flag for mesh interpolation
1523: Output Parameter:
1524: . mesh - The Mesh object
1526: Level: beginner
1528: .keywords: mesh, PCICE
1529: .seealso: MeshCreate()
1530: @*/
1531: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1532: {
1533: ALE::Obj<PETSC_MESH_TYPE> m;
1534: PetscInt debug = 0;
1535: PetscTruth flag;
1536: PetscErrorCode ierr;
1539: MeshCreate(comm, mesh);
1540: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1541: try {
1542: m = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1543: } catch(ALE::Exception e) {
1544: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1545: }
1546: MeshSetMesh(*mesh, m);
1547: return(0);
1548: }
1552: /*@C
1553: MeshGetCoordinates - Creates an array holding the coordinates.
1555: Not Collective
1557: Input Parameter:
1558: + mesh - The Mesh object
1559: - columnMajor - Flag for column major order
1561: Output Parameter:
1562: + numVertices - The number of vertices
1563: . dim - The embedding dimension
1564: - coords - The array holding local coordinates
1566: Level: intermediate
1568: .keywords: mesh, coordinates
1569: .seealso: MeshCreate()
1570: @*/
1571: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1572: {
1573: ALE::Obj<PETSC_MESH_TYPE> m;
1574: PetscErrorCode ierr;
1577: MeshGetMesh(mesh, m);
1578: ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1579: return(0);
1580: }
1584: /*@C
1585: MeshGetElements - Creates an array holding the vertices on each element.
1587: Not Collective
1589: Input Parameters:
1590: + mesh - The Mesh object
1591: - columnMajor - Flag for column major order
1593: Output Parameters:
1594: + numElements - The number of elements
1595: . numCorners - The number of vertices per element
1596: - vertices - The array holding vertices on each local element
1598: Level: intermediate
1600: .keywords: mesh, elements
1601: .seealso: MeshCreate()
1602: @*/
1603: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1604: {
1605: ALE::Obj<PETSC_MESH_TYPE> m;
1606: PetscErrorCode ierr;
1609: MeshGetMesh(mesh, m);
1610: ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1611: return(0);
1612: }
1616: /*@C
1617: MeshGetCone - Creates an array holding the cone of a given point
1619: Not Collective
1621: Input Parameters:
1622: + mesh - The Mesh object
1623: - p - The mesh point
1625: Output Parameters:
1626: + numPoints - The number of points in the cone
1627: - points - The array holding the cone points
1629: Level: intermediate
1631: .keywords: mesh, cone
1632: .seealso: MeshCreate()
1633: @*/
1634: PetscErrorCode MeshGetCone(Mesh mesh, PetscInt p, PetscInt *numPoints, PetscInt *points[])
1635: {
1636: ALE::Obj<PETSC_MESH_TYPE> m;
1637: PetscErrorCode ierr;
1640: MeshGetMesh(mesh, m);
1641: *numPoints = m->getSieve()->getConeSize(p);
1642: ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type> v(*numPoints);
1644: m->getSieve()->cone(p, v);
1645: *points = const_cast<PetscInt*>(v.getPoints());
1646: return(0);
1647: }
1651: /*@C
1652: MeshDistribute - Distributes the mesh and any associated sections.
1654: Not Collective
1656: Input Parameter:
1657: + serialMesh - The original Mesh object
1658: - partitioner - The partitioning package, or NULL for the default
1660: Output Parameter:
1661: . parallelMesh - The distributed Mesh object
1663: Level: intermediate
1665: .keywords: mesh, elements
1667: .seealso: MeshCreate(), MeshDistributeByFace()
1668: @*/
1669: PetscErrorCode MeshDistribute(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1670: {
1671: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1672: PetscErrorCode ierr;
1675: MeshGetMesh(serialMesh, oldMesh);
1676: MeshCreate(oldMesh->comm(), parallelMesh);
1677: #ifdef PETSC_OPT_SIEVE
1678: const Obj<PETSC_MESH_TYPE> newMesh = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->getDimension(), oldMesh->debug());
1679: const Obj<PETSC_MESH_TYPE::sieve_type> newSieve = new PETSC_MESH_TYPE::sieve_type(oldMesh->comm(), oldMesh->debug());
1681: newMesh->setSieve(newSieve);
1682: PetscPrintf(oldMesh->comm(), "Starting Mesh Distribution");
1683: ALE::DistributionNew<PETSC_MESH_TYPE>::distributeMeshAndSectionsV(oldMesh, newMesh);
1684: MeshSetMesh(*parallelMesh, newMesh);
1685: PetscPrintf(oldMesh->comm(), "Ending Mesh Distribution");
1686: #else
1687: if (partitioner == NULL) {
1688: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh);
1689: MeshSetMesh(*parallelMesh, newMesh);
1690: } else {
1691: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 0, partitioner);
1692: MeshSetMesh(*parallelMesh, newMesh);
1693: }
1694: #endif
1695: return(0);
1696: }
1700: /*@C
1701: MeshDistribute - Distributes the mesh and any associated sections.
1703: Not Collective
1705: Input Parameter:
1706: + serialMesh - The original Mesh object
1707: - partitioner - The partitioning package, or NULL for the default
1709: Output Parameter:
1710: . parallelMesh - The distributed Mesh object
1712: Level: intermediate
1714: .keywords: mesh, elements
1716: .seealso: MeshCreate(), MeshDistribute()
1717: @*/
1718: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1719: {
1720: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1721: PetscErrorCode ierr;
1724: MeshGetMesh(serialMesh, oldMesh);
1725: MeshCreate(oldMesh->comm(), parallelMesh);
1726: #ifdef PETSC_OPT_SIEVE
1727: SETERRQ(PETSC_ERR_SUP, "I am being lazy, bug me.");
1728: #else
1729: if (partitioner == NULL) {
1730: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1);
1731: MeshSetMesh(*parallelMesh, newMesh);
1732: } else {
1733: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Distribution<PETSC_MESH_TYPE>::distributeMesh(oldMesh, 1, partitioner);
1734: MeshSetMesh(*parallelMesh, newMesh);
1735: }
1736: #endif
1737: return(0);
1738: }
1742: /*@C
1743: MeshGenerate - Generates a mesh.
1745: Not Collective
1747: Input Parameters:
1748: + boundary - The Mesh boundary object
1749: - interpolate - Flag to create intermediate mesh elements
1751: Output Parameter:
1752: . mesh - The Mesh object
1754: Level: intermediate
1756: .keywords: mesh, elements
1757: .seealso: MeshCreate(), MeshRefine()
1758: @*/
1759: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1760: {
1761: ALE::Obj<PETSC_MESH_TYPE> mB;
1762: PetscErrorCode ierr;
1765: MeshGetMesh(boundary, mB);
1766: MeshCreate(mB->comm(), mesh);
1767: #ifdef PETSC_OPT_SIEVE
1768: ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMeshV(mB, interpolate);
1769: #else
1770: ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMesh(mB, interpolate);
1771: #endif
1772: MeshSetMesh(*mesh, m);
1773: return(0);
1774: }
1778: /*@C
1779: MeshRefine - Refines the mesh.
1781: Not Collective
1783: Input Parameters:
1784: + mesh - The original Mesh object
1785: . refinementLimit - The maximum size of any cell
1786: - interpolate - Flag to create intermediate mesh elements
1788: Output Parameter:
1789: . refinedMesh - The refined Mesh object
1791: Level: intermediate
1793: .keywords: mesh, elements
1794: .seealso: MeshCreate(), MeshGenerate()
1795: @*/
1796: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1797: {
1798: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1799: PetscErrorCode ierr;
1802: MeshGetMesh(mesh, oldMesh);
1803: MeshCreate(oldMesh->comm(), refinedMesh);
1804: #ifdef PETSC_OPT_SIEVE
1805: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, interpolate);
1806: #else
1807: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, interpolate);
1808: #endif
1809: MeshSetMesh(*refinedMesh, newMesh);
1810: return(0);
1811: }
1815: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1816: {
1817: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1818: double refinementLimit;
1819: PetscErrorCode ierr;
1822: MeshGetMesh(mesh, oldMesh);
1823: MeshCreate(comm, refinedMesh);
1824: refinementLimit = oldMesh->getMaxVolume()/2.0;
1825: #ifdef PETSC_OPT_SIEVE
1826: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, true);
1827: #else
1828: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMesh(oldMesh, refinementLimit, true);
1829: #endif
1830: MeshSetMesh(*refinedMesh, newMesh);
1831: #ifndef PETSC_OPT_SIEVE
1832: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");
1833: const Obj<std::set<std::string> >& discs = oldMesh->getDiscretizations();
1835: for(std::set<std::string>::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter) {
1836: newMesh->setDiscretization(*f_iter, oldMesh->getDiscretization(*f_iter));
1837: }
1838: newMesh->setupField(s);
1839: #endif
1840: return(0);
1841: }
1843: #ifndef PETSC_OPT_SIEVE
1845: #include "Hierarchy_New.hh"
1851: #include "Hierarchy.hh"
1855: /*@C
1856: MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.
1858: Not Collective
1860: Input Parameters:
1861: + mesh - The original Mesh object
1862: . numLevels - The number of
1863: . coarseningFactor - The expansion factor for coarse meshes
1864: - interpolate - Flag to create intermediate mesh elements
1866: Output Parameter:
1867: . coarseHierarchy - The coarse Mesh objects
1869: Level: intermediate
1871: .keywords: mesh, elements
1872: .seealso: MeshCreate(), MeshGenerate()
1873: @*/
1874: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh *coarseHierarchy)
1875: {
1876: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1877: PetscErrorCode ierr;
1880: if (numLevels < 1) {
1881: *coarseHierarchy = PETSC_NULL;
1882: return(0);
1883: }
1884: MeshGetMesh(mesh, oldMesh);
1885: for (int i = 0; i < numLevels; i++) {
1886: MeshCreate(oldMesh->comm(), &coarseHierarchy[i]);
1887: }
1888: MeshSpacingFunction(mesh);
1889: MeshCreateHierarchyLabel_Link(mesh, coarseningFactor, numLevels+1, coarseHierarchy);
1890:
1891: #if 0
1892: if (oldMesh->getDimension() != 2) SETERRQ(PETSC_ERR_SUP, "Coarsening only works in two dimensions right now");
1893: ALE::Coarsener::IdentifyBoundary(oldMesh, 2);
1894: ALE::Coarsener::make_coarsest_boundary(oldMesh, 2, numLevels+1);
1895: ALE::Coarsener::CreateSpacingFunction(oldMesh, 2);
1896: ALE::Coarsener::CreateCoarsenedHierarchyNew(oldMesh, 2, numLevels, coarseningFactor);
1897: PetscMalloc(numLevels * sizeof(Mesh),coarseHierarchy);
1898: for(int l = 0; l < numLevels; l++) {
1899: ALE::Obj<PETSC_MESH_TYPE> newMesh = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->debug());
1900: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& s = newMesh->getRealSection("default");
1902: MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1903: newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1904: newMesh->setDiscretization(oldMesh->getDiscretization());
1905: newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1906: newMesh->setupField(s);
1907: MeshSetMesh((*coarseHierarchy)[l], newMesh);
1908: }
1909: #endif
1910: return(0);
1911: }
1913: #endif
1915: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh *coarseHierarchy)
1916: {
1918: double cfactor = 1.5;
1920: PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1921: #ifdef PETSC_OPT_SIEVE
1922: SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
1923: #else
1924: MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1925: #endif
1926: return(0);
1927: }
1929: #if 0
1934: //Interpolate between two meshes whenever the unknowns can be evaluated at points.
1936: PetscErrorCode MeshGetInterpolation_Mesh_General(Mesh coarse_mesh, Mesh fine_mesh, Mat *interpolation, Vec *scaling) {
1937: ALE::Obj<PETSC_MESH_TYPE> fm, cm;
1938: Mat P;
1939: PetscErrorCode ierr;
1940:
1942: //Stages:
1943: // 1. Create a section on the fine mesh describing the location in the fine mesh of the assorted unknowns.
1944: // 2. Fill in this section by traversing across the mesh via cones and supports, transforming the coordinates of the assorted functional points
1945: // 3. Preallocate the matrix rows/columns
1946: // 4. Assemble the matrix by writing evaluating each unknown as the point
1947: MeshGetMesh(dmFine, fm);
1948: MeshGetMesh(dmCoarse, cm);
1949: // ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
1950: // ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal = fm->createLabel ("traversal");
1951: const int debug = fm->debug();
1952: if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1953: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates = fm->getRealSection("coordinates");
1954: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
1956: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse = cm->getRealSection("default");
1957: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine = fm->getRealSection("default");
1959: const ALE::Obj<PETSC_MESH_TYPE::order_type>& coarseOrder = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1960: const ALE::Obj<PETSC_MESH_TYPE::order_type>& fineOrder = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
1962: std::list<PETSC_MESH_TYPE::point_type> travlist; // store point
1963: std::list<PETSC_MESH_TYPE::point_type> travguesslist; // store guess
1964: std::list<PETSC_MESH_TYPE::point_type> eguesslist; // store the next guesses for the location of the current point.
1966: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1967: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
1968: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> covering_points = PETSC_MESH_TYPE::sieve_type::supportSet();
1970: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> uncorrected_points = PETSC_MESH_TYPE::sieve_type::supportSet();
1971: static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1972: if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}
1974: //set up the new section holding the names of the contained points.
1976: const ALE::Obj<PETSC_MESH_TYPE::int_section_type> & node_locations = fm->getIntSection("node_locations");
1977: const ALE::Obj<PETSC_MESH_TYPE::real_section_type> & fine_default = fm->getRealSection("default");
1978: int total_dimension
1979: for (int i = 0; i < dim; i++) {
1980: const ALE::Obj<PETSC_MESH_TYPE::label_sequence> & present_level = fm->depthStratum(i);
1981: int current_dimension = fine_default->getFiberDimension(*present_level->begin());
1982: node_locations->setFiberDimension(present_level, current_dimension);
1983: }
1984: node_locations->allocate();
1985: //traverse!
1987:
1989: ALE::Obj<PETSC_MESH_TYPE::label_sequence> fine_cells = fm->heightStratum(0);
1990: ALE::Obj<PETSC_MESH_TYPE::label_sequence> coarse_cells = cm->heightStratum(0);
1992: PETSC_MESH_TYPE::label_sequence::iterator fc_iter = fine_cells->begin();
1993: PETSC_MESH_TYPE::label_sequence::iterator fc_iter_end = fine_cells->end();
1994: while (fc_iter != fc_iter_end) {
1995: //locate an initial coarse cell that overlaps with this fine cell in terms of their bounding boxes;
1996: PETSC_MESH_TYPE::label_sequence::iterator cc_iter = coarse_cells->begin();
1997: PETSC_MESH_TYPE::label_sequence::iterator cc_iter_end = coarse_cells->end();
1998: while (cc_iter != cc_iter_end) {
1999:
2000: cc_iter++;
2001: }
2002: fc_iter++;
2003: }
2004: }
2006: #endif
2011: PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling) {
2013: #ifdef PETSC_OPT_SIEVE
2014: SETERRQ(PETSC_ERR_SUP, "This needs to be rewritten for optimized meshes.");
2015: #else
2016: ALE::Obj<PETSC_MESH_TYPE> fm, cm;
2017: Mat P;
2018: PetscErrorCode ierr;
2021: MeshGetMesh(dmFine, fm);
2022: MeshGetMesh(dmCoarse, cm);
2023: // ALE::Obj<PETSC_MESH_TYPE::label_type> coarsetraversal = cm->createLabel("traversal");
2024: // ALE::Obj<PETSC_MESH_TYPE::label_type> finetraversal = fm->createLabel ("traversal");
2025: const int debug = fm->debug();
2026: if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
2027: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& finecoordinates = fm->getRealSection("coordinates");
2028: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
2029: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse = cm->getRealSection("default");
2030: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine = fm->getRealSection("default");
2031: const ALE::Obj<PETSC_MESH_TYPE::order_type>& coarseOrder = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
2032: const ALE::Obj<PETSC_MESH_TYPE::order_type>& fineOrder = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
2033: std::list<PETSC_MESH_TYPE::point_type> travlist; // store point
2034: std::list<PETSC_MESH_TYPE::point_type> travguesslist; // store guess
2035: std::list<PETSC_MESH_TYPE::point_type> eguesslist; // store the next guesses for the location of the current point.
2036: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> coarse_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
2037: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> fine_traversal = PETSC_MESH_TYPE::sieve_type::supportSet();
2038: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> uncorrected_points = PETSC_MESH_TYPE::sieve_type::supportSet();
2039: static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
2040: if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}
2042: MatCreate(fm->comm(), &P);
2043: MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2044: MatSeqAIJSetPreallocation(P,10,PETSC_NULL);
2045: MatSetFromOptions(P);
2047: const int dim = fm->getDimension();
2048: int maxComparisons = 60; //point is considered a lost cause beyond this many comparisons with volumes
2049: if (dim == 3) maxComparisons = 1000; //3D is odd
2050: if (dim != cm->getDimension()) throw ALE::Exception("Dimensions of the fine and coarse meshes do not match");
2052: //traversal labels on both layers
2053: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& finevertices = fm->depthStratum(0);
2054: const PETSC_MESH_TYPE::label_sequence::iterator fv_iter_end = finevertices->end();
2055: PETSC_MESH_TYPE::label_sequence::iterator fv_iter = finevertices->begin();
2057: // while (fv_iter != fv_iter_end) {
2058: // fm->setValue(finetraversal, *fv_iter, 0);
2059: // fv_iter++;
2060: // }
2062: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& coarseelements = cm->heightStratum(0);
2063: const PETSC_MESH_TYPE::label_sequence::iterator ce_iter_end = coarseelements->end();
2064: PETSC_MESH_TYPE::label_sequence::iterator ce_iter = coarseelements->begin();
2065:
2066: // while (ce_iter != ce_iter_end) {
2067: // cm->setValue(coarsetraversal, *ce_iter, 0);
2068: // ce_iter++;
2069: // }
2071: double *fvCoords = new double[dim], *nvCoords = new double[dim];
2072: bool pointIsInElement;
2074: if (debug) {PetscPrintf(fm->comm(), "starting iterations\n");}
2075: fv_iter = finevertices->begin();
2076: while (fv_iter != fv_iter_end) {
2077: // locate an initial point.
2078: // if (fm->getValue(finetraversal, *fv_iter) == 0) {
2079: if ((fine_traversal->find(*fv_iter) == fine_traversal->end()) && (uncorrected_points->find(*fv_iter) == uncorrected_points->end())) {
2080: bool isLocated = false;
2082: ce_iter = coarseelements->begin();
2083: PetscMemcpy(fvCoords, finecoordinates->restrictPoint(*fv_iter), dim*sizeof(double));
2084: while ((ce_iter != ce_iter_end) && (!isLocated)) {
2085: cm->computeElementGeometry(coarsecoordinates, *ce_iter, v0, J, invJ, detJ);
2086: // generalized simplicial location for 2D, 3D:
2087: loc[0] = 1.0;
2088: pointIsInElement = true;
2089: for(int i = 0; i < dim; i++) {
2090: loc[i+1] = 0.0;
2091: for(int j = 0; j < dim; j++) {
2092: loc[i+1] += 0.5*invJ[i*dim+j]*(fvCoords[j] - v0[j]);
2093: }
2094: loc[0] -= loc[i+1];
2095: //PetscPrintf(fm->comm(), "%f, ", loc[i+1]);
2096: if (loc[i+1] < -0.000000000001) pointIsInElement = false;
2097: }
2098: //PetscPrintf(fm->comm(), "%f\n", loc[0]);
2099: if (loc[0] < -0.000000000001) pointIsInElement = false;
2100: if (pointIsInElement) {
2101: //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2102: //PetscPrintf(fm->comm(), "located by guess.\n");
2103: isLocated = true;
2104: updateOperatorGeneral(P, fm, sFine, fineOrder, *fv_iter, cm, sCoarse, coarseOrder, *ce_iter, loc, INSERT_VALUES);
2105: //fm->setValue(finetraversal, *fv_iter, 1);
2106: fine_traversal->insert(*fv_iter);
2107: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> & neighbors = fm->getSieve()->cone(fm->getSieve()->support(*fv_iter));
2108: const PETSC_MESH_TYPE::sieve_type::coneSet::iterator n_iter_end = neighbors->end();
2109: PETSC_MESH_TYPE::sieve_type::coneSet::iterator n_iter = neighbors->begin();
2110: while (n_iter != n_iter_end) {
2111: // if (fm->getValue(finetraversal, *n_iter) == 0) {
2112: if (fine_traversal->find(*n_iter) != fine_traversal->end()) {
2113: travlist.push_back(*n_iter);
2114: // fm->setValue(finetraversal, *n_iter, 1);
2115: fine_traversal->insert(*n_iter);
2116: travguesslist.push_back(*ce_iter);
2117: }
2118: n_iter++;
2119: }
2120: //do a DFS across the finemesh with BFSes on the coarse mesh for each point using assumed regularity of edgelength as a justification for guessing neighboring point's locations.
2121: while (!travlist.empty()) {
2122: PETSC_MESH_TYPE::point_type curVert = *travlist.begin();
2123: PetscMemcpy(nvCoords, finecoordinates->restrictPoint(curVert), dim*sizeof(double));
2124: PETSC_MESH_TYPE::point_type curEle = *travguesslist.begin();
2125: travlist.pop_front();
2126: travguesslist.pop_front();
2127: eguesslist.push_front(curEle);
2128: //cm->setValue(coarsetraversal, curEle, 1);
2129: coarse_traversal->insert(curEle);
2130: bool locationDiscovered = false;
2131: //int traversalcomparisons = 0;
2132: while ((!eguesslist.empty()) && (!locationDiscovered) && (int)coarse_traversal->size() < maxComparisons) {
2133: //traversalcomparisons = 0;
2134: PETSC_MESH_TYPE::point_type curguess = *eguesslist.begin();
2135: eguesslist.pop_front();
2136: pointIsInElement = true;
2137: cm->computeElementGeometry(coarsecoordinates, curguess, v0, J, invJ, detJ);
2138: loc[0] = 1.0;
2139: for(int i = 0; i < dim; i++) {
2140: loc[i+1] = 0.0;
2141: for(int j = 0; j < dim; j++) {
2142: loc[i+1] += 0.5*invJ[i*dim+j]*(nvCoords[j] - v0[j]);
2143: }
2144: loc[0] -= loc[i+1];
2145: if (loc[i+1] < -0.00000000001) pointIsInElement = false;
2146: }
2147: if (loc[0] < -0.00000000001) pointIsInElement = false;
2149: if (pointIsInElement) {
2150: //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2151: locationDiscovered = true;
2152: //PetscPrintf(fm->comm(), "located by traversal.\n");
2153: //set the label.
2154: //fm->setValue(prolongation, curVert, curguess);
2155: updateOperatorGeneral(P, fm, sFine, fineOrder, curVert, cm, sCoarse, coarseOrder, curguess, loc, INSERT_VALUES);
2156: //PetscPrintf(fm->comm(), "Point %d located in %d.\n", curVert, curguess);
2157: //stick its neighbors in the queue along with its location as a good guess of the location of its neighbors
2158: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::coneSet> newNeighbors = fm->getSieve()->cone(fm->getSieve()->support(curVert));
2159: const PETSC_MESH_TYPE::sieve_type::coneSet::iterator nn_iter_end = newNeighbors->end();
2160: PETSC_MESH_TYPE::sieve_type::coneSet::iterator nn_iter = newNeighbors->begin();
2161: while (nn_iter != nn_iter_end) {
2162: //if (fm->getValue(finetraversal, *nn_iter) == 0) { //unlocated neighbor
2163: if (fine_traversal->find(*nn_iter) == fine_traversal->end()) {
2164: travlist.push_back(*nn_iter);
2165: travguesslist.push_back(curguess);
2166: //fm->setValue(finetraversal, *nn_iter, 1);
2167: fine_traversal->insert(*nn_iter);
2168: }
2169: nn_iter++;
2170: }
2171: } else {
2172: //add the current guesses neighbors to the comparison queue and start over.
2173: const ALE::Obj<PETSC_MESH_TYPE::sieve_type::supportSet> & curguessneighbors = cm->getSieve()->support(cm->getSieve()->cone(curguess));
2174: const PETSC_MESH_TYPE::sieve_type::supportSet::iterator cgn_iter_end = curguessneighbors->end();
2175: PETSC_MESH_TYPE::sieve_type::supportSet::iterator cgn_iter = curguessneighbors->begin();
2176: while (cgn_iter != cgn_iter_end) {
2177: //if (cm->getValue(coarsetraversal, *cgn_iter) == 0) {
2178: if (coarse_traversal->find(*cgn_iter) == coarse_traversal->end()) {
2179: eguesslist.push_back(*cgn_iter);
2180: //cm->setValue(coarsetraversal, *cgn_iter, 1);
2181: coarse_traversal->insert(*cgn_iter);
2182: }
2183: cgn_iter++;
2184: }
2185: }
2186: }
2187: coarse_traversal->clear();
2188: if (!locationDiscovered) { //if a position for it is not discovered, it doesn't get corrected; complain
2189: if (fm->debug())PetscPrintf(fm->comm(), "Point %d (%f, %f) not located.\n", curVert, nvCoords[0], nvCoords[1]);
2190: //fm->setValue(finetraversal, curVert, 2); //don't try again.
2191: uncorrected_points->insert(curVert);
2192: }
2193: eguesslist.clear(); //we've discovered the location of the point or exhausted our possibilities on this contiguous block of elements.
2194: //unset the traversed element list
2195: //const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& traved_elements = cm->getLabelStratum("traversal", 1);
2196: //const PETSC_MESH_TYPE::label_sequence::iterator tp_iter_end = traved_elements->end();
2197: //PETSC_MESH_TYPE::label_sequence::iterator tp_iter = traved_elements->begin();
2198: //PetscPrintf(cm->comm(), "%d\n", traved_elements->size());
2199: //while (tp_iter != tp_iter_end) {
2200: // eguesslist.push_back(*tp_iter);
2201: // tp_iter++;
2202: //}
2203: //while (!eguesslist.empty()) {
2204: // cm->setValue(coarsetraversal, *eguesslist.begin(), 0);
2205: // eguesslist.pop_front();
2206: //}
2207:
2208: }
2209: }
2210: ce_iter++;
2211: }
2212: if (!isLocated) {
2213: if (fm->debug())PetscPrintf(fm->comm(), "NOT located\n");
2214: //fm->setValue(finetraversal, *fv_iter, 2); //don't try again.
2215: uncorrected_points->insert(*fv_iter);
2216: }
2217: }
2218: // printf("-");
2219: fv_iter++;
2220: }
2221: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2222: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2223: //MatView(P, PETSC_VIEWER_STDOUT_SELF);
2224: delete [] fvCoords; delete [] nvCoords;
2225: *interpolation = P;
2226: if (debug) {PetscPrintf(fm->comm(), "Ending Interpolation Matrix Build\n");}
2227: return(0);
2228: #endif
2229: }
2234: /*
2235: This method only handle P_1 discretizations at present.
2236: */
2237: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
2238: {
2239: #ifdef PETSC_OPT_SIEVE
2240: SETERRQ(PETSC_ERR_SUP, "This has been superceded.");
2241: #else
2242: ALE::Obj<PETSC_MESH_TYPE> coarse;
2243: ALE::Obj<PETSC_MESH_TYPE> fine;
2244: Mat P;
2245: PetscErrorCode ierr;
2248: MeshGetMesh(dmFine, fine);
2249: MeshGetMesh(dmCoarse, coarse);
2250: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
2251: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& fineCoordinates = fine->getRealSection("coordinates");
2252: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& vertices = fine->depthStratum(0);
2253: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sCoarse = coarse->getRealSection("default");
2254: const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& sFine = fine->getRealSection("default");
2255: const ALE::Obj<PETSC_MESH_TYPE::order_type>& coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
2256: const ALE::Obj<PETSC_MESH_TYPE::order_type>& fineOrder = fine->getFactory()->getGlobalOrder(fine, "default", sFine);
2258: const int dim = coarse->getDimension();
2259: const int numDof = fine->getDiscretization()->getNumDof(fine->getDimension());
2260: double *v0, *J, *invJ, detJ, *refCoords, *values;
2262: MatCreate(fine->comm(), &P);
2263: MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2264: MatSetFromOptions(P);
2265: MatSeqAIJSetPreallocation(P, numDof, PETSC_NULL);
2266: MatMPIAIJSetPreallocation(P, numDof, PETSC_NULL, numDof, PETSC_NULL);
2267: PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
2268: bool hasprolong;
2269: if (fine->hasLabel("prolongation")) {
2270: hasprolong = true;
2271: } else {
2272: hasprolong = false;
2273: PetscPrintf(fine->comm(), "WARNING: Point Location Label Does Not Exist");
2274: }
2275: PETSC_MESH_TYPE::label_sequence::iterator v_iter_end = vertices->end();
2276: PETSC_MESH_TYPE::real_section_type::value_type *coords = new PETSC_MESH_TYPE::real_section_type::value_type[dim];
2278: for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != v_iter_end; ++v_iter) {
2279: //const PETSC_MESH_TYPE::real_section_type::value_type *coords = fineCoordinates->restrictPoint(*v_iter);
2280: PetscMemcpy(coords, fineCoordinates->restrictPoint(*v_iter), dim*sizeof(double));
2281: PETSC_MESH_TYPE::point_type coarseCell;
2282: PETSC_MESH_TYPE::point_type cellguess = -1;
2283: if (hasprolong) {
2284: cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
2285: coarseCell = coarse->locatePoint(coords, cellguess);
2286: } else {
2287: coarseCell = coarse->locatePoint(coords);
2288: }
2289: // coarseCell = coarse->locatePoint(coords);
2290: if (coarseCell == -1) {
2291: // do NO CORRECTION!
2292: } else {
2293: coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
2294: for(int d = 0; d < dim; ++d) {
2295: refCoords[d] = 0.0;
2296: for(int e = 0; e < dim; ++e) {
2297: refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
2298: }
2299: refCoords[d] -= 1.0;
2300: }
2301: values[0] = -(refCoords[0] + refCoords[1])/2.0;
2302: values[1] = 0.5*(refCoords[0] + 1.0);
2303: values[2] = 0.5*(refCoords[1] + 1.0);
2304: // PetscPrintf(fine->comm(), "%f, %f, %f\n", values[0], values[1], values[2]);
2305: updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
2306: }
2307: }
2308: PetscFree5(v0,J,invJ,refCoords,values);
2309: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2310: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2311: delete [] coords;
2312: *interpolation = P;
2313: return(0);
2314: #endif
2315: }
2319: /*@C
2320: MeshHasSectionReal - Determines whether this mesh has a SectionReal with the given name.
2322: Not Collective
2324: Input Parameters:
2325: + mesh - The Mesh object
2326: - name - The section name
2328: Output Parameter:
2329: . flag - True if the SectionReal is present in the Mesh
2331: Level: intermediate
2333: .keywords: mesh, elements
2334: .seealso: MeshCreate()
2335: @*/
2336: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
2337: {
2338: ALE::Obj<PETSC_MESH_TYPE> m;
2339: PetscErrorCode ierr;
2342: MeshGetMesh(mesh, m);
2343: *flag = (PetscTruth) m->hasRealSection(std::string(name));
2344: return(0);
2345: }
2349: /*@C
2350: MeshGetSectionReal - Returns a SectionReal of the given name from the Mesh.
2352: Collective on Mesh
2354: Input Parameters:
2355: + mesh - The Mesh object
2356: - name - The section name
2358: Output Parameter:
2359: . section - The SectionReal
2361: Note: The section is a new object, and must be destroyed by the user
2363: Level: intermediate
2365: .keywords: mesh, elements
2366: .seealso: MeshCreate()
2367: @*/
2368: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
2369: {
2370: ALE::Obj<PETSC_MESH_TYPE> m;
2371: bool has;
2372: PetscErrorCode ierr;
2375: MeshGetMesh(mesh, m);
2376: SectionRealCreate(m->comm(), section);
2377: PetscObjectSetName((PetscObject) *section, name);
2378: has = m->hasRealSection(std::string(name));
2379: SectionRealSetSection(*section, m->getRealSection(std::string(name)));
2380: SectionRealSetBundle(*section, m);
2381: #ifdef PETSC_OPT_SIEVE
2382: if (!has) {
2383: m->getRealSection(std::string(name))->setChart(m->getSieve()->getChart());
2384: }
2385: #endif
2386: return(0);
2387: }
2391: /*@C
2392: MeshSetSectionReal - Puts a SectionReal of the given name into the Mesh.
2394: Collective on Mesh
2396: Input Parameters:
2397: + mesh - The Mesh object
2398: - section - The SectionReal
2400: Note: This takes the section name from the PETSc object
2402: Level: intermediate
2404: .keywords: mesh, elements
2405: .seealso: MeshCreate()
2406: @*/
2407: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
2408: {
2409: ALE::Obj<PETSC_MESH_TYPE> m;
2410: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
2411: const char *name;
2412: PetscErrorCode ierr;
2415: MeshGetMesh(mesh, m);
2416: PetscObjectGetName((PetscObject) section, &name);
2417: SectionRealGetSection(section, s);
2418: m->setRealSection(std::string(name), s);
2419: return(0);
2420: }
2424: /*@C
2425: MeshHasSectionInt - Determines whether this mesh has a SectionInt with the given name.
2427: Not Collective
2429: Input Parameters:
2430: + mesh - The Mesh object
2431: - name - The section name
2433: Output Parameter:
2434: . flag - True if the SectionInt is present in the Mesh
2436: Level: intermediate
2438: .keywords: mesh, elements
2439: .seealso: MeshCreate()
2440: @*/
2441: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2442: {
2443: ALE::Obj<PETSC_MESH_TYPE> m;
2444: PetscErrorCode ierr;
2447: MeshGetMesh(mesh, m);
2448: *flag = (PetscTruth) m->hasIntSection(std::string(name));
2449: return(0);
2450: }
2454: /*@C
2455: MeshGetSectionInt - Returns a SectionInt of the given name from the Mesh.
2457: Collective on Mesh
2459: Input Parameters:
2460: + mesh - The Mesh object
2461: - name - The section name
2463: Output Parameter:
2464: . section - The SectionInt
2466: Note: The section is a new object, and must be destroyed by the user
2468: Level: intermediate
2470: .keywords: mesh, elements
2471: .seealso: MeshCreate()
2472: @*/
2473: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2474: {
2475: ALE::Obj<PETSC_MESH_TYPE> m;
2476: bool has;
2477: PetscErrorCode ierr;
2480: MeshGetMesh(mesh, m);
2481: SectionIntCreate(m->comm(), section);
2482: PetscObjectSetName((PetscObject) *section, name);
2483: has = m->hasIntSection(std::string(name));
2484: SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2485: SectionIntSetBundle(*section, m);
2486: #ifdef PETSC_OPT_SIEVE
2487: if (!has) {
2488: m->getIntSection(std::string(name))->setChart(m->getSieve()->getChart());
2489: }
2490: #endif
2491: return(0);
2492: }
2496: /*@C
2497: MeshSetSectionInt - Puts a SectionInt of the given name into the Mesh.
2499: Collective on Mesh
2501: Input Parameters:
2502: + mesh - The Mesh object
2503: - section - The SectionInt
2505: Note: This takes the section name from the PETSc object
2507: Level: intermediate
2509: .keywords: mesh, elements
2510: .seealso: MeshCreate()
2511: @*/
2512: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2513: {
2514: ALE::Obj<PETSC_MESH_TYPE> m;
2515: ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2516: const char *name;
2517: PetscErrorCode ierr;
2520: MeshGetMesh(mesh, m);
2521: PetscObjectGetName((PetscObject) section, &name);
2522: SectionIntGetSection(section, s);
2523: m->setIntSection(std::string(name), s);
2524: return(0);
2525: }
2529: /*@C
2530: SectionGetArray - Returns the array underlying the Section.
2532: Not Collective
2534: Input Parameters:
2535: + mesh - The Mesh object
2536: - name - The section name
2538: Output Parameters:
2539: + numElements - The number of mesh element with values
2540: . fiberDim - The number of values per element
2541: - array - The array
2543: Level: intermediate
2545: .keywords: mesh, elements
2546: .seealso: MeshCreate()
2547: @*/
2548: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2549: {
2550: ALE::Obj<PETSC_MESH_TYPE> m;
2551: PetscErrorCode ierr;
2554: MeshGetMesh(mesh, m);
2555: const Obj<PETSC_MESH_TYPE::real_section_type>& section = m->getRealSection(std::string(name));
2556: if (section->size() == 0) {
2557: *numElements = 0;
2558: *fiberDim = 0;
2559: *array = NULL;
2560: return(0);
2561: }
2562: const PETSC_MESH_TYPE::real_section_type::chart_type& chart = section->getChart();
2563: /* const int depth = m->depth(*chart.begin()); */
2564: /* *numElements = m->depthStratum(depth)->size(); */
2565: /* *fiberDim = section->getFiberDimension(*chart.begin()); */
2566: /* *array = (PetscScalar *) m->restrict(section); */
2567: int fiberDimMin = section->getFiberDimension(*chart.begin());
2568: int numElem = 0;
2570: for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2571: const int fiberDim = section->getFiberDimension(*c_iter);
2573: if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2574: }
2575: for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2576: const int fiberDim = section->getFiberDimension(*c_iter);
2578: numElem += fiberDim/fiberDimMin;
2579: }
2580: *numElements = numElem;
2581: *fiberDim = fiberDimMin;
2582: *array = (PetscScalar *) section->restrictSpace();
2583: return(0);
2584: }
2588: PetscErrorCode WritePyLithVertices(Mesh mesh, PetscViewer viewer)
2589: {
2590: ALE::Obj<PETSC_MESH_TYPE> m;
2593: MeshGetMesh(mesh, m);
2594: return ALE::PyLith::Viewer::writeVertices(m, viewer);
2595: }
2599: PetscErrorCode WritePyLithElements(Mesh mesh, SectionInt material, PetscViewer viewer)
2600: {
2601: ALE::Obj<PETSC_MESH_TYPE> m;
2602: ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2605: MeshGetMesh(mesh, m);
2606: SectionIntGetSection(material, s);
2607: return ALE::PyLith::Viewer::writeElements(m, s, viewer);
2608: }
2612: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2613: {
2614: ALE::Obj<PETSC_MESH_TYPE> m;
2617: MeshGetMesh(mesh, m);
2618: return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2619: }
2623: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2624: {
2625: ALE::Obj<PETSC_MESH_TYPE> m;
2626: ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2629: MeshGetMesh(mesh, m);
2630: SectionIntGetSection(material, s);
2631: return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2632: }
2634: #if 0
2637: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2638: {
2639: ALE::Obj<PETSC_MESH_TYPE> m;
2642: MeshGetMesh(mesh, m);
2643: return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2644: }
2645: #endif
2649: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2650: {
2651: const int end = interval.prefix + interval.index;
2652: for(int i = interval.index; i < end; i++) {
2653: indices[indx++] = i;
2654: }
2655: }
2659: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2660: {
2661: for(int i = 0; i < interval.prefix; i++) {
2662: indices[(*indx)++] = interval.index + i;
2663: }
2664: for(int i = 0; i < -interval.prefix; i++) {
2665: indices[(*indx)++] = -1;
2666: }
2667: }