Actual source code: mesh.c
1: #include "private/meshimpl.h" /*I "petscmesh.h" I*/
2: #include <petscmesh_viewers.hh>
3: #include <petscmesh_formats.hh>
5: /* Logging support */
6: PetscCookie MESH_COOKIE = 0;
7: PetscEvent Mesh_View = 0, Mesh_GetGlobalScatter = 0, Mesh_restrictVector = 0, Mesh_assembleVector = 0,
8: Mesh_assembleVectorComplete = 0, Mesh_assembleMatrix = 0, Mesh_updateOperator = 0;
10: PetscTruth MeshRegisterAllCalled = PETSC_FALSE;
11: PetscFList MeshList;
13: EXTERN PetscErrorCode MeshView_Mesh(Mesh, PetscViewer);
14: EXTERN PetscErrorCode MeshRefine_Mesh(Mesh, MPI_Comm, Mesh *);
15: EXTERN PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh, int, Mesh **);
16: EXTERN PetscErrorCode MeshGetInterpolation_Mesh(Mesh, Mesh, Mat *, Vec *);
17: EXTERN PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh, Mesh, Mat *, Vec *);
19: EXTERN PetscErrorCode updateOperatorCompat(Mat, const ALE::Obj<ALECompat::Mesh::real_section_type>&, const ALE::Obj<ALECompat::Mesh::order_type>&, const ALECompat::Mesh::point_type&, PetscScalar[], InsertMode);
24: /*
25: Private routine to delete internal tag storage when a communicator is freed.
27: This is called by MPI, not by users.
31: we do not use PetscFree() since it is unsafe after PetscFinalize()
32: */
33: PetscMPIInt Mesh_DelTag(MPI_Comm comm,PetscMPIInt keyval,void* attr_val,void* extra_state)
34: {
35: free(attr_val);
36: return(MPI_SUCCESS);
37: }
42: PetscErrorCode MeshFinalize()
43: {
45: ALE::Mesh::NumberingFactory::singleton(0, 0, true);
46: return(0);
47: }
51: PetscErrorCode MeshView_Sieve_Ascii(const ALE::Obj<ALE::Mesh>& mesh, PetscViewer viewer)
52: {
53: PetscViewerFormat format;
54: PetscErrorCode ierr;
57: PetscViewerGetFormat(viewer, &format);
58: if (format == PETSC_VIEWER_ASCII_VTK) {
59: VTKViewer::writeHeader(viewer);
60: VTKViewer::writeVertices(mesh, viewer);
61: VTKViewer::writeElements(mesh, viewer);
62: } else if (format == PETSC_VIEWER_ASCII_PYLITH) {
63: char *filename;
64: char connectFilename[2048];
65: char coordFilename[2048];
67: PetscViewerFileGetName(viewer, &filename);
68: PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
69: PetscStrcpy(connectFilename, filename);
70: PetscStrcat(connectFilename, ".connect");
71: PetscViewerFileSetName(viewer, connectFilename);
72: ALE::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
73: PetscStrcpy(coordFilename, filename);
74: PetscStrcat(coordFilename, ".coord");
75: PetscViewerFileSetName(viewer, coordFilename);
76: ALE::PyLith::Viewer::writeVertices(mesh, viewer);
77: PetscViewerFileSetMode(viewer, FILE_MODE_READ);
78: PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
79: if (PetscExceptionValue(ierr)) {
80: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
81: } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
82: 0;
83: }
84:
85: } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
86: PetscViewer connectViewer, coordViewer;
87: char *filename;
88: char localFilename[2048];
89: int rank = mesh->commRank();
91: PetscViewerFileGetName(viewer, &filename);
93: sprintf(localFilename, "%s.%d.connect", filename, rank);
94: PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
95: PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
96: PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
97: PetscViewerFileSetName(connectViewer, localFilename);
98: ALE::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
99: PetscViewerDestroy(connectViewer);
101: sprintf(localFilename, "%s.%d.coord", filename, rank);
102: PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
103: PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
104: PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
105: PetscViewerFileSetName(coordViewer, localFilename);
106: ALE::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
107: PetscViewerDestroy(coordViewer);
108: } else if (format == PETSC_VIEWER_ASCII_PCICE) {
109: char *filename;
110: char coordFilename[2048];
111: PetscTruth isConnect;
112: size_t len;
114: PetscViewerFileGetName(viewer, &filename);
115: PetscStrlen(filename, &len);
116: PetscStrcmp(&(filename[len-5]), ".lcon", &isConnect);
117: if (!isConnect) {
118: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid element connectivity filename: %s", filename);
119: }
120: ALE::PCICE::Viewer::writeElements(mesh, viewer);
121: PetscStrncpy(coordFilename, filename, len-5);
122: coordFilename[len-5] = '\0';
123: PetscStrcat(coordFilename, ".nodes");
124: PetscViewerFileSetName(viewer, coordFilename);
125: ALE::PCICE::Viewer::writeVertices(mesh, viewer);
126: } else {
127: int dim = mesh->getDimension();
129: PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
130: for(int d = 0; d <= dim; d++) {
131: // FIX: Need to globalize
132: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->depthStratum(d)->size(), d);
133: }
134: }
135: PetscViewerFlush(viewer);
136: return(0);
137: }
141: PetscErrorCode MeshCompatView_Sieve_Ascii(const ALE::Obj<ALECompat::Mesh>& mesh, PetscViewer viewer)
142: {
143: PetscViewerFormat format;
144: PetscErrorCode ierr;
147: PetscViewerGetFormat(viewer, &format);
148: if (format == PETSC_VIEWER_ASCII_PYLITH) {
149: char *filename;
150: char connectFilename[2048];
151: char coordFilename[2048];
153: PetscViewerFileGetName(viewer, &filename);
154: PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
155: PetscStrcpy(connectFilename, filename);
156: PetscStrcat(connectFilename, ".connect");
157: PetscViewerFileSetName(viewer, connectFilename);
158: ALECompat::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
159: PetscStrcpy(coordFilename, filename);
160: PetscStrcat(coordFilename, ".coord");
161: PetscViewerFileSetName(viewer, coordFilename);
162: ALECompat::PyLith::Viewer::writeVertices(mesh, viewer);
163: PetscViewerFileSetMode(viewer, FILE_MODE_READ);
164: PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
165: if (PetscExceptionValue(ierr)) {
166: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
167: } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
168: 0;
169: }
170:
171: } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
172: PetscViewer connectViewer, coordViewer;
173: char *filename;
174: char localFilename[2048];
175: int rank = mesh->commRank();
177: PetscViewerFileGetName(viewer, &filename);
179: sprintf(localFilename, "%s.%d.connect", filename, rank);
180: PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
181: PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
182: PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
183: PetscViewerFileSetName(connectViewer, localFilename);
184: ALECompat::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
185: PetscViewerDestroy(connectViewer);
187: sprintf(localFilename, "%s.%d.coord", filename, rank);
188: PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
189: PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
190: PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
191: PetscViewerFileSetName(coordViewer, localFilename);
192: ALECompat::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
193: PetscViewerDestroy(coordViewer);
195: if (mesh->hasPairSection("split")) {
196: PetscViewer splitViewer;
198: sprintf(localFilename, "%s.%d.split", filename, rank);
199: PetscViewerCreate(PETSC_COMM_SELF, &splitViewer);
200: PetscViewerSetType(splitViewer, PETSC_VIEWER_ASCII);
201: PetscViewerSetFormat(splitViewer, PETSC_VIEWER_ASCII_PYLITH);
202: PetscViewerFileSetName(splitViewer, localFilename);
203: ALECompat::PyLith::Viewer::writeSplitLocal(mesh, mesh->getPairSection("split"), splitViewer);
204: PetscViewerDestroy(splitViewer);
205: }
207: if (mesh->hasRealSection("traction")) {
208: PetscViewer tractionViewer;
210: sprintf(localFilename, "%s.%d.traction", filename, rank);
211: PetscViewerCreate(PETSC_COMM_SELF, &tractionViewer);
212: PetscViewerSetType(tractionViewer, PETSC_VIEWER_ASCII);
213: PetscViewerSetFormat(tractionViewer, PETSC_VIEWER_ASCII_PYLITH);
214: PetscViewerFileSetName(tractionViewer, localFilename);
215: ALECompat::PyLith::Viewer::writeTractionsLocal(mesh, mesh->getRealSection("traction"), tractionViewer);
216: PetscViewerDestroy(tractionViewer);
217: }
218: } else {
219: int dim = mesh->getDimension();
221: PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
222: for(int d = 0; d <= dim; d++) {
223: // FIX: Need to globalize
224: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->getTopology()->depthStratum(0, d)->size(), d);
225: }
226: }
227: PetscViewerFlush(viewer);
228: return(0);
229: }
233: PetscErrorCode MeshView_Sieve(const ALE::Obj<ALE::Mesh>& mesh, PetscViewer viewer)
234: {
235: PetscTruth iascii, isbinary, isdraw;
239: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
240: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
241: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);
243: if (iascii){
244: MeshView_Sieve_Ascii(mesh, viewer);
245: } else if (isbinary) {
246: SETERRQ(PETSC_ERR_SUP, "Binary viewer not implemented for Mesh");
247: } else if (isdraw){
248: SETERRQ(PETSC_ERR_SUP, "Draw viewer not implemented for Mesh");
249: } else {
250: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
251: }
252: return(0);
253: }
257: PetscErrorCode MeshView_Mesh(Mesh mesh, PetscViewer viewer)
258: {
262: if (!mesh->mcompat.isNull()) {
263: MeshCompatView_Sieve_Ascii(mesh->mcompat, viewer);
264: } else {
265: MeshView_Sieve(mesh->m, viewer);
266: }
267: return(0);
268: }
272: /*@C
273: MeshView - Views a Mesh object.
275: Collective on Mesh
277: Input Parameters:
278: + mesh - the mesh
279: - viewer - an optional visualization context
281: Notes:
282: The available visualization contexts include
283: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
284: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
285: output where only the first processor opens
286: the file. All other processors send their
287: data to the first processor to print.
289: You can change the format the mesh is printed using the
290: option PetscViewerSetFormat().
292: The user can open alternative visualization contexts with
293: + PetscViewerASCIIOpen() - Outputs mesh to a specified file
294: . PetscViewerBinaryOpen() - Outputs mesh in binary to a
295: specified file; corresponding input uses MeshLoad()
296: . PetscViewerDrawOpen() - Outputs mesh to an X window display
298: The user can call PetscViewerSetFormat() to specify the output
299: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
300: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
301: + PETSC_VIEWER_ASCII_DEFAULT - default, prints mesh information
302: - PETSC_VIEWER_ASCII_VTK - outputs a VTK file describing the mesh
304: Level: beginner
306: Concepts: mesh^printing
307: Concepts: mesh^saving to disk
309: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
310: MeshLoad(), PetscViewerCreate()
311: @*/
312: PetscErrorCode MeshView(Mesh mesh, PetscViewer viewer)
313: {
319: if (!viewer) {
320: PetscViewerASCIIGetStdout(((PetscObject)mesh)->comm,&viewer);
321: }
326: (*mesh->ops->view)(mesh, viewer);
328: return(0);
329: }
333: /*@C
334: MeshLoad - Create a mesh topology from the saved data in a viewer.
336: Collective on Viewer
338: Input Parameter:
339: . viewer - The viewer containing the data
341: Output Parameters:
342: . mesh - the mesh object
344: Level: advanced
346: .seealso MeshView()
348: @*/
349: PetscErrorCode MeshLoad(PetscViewer viewer, Mesh *mesh)
350: {
351: SETERRQ(PETSC_ERR_SUP, "");
352: }
356: /*@C
357: MeshGetMesh - Gets the internal mesh object
359: Not collective
361: Input Parameter:
362: . mesh - the mesh object
364: Output Parameter:
365: . m - the internal mesh object
366:
367: Level: advanced
369: .seealso MeshCreate(), MeshSetMesh()
371: @*/
372: PetscErrorCode MeshGetMesh(Mesh mesh, ALE::Obj<ALE::Mesh>& m)
373: {
376: m = mesh->m;
377: return(0);
378: }
382: /*@C
383: MeshSetMesh - Sets the internal mesh object
385: Not collective
387: Input Parameters:
388: + mesh - the mesh object
389: - m - the internal mesh object
390:
391: Level: advanced
393: .seealso MeshCreate(), MeshGetMesh()
395: @*/
396: PetscErrorCode MeshSetMesh(Mesh mesh, const ALE::Obj<ALE::Mesh>& m)
397: {
400: mesh->m = m;
401: if (mesh->globalScatter) {
404: VecScatterDestroy(mesh->globalScatter);
405: mesh->globalScatter = PETSC_NULL;
406: }
407: return(0);
408: }
412: PetscErrorCode MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
413: {
414: ALE::Obj<ALE::Mesh> m;
415: ALE::Obj<ALE::Mesh::real_section_type> s;
419: MeshGetMesh(mesh, m);
420: SectionRealGetSection(section, s);
421: MeshCreateMatrix(m, s, mtype, J);
422: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
423: return(0);
424: }
428: PetscErrorCode MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
429: {
430: SectionReal section;
434: MeshGetVertexSectionReal(mesh, 1, §ion);
435: MeshCreateMatrix(mesh, section, mtype, J);
436: SectionRealDestroy(section);
437: return(0);
438: }
442: /*@C
443: MeshGetMatrix - Creates a matrix with the correct parallel layout required for
444: computing the Jacobian on a function defined using the informatin in Mesh.
446: Collective on Mesh
448: Input Parameter:
449: + mesh - the mesh object
450: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
451: or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).
453: Output Parameters:
454: . J - matrix with the correct nonzero preallocation
455: (obviously without the correct Jacobian values)
457: Level: advanced
459: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
460: do not need to do it yourself.
462: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
464: @*/
465: PetscErrorCode MeshGetMatrix(Mesh mesh, MatType mtype, Mat *J)
466: {
467: ALE::Obj<ALE::Mesh> m;
468: PetscTruth flag;
469: PetscErrorCode ierr;
472: MeshHasSectionReal(mesh, "default", &flag);
473: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
474: MeshGetMesh(mesh, m);
475: MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
476: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
477: return(0);
478: }
482: /*@C
483: MeshCreate - Creates a DM object, used to manage data for an unstructured problem
484: described by a Sieve.
486: Collective on MPI_Comm
488: Input Parameter:
489: . comm - the processors that will share the global vector
491: Output Parameters:
492: . mesh - the mesh object
494: Level: advanced
496: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
498: @*/
499: PetscErrorCode MeshCreate(MPI_Comm comm,Mesh *mesh)
500: {
502: Mesh p;
506: *mesh = PETSC_NULL;
507: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
508: DMInitializePackage(PETSC_NULL);
509: #endif
511: PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
512: p->ops->view = MeshView_Mesh;
513: p->ops->destroy = PETSC_NULL;
514: p->ops->createglobalvector = MeshCreateGlobalVector;
515: p->ops->createlocalvector = MeshCreateLocalVector;
516: p->ops->getcoloring = PETSC_NULL;
517: p->ops->getmatrix = MeshGetMatrix;
518: p->ops->getinterpolation = MeshGetInterpolation_Mesh_New;
519: p->ops->getinjection = PETSC_NULL;
520: p->ops->refine = MeshRefine_Mesh;
521: p->ops->coarsen = PETSC_NULL;
522: p->ops->refinehierarchy = PETSC_NULL;
523: p->ops->coarsenhierarchy = MeshCoarsenHierarchy_Mesh;
525: PetscObjectChangeTypeName((PetscObject) p, "sieve");
527: new(&p->m) ALE::Obj<ALE::Mesh>(PETSC_NULL);
528: p->globalScatter = PETSC_NULL;
529: p->lf = PETSC_NULL;
530: p->lj = PETSC_NULL;
531: new(&p->mcompat) ALE::Obj<ALECompat::Mesh>(PETSC_NULL);
532: p->data = PETSC_NULL;
533: *mesh = p;
534: return(0);
535: }
539: /*@
540: MeshDestroy - Destroys a mesh.
542: Collective on Mesh
544: Input Parameter:
545: . mesh - the mesh object
547: Level: advanced
549: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
550: @*/
551: PetscErrorCode MeshDestroy(Mesh mesh)
552: {
553: PetscErrorCode ierr;
556: if (--((PetscObject)mesh)->refct > 0) return(0);
557: if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
558: mesh->m = PETSC_NULL;
559: PetscHeaderDestroy(mesh);
560: return(0);
561: }
565: /*@C
566: MeshSetType - Sets the Mesh type
568: Collective on Mesh
570: Input Parameters:
571: + mesh - the Mesh context
572: - type - the type
574: Options Database Key:
575: . -mesh_type <method> - Sets the type; use -help for a list
576: of available types (for instance, cartesian or sieve)
578: Notes:
579: See "petsc/include/petscmesh.h" for available types (for instance,
580: MESHCARTESIAN or MESHSIEVE).
582: Level: intermediate
584: .keywords: Mesh, set, typr
585: .seealso: MeshGetType(), MeshType
586: @*/
587: PetscErrorCode MeshSetType(Mesh mesh, MeshType type)
588: {
589: PetscErrorCode ierr,(*r)(Mesh);
590: PetscTruth match;
596: PetscTypeCompare((PetscObject)mesh,type,&match);
597: if (match) return(0);
599: PetscFListFind(MeshList,((PetscObject)mesh)->comm,type,(void (**)(void)) &r);
600: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
601: /* Destroy the previous private Mesh context */
602: if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
603: /* Reinitialize function pointers in MeshOps structure */
604: PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
605: /* Call the MeshCreate_XXX routine for this particular mesh */
606: (*r)(mesh);
607: PetscObjectChangeTypeName((PetscObject) mesh, type);
608: return(0);
609: }
613: /*@C
614: MeshGetType - Gets the Mesh type as a string from the Mesh object.
616: Not Collective
618: Input Parameter:
619: . mesh - Mesh context
621: Output Parameter:
622: . name - name of Mesh type
624: Level: intermediate
626: .keywords: Mesh, get, type
627: .seealso: MeshSetType()
628: @*/
629: PetscErrorCode MeshGetType(Mesh mesh,MeshType *type)
630: {
634: *type = ((PetscObject)mesh)->type_name;
635: return(0);
636: }
640: /*@C
641: MeshRegister - See MeshRegisterDynamic()
643: Level: advanced
644: @*/
645: PetscErrorCode MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
646: {
648: char fullname[PETSC_MAX_PATH_LEN];
651: PetscFListConcat(path,name,fullname);
652: PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
653: return(0);
654: }
657: EXTERN PetscErrorCode MeshCreate_Cartesian(Mesh);
662: /*@C
663: MeshRegisterAll - Registers all of the Mesh types in the Mesh package.
665: Not Collective
667: Level: advanced
669: .keywords: Mesh, register, all
670: .seealso: MeshRegisterDestroy()
671: @*/
672: PetscErrorCode MeshRegisterAll(const char path[])
673: {
677: MeshRegisterAllCalled = PETSC_TRUE;
679: MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
680: return(0);
681: }
685: /*@
686: MeshRegisterDestroy - Frees the list of Mesh types that were
687: registered by MeshRegister().
689: Not Collective
691: Level: advanced
693: .keywords: Mesh, register, destroy
694: .seealso: MeshRegister(), MeshRegisterAll()
695: @*/
696: PetscErrorCode MeshRegisterDestroy(void)
697: {
701: PetscFListDestroy(&MeshList);
702: MeshRegisterAllCalled = PETSC_FALSE;
703: return(0);
704: }
708: /*@C
709: MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into
710: by the mesh.
712: Collective on Mesh
714: Input Parameter:
715: . mesh - the mesh object
717: Output Parameters:
718: . gvec - the global vector
720: Level: advanced
722: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
724: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
726: @*/
727: PetscErrorCode MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
728: {
729: ALE::Obj<ALE::Mesh> m;
730: PetscTruth flag;
734: MeshHasSectionReal(mesh, "default", &flag);
735: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
736: MeshGetMesh(mesh, m);
737: const ALE::Obj<ALE::Mesh::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));
739: VecCreate(m->comm(), gvec);
740: VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
741: VecSetFromOptions(*gvec);
742: return(0);
743: }
747: /*@C
748: MeshCreateLocalVector - Creates a vector of the correct size for local computation.
750: Collective on Mesh
752: Input Parameter:
753: . mesh - the mesh object
755: Output Parameters:
756: . lvec - the local vector
758: Level: advanced
760: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
762: .seealso MeshDestroy(), MeshCreate(), MeshCreateGlobalVector()
764: @*/
765: PetscErrorCode MeshCreateLocalVector(Mesh mesh, Vec *lvec)
766: {
767: ALE::Obj<ALE::Mesh> m;
768: PetscTruth flag;
772: MeshHasSectionReal(mesh, "default", &flag);
773: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
774: MeshGetMesh(mesh, m);
775: const int size = m->getRealSection("default")->getStorageSize();
777: VecCreate(PETSC_COMM_SELF, lvec);
778: VecSetSizes(*lvec, size, size);
779: VecSetFromOptions(*lvec);
780: return(0);
781: }
785: /*@C
786: MeshGetGlobalIndices - Gets the global indices for all the local entries
788: Collective on Mesh
790: Input Parameter:
791: . mesh - the mesh object
793: Output Parameters:
794: . idx - the individual indices for each packed vector/array
795:
796: Level: advanced
798: Notes:
799: The idx parameters should be freed by the calling routine with PetscFree()
801: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
803: @*/
804: PetscErrorCode MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
805: {
806: SETERRQ(PETSC_ERR_SUP, "");
807: }
811: PetscErrorCode MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
812: {
813: ALE::Obj<ALE::Mesh> m;
814: ALE::Obj<ALE::Mesh::real_section_type> s;
818: MeshGetMesh(mesh, m);
819: SectionRealGetSection(section, s);
820: MeshCreateGlobalScatter(m, s, scatter);
821: return(0);
822: }
826: PetscErrorCode MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
827: {
833: if (!mesh->globalScatter) {
834: SectionReal section;
836: MeshGetSectionReal(mesh, "default", §ion);
837: MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
838: SectionRealDestroy(section);
839: }
840: *scatter = mesh->globalScatter;
841: return(0);
842: }
846: PetscErrorCode MeshGetLocalFunction(Mesh mesh, PetscErrorCode (**lf)(Mesh, SectionReal, SectionReal, void *))
847: {
850: if (lf) *lf = mesh->lf;
851: return(0);
852: }
856: PetscErrorCode MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
857: {
860: mesh->lf = lf;
861: return(0);
862: }
866: PetscErrorCode MeshGetLocalJacobian(Mesh mesh, PetscErrorCode (**lj)(Mesh, SectionReal, Mat, void *))
867: {
870: if (lj) *lj = mesh->lj;
871: return(0);
872: }
876: PetscErrorCode MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
877: {
880: mesh->lj = lj;
881: return(0);
882: }
886: PetscErrorCode MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
887: {
894: if (mesh->lf) {
895: (*mesh->lf)(mesh, X, F, ctx);
896: }
897: return(0);
898: }
902: PetscErrorCode MeshFormJacobian(Mesh mesh, SectionReal X, Mat J, void *ctx)
903: {
910: if (mesh->lj) {
911: (*mesh->lj)(mesh, X, J, ctx);
912: }
913: return(0);
914: }
918: // Here we assume:
919: // - Assumes 3D and tetrahedron
920: // - The section takes values on vertices and is P1
921: // - Points have the same dimension as the mesh
922: // - All values have the same dimension
923: PetscErrorCode MeshInterpolatePoints(Mesh mesh, SectionReal section, int numPoints, double *points, double **values)
924: {
925: Obj<ALE::Mesh> m;
926: Obj<ALE::Mesh::real_section_type> s;
927: double *v0, *J, *invJ, detJ;
931: MeshGetMesh(mesh, m);
932: SectionRealGetSection(section, s);
933: const Obj<ALE::Mesh::real_section_type>& coordinates = m->getRealSection("coordinates");
934: int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
935: int dim = s->getFiberDimension(*m->depthStratum(0)->begin());
937: PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
938: PetscMalloc(numPoints*dim * sizeof(double), &values);
939: for(int p = 0; p < numPoints; p++) {
940: double *point = &points[p*embedDim];
941:
942: ALE::Mesh::point_type e = m->locatePoint(point);
943: const ALE::Mesh::real_section_type::value_type *coeff = s->restrictPoint(e);
945: m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
946: double xi = (invJ[0*embedDim+0]*(point[0] - v0[0]) + invJ[0*embedDim+1]*(point[1] - v0[1]) + invJ[0*embedDim+2]*(point[2] - v0[2]))*0.5;
947: double eta = (invJ[1*embedDim+0]*(point[0] - v0[0]) + invJ[1*embedDim+1]*(point[1] - v0[1]) + invJ[1*embedDim+2]*(point[2] - v0[2]))*0.5;
948: double zeta = (invJ[2*embedDim+0]*(point[0] - v0[0]) + invJ[2*embedDim+1]*(point[1] - v0[1]) + invJ[2*embedDim+2]*(point[2] - v0[2]))*0.5;
950: for(int d = 0; d < dim; d++) {
951: (*values)[p*dim+d] = coeff[0*dim+d]*(1 - xi - eta - zeta) + coeff[1*dim+d]*xi + coeff[2*dim+d]*eta + coeff[3*dim+d]*zeta;
952: }
953: }
954: PetscFree3(v0, J, invJ);
955: return(0);
956: }
960: /*@
961: MeshGetMaximumDegree - Return the maximum degree of any mesh vertex
963: Collective on mesh
965: Input Parameter:
966: . mesh - The Mesh
968: Output Parameter:
969: . maxDegree - The maximum number of edges at any vertex
971: Level: beginner
973: .seealso: MeshCreate()
974: @*/
975: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
976: {
977: Obj<ALE::Mesh> m;
981: MeshGetMesh(mesh, m);
982: const ALE::Obj<ALE::Mesh::label_sequence>& vertices = m->depthStratum(0);
983: const ALE::Obj<ALE::Mesh::sieve_type>& sieve = m->getSieve();
984: PetscInt maxDeg = -1;
986: for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
987: maxDeg = PetscMax(maxDeg, (PetscInt) sieve->support(*v_iter)->size());
988: }
989: *maxDegree = maxDeg;
990: return(0);
991: }
993: EXTERN PetscErrorCode assembleFullField(VecScatter, Vec, Vec, InsertMode);
997: /*@C
998: restrictVector - Insert values from a global vector into a local ghosted vector
1000: Collective on g
1002: Input Parameters:
1003: + g - The global vector
1004: . l - The local vector
1005: - mode - either ADD_VALUES or INSERT_VALUES, where
1006: ADD_VALUES adds values to any existing entries, and
1007: INSERT_VALUES replaces existing entries with new values
1009: Level: beginner
1011: .seealso: MatSetOption()
1012: @*/
1013: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1014: {
1015: VecScatter injection;
1020: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1021: if (injection) {
1022: VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
1023: VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
1024: } else {
1025: if (mode == INSERT_VALUES) {
1026: VecCopy(g, l);
1027: } else {
1028: VecAXPY(l, 1.0, g);
1029: }
1030: }
1032: return(0);
1033: }
1037: /*@C
1038: assembleVectorComplete - Insert values from a local ghosted vector into a global vector
1040: Collective on g
1042: Input Parameters:
1043: + g - The global vector
1044: . l - The local vector
1045: - mode - either ADD_VALUES or INSERT_VALUES, where
1046: ADD_VALUES adds values to any existing entries, and
1047: INSERT_VALUES replaces existing entries with new values
1049: Level: beginner
1051: .seealso: MatSetOption()
1052: @*/
1053: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1054: {
1055: VecScatter injection;
1060: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1061: if (injection) {
1062: VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1063: VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1064: } else {
1065: if (mode == INSERT_VALUES) {
1066: VecCopy(l, g);
1067: } else {
1068: VecAXPY(g, 1.0, l);
1069: }
1070: }
1072: return(0);
1073: }
1077: /*@C
1078: assembleVector - Insert values into a vector
1080: Collective on A
1082: Input Parameters:
1083: + b - the vector
1084: . e - The element number
1085: . v - The values
1086: - mode - either ADD_VALUES or INSERT_VALUES, where
1087: ADD_VALUES adds values to any existing entries, and
1088: INSERT_VALUES replaces existing entries with new values
1090: Level: beginner
1092: .seealso: VecSetOption()
1093: @*/
1094: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1095: {
1096: Mesh mesh;
1097: ALE::Obj<ALE::Mesh> m;
1098: PetscInt firstElement;
1099: PetscErrorCode ierr;
1103: PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1104: MeshGetMesh(mesh, m);
1105: //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1106: firstElement = 0;
1107: // Must relate b to field
1108: if (mode == INSERT_VALUES) {
1109: m->update(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1110: } else {
1111: m->updateAdd(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1112: }
1114: return(0);
1115: }
1119: PetscErrorCode updateOperator(Mat A, const ALE::Obj<ALE::Mesh>& m, const ALE::Obj<ALE::Mesh::real_section_type>& section, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, const ALE::Mesh::point_type& e, PetscScalar array[], InsertMode mode)
1120: {
1124: const ALE::Mesh::indices_type indicesBlock = m->getIndices(section, e, globalOrder);
1125: const PetscInt *indices = indicesBlock.first;
1126: const int& numIndices = indicesBlock.second;
1129: if (section->debug()) {
1130: printf("[%d]mat for element %d\n", section->commRank(), e);
1131: for(int i = 0; i < numIndices; i++) {
1132: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1133: }
1134: for(int i = 0; i < numIndices; i++) {
1135: printf("[%d]", section->commRank());
1136: for(int j = 0; j < numIndices; j++) {
1137: printf(" %g", array[i*numIndices+j]);
1138: }
1139: printf("\n");
1140: }
1141: }
1142: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1143: if (ierr) {
1144: printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
1145: for(int i = 0; i < numIndices; i++) {
1146: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1147: }
1148:
1149: }
1151: return(0);
1152: }
1156: PetscErrorCode updateOperator(Mat A, const ALE::Obj<ALE::Mesh>& m, const ALE::Obj<ALE::Mesh::real_section_type>& section, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, int tag, int p, PetscScalar array[], InsertMode mode)
1157: {
1158: const int *offsets, *indices;
1162: section->getCustomRestrictAtlas(tag, &offsets, &indices);
1163: const int& numIndices = offsets[p+1] - offsets[p];
1166: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1167: if (ierr) {
1168: printf("[%d]ERROR in updateOperator: tag %d point num %d\n", section->commRank(), tag, p);
1169: for(int i = 0; i < numIndices; i++) {
1170: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1171: }
1172:
1173: }
1175: return(0);
1176: }
1180: PetscErrorCode updateOperatorGeneral(Mat A, const ALE::Obj<ALE::Mesh>& rowM, const ALE::Obj<ALE::Mesh::real_section_type>& rowSection, const ALE::Obj<ALE::Mesh::order_type>& rowGlobalOrder, const ALE::Mesh::point_type& rowE, const ALE::Obj<ALE::Mesh>& colM, const ALE::Obj<ALE::Mesh::real_section_type>& colSection, const ALE::Obj<ALE::Mesh::order_type>& colGlobalOrder, const ALE::Mesh::point_type& colE, PetscScalar array[], InsertMode mode)
1181: {
1185: const ALE::Mesh::indices_type rowIndicesBlock = rowM->getIndices(rowSection, rowE, rowGlobalOrder);
1187: const PetscInt *tmpIndices = rowIndicesBlock.first;
1188: const int numRowIndices = rowIndicesBlock.second;
1189: PetscInt *rowIndices = new PetscInt[numRowIndices];
1190: PetscMemcpy(rowIndices, tmpIndices, numRowIndices*sizeof(PetscInt));
1192: const ALE::Mesh::indices_type colIndicesBlock = colM->getIndices(colSection, colE, colGlobalOrder);
1194: const PetscInt *colIndices = colIndicesBlock.first;
1195: const int numColIndices = colIndicesBlock.second;
1198: if (rowSection->debug()) {
1199: printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1200: for(int i = 0; i < numRowIndices; i++) {
1201: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1202: }
1203: }
1204: if (colSection->debug()) {
1205: for(int i = 0; i < numColIndices; i++) {
1206: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1207: }
1208: for(int i = 0; i < numRowIndices; i++) {
1209: printf("[%d]", rowSection->commRank());
1210: for(int j = 0; j < numColIndices; j++) {
1211: printf(" %g", array[i*numColIndices+j]);
1212: }
1213: printf("\n");
1214: }
1215: }
1216: MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1217: if (ierr) {
1218: printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1219: for(int i = 0; i < numRowIndices; i++) {
1220: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1221: }
1222: for(int i = 0; i < numColIndices; i++) {
1223: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1224: }
1225:
1226: }
1228: delete [] rowIndices;
1229: return(0);
1230: }
1234: /*@C
1235: assembleMatrix - Insert values into a matrix
1237: Collective on A
1239: Input Parameters:
1240: + A - the matrix
1241: . e - The element number
1242: . v - The values
1243: - mode - either ADD_VALUES or INSERT_VALUES, where
1244: ADD_VALUES adds values to any existing entries, and
1245: INSERT_VALUES replaces existing entries with new values
1247: Level: beginner
1249: .seealso: MatSetOption()
1250: @*/
1251: PetscErrorCode assembleMatrix(Mat A, PetscInt e, PetscScalar v[], InsertMode mode)
1252: {
1253: Mesh mesh;
1258: PetscObjectQuery((PetscObject) A, "mesh", (PetscObject *) &mesh);
1259: try {
1260: if (!mesh->mcompat.isNull()) {
1261: Obj<ALECompat::Mesh> m;
1263: MeshCompatGetMesh(mesh, m);
1264: const ALE::Obj<ALECompat::Mesh::topology_type>& topology = m->getTopology();
1265: const ALE::Obj<ALECompat::Mesh::numbering_type>& cNumbering = m->getFactory()->getLocalNumbering(topology, 0, topology->depth());
1266: const ALE::Obj<ALECompat::Mesh::real_section_type>& s = m->getRealSection("default");
1267: const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(topology, 0, "default", s->getAtlas());
1269: if (m->debug()) {
1270: std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1271: }
1272: updateOperatorCompat(A, s, globalOrder, cNumbering->getPoint(e), v, mode);
1273: } else {
1274: Obj<ALE::Mesh> m;
1276: MeshGetMesh(mesh, m);
1277: const ALE::Obj<ALE::Mesh::numbering_type>& cNumbering = m->getFactory()->getLocalNumbering(m, m->depth());
1278: const ALE::Obj<ALE::Mesh::real_section_type>& s = m->getRealSection("default");
1279: const ALE::Obj<ALE::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, "default", s);
1281: if (m->debug()) {
1282: std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1283: }
1284: updateOperator(A, m, s, globalOrder, cNumbering->getPoint(e), v, mode);
1285: }
1286: } catch (ALE::Exception e) {
1287: std::cout << e.msg() << std::endl;
1288: }
1290: return(0);
1291: }
1295: PetscErrorCode preallocateMatrix(const ALE::Obj<ALE::Mesh>& mesh, const int bs, const ALE::Obj<ALE::Mesh::real_section_type::atlas_type>& atlas, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, Mat A)
1296: {
1297: return preallocateOperator(mesh, bs, atlas, globalOrder, A);
1298: }
1300: /******************************** C Wrappers **********************************/
1304: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1305: {
1306: return VTKViewer::writeHeader(viewer);
1307: }
1311: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1312: {
1313: ALE::Obj<ALE::Mesh> m;
1316: MeshGetMesh(mesh, m);
1317: return VTKViewer::writeVertices(m, viewer);
1318: }
1322: PetscErrorCode WriteVTKElements(Mesh mesh, PetscViewer viewer)
1323: {
1324: ALE::Obj<ALE::Mesh> m;
1327: MeshGetMesh(mesh, m);
1328: return VTKViewer::writeElements(m, viewer);
1329: }
1333: PetscErrorCode WritePCICEVertices(Mesh mesh, PetscViewer viewer)
1334: {
1335: ALE::Obj<ALE::Mesh> m;
1338: MeshGetMesh(mesh, m);
1339: return ALE::PCICE::Viewer::writeVertices(m, viewer);
1340: }
1344: PetscErrorCode WritePCICEElements(Mesh mesh, PetscViewer viewer)
1345: {
1346: ALE::Obj<ALE::Mesh> m;
1349: MeshGetMesh(mesh, m);
1350: return ALE::PCICE::Viewer::writeElements(m, viewer);
1351: }
1355: PetscErrorCode WritePCICERestart(Mesh mesh, PetscViewer viewer)
1356: {
1357: ALE::Obj<ALE::Mesh> m;
1360: MeshGetMesh(mesh, m);
1361: return ALE::PCICE::Viewer::writeRestart(m, viewer);
1362: }
1366: /*@C
1367: MeshCreatePFLOTRAN - Create a Mesh from PFLOTRAN HDF5 files.
1369: Not Collective
1371: Input Parameters:
1372: + dim - The topological mesh dimension
1373: . hdf5Filename - The HDF5 file containing the vertices for each element and vertex coordinates
1374: . interpolate - The flag for construction of intermediate elements
1376: Output Parameter:
1377: . mesh - The Mesh object
1379: Level: beginner
1381: .keywords: mesh, PFLOTRAN
1382: .seealso: MeshCreate()
1383: @*/
1384: PetscErrorCode MeshCreatePFLOTRAN(MPI_Comm comm, const int dim, const char hdf5Filename[], PetscTruth interpolate, Mesh *mesh)
1385: {
1386: ALE::Obj<ALE::Mesh> m;
1387: PetscInt debug = 0;
1388: PetscTruth flag;
1389: PetscErrorCode ierr;
1392: MeshCreate(comm, mesh);
1393: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1394: try {
1395: m = ALE::PFLOTRAN::Builder::readMesh(comm, dim, std::string(hdf5Filename), true, interpolate, debug);
1396: if (debug) {m->view("Mesh");}
1397: } catch(ALE::Exception e) {
1398: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1399: }
1400: #if 0
1401: if (bcFilename) {
1402: ALE::PFLOTRAN::Builder::readBoundary(m, std::string(bcFilename));
1403: }
1404: #endif
1405: MeshSetMesh(*mesh, m);
1406: return(0);
1407: }
1411: /*@C
1412: MeshCreatePCICE - Create a Mesh from PCICE files.
1414: Not Collective
1416: Input Parameters:
1417: + dim - The topological mesh dimension
1418: . coordFilename - The file containing vertex coordinates
1419: . adjFilename - The file containing the vertices for each element
1420: . interpolate - The flag for construction of intermediate elements
1421: . bcFilename - The file containing the boundary topology and conditions
1422: . numBdFaces - The number of boundary faces (or edges)
1423: - numBdVertices - The number of boundary vertices
1425: Output Parameter:
1426: . mesh - The Mesh object
1428: Level: beginner
1430: .keywords: mesh, PCICE
1431: .seealso: MeshCreate()
1432: @*/
1433: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], Mesh *mesh)
1434: {
1435: ALE::Obj<ALE::Mesh> m;
1436: PetscInt debug = 0;
1437: PetscTruth flag;
1438: PetscErrorCode ierr;
1441: MeshCreate(comm, mesh);
1442: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1443: try {
1444: m = ALE::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1445: if (debug) {m->view("Mesh");}
1446: } catch(ALE::Exception e) {
1447: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1448: }
1449: if (bcFilename) {
1450: ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1451: }
1452: MeshSetMesh(*mesh, m);
1453: return(0);
1454: }
1458: /*@C
1459: MeshCreatePyLith - Create a Mesh from PyLith files.
1461: Not Collective
1463: Input Parameters:
1464: + dim - The topological mesh dimension
1465: . baseFilename - The basename for mesh files
1466: . zeroBase - Use 0 to start numbering
1467: - interpolate - The flag for mesh interpolation
1469: Output Parameter:
1470: . mesh - The Mesh object
1472: Level: beginner
1474: .keywords: mesh, PCICE
1475: .seealso: MeshCreate()
1476: @*/
1477: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1478: {
1479: ALE::Obj<ALE::Mesh> m;
1480: PetscInt debug = 0;
1481: PetscTruth flag;
1482: PetscErrorCode ierr;
1485: MeshCreate(comm, mesh);
1486: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1487: try {
1488: m = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1489: } catch(ALE::Exception e) {
1490: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1491: }
1492: MeshSetMesh(*mesh, m);
1493: return(0);
1494: }
1498: /*@C
1499: MeshGetCoordinates - Creates an array holding the coordinates.
1501: Not Collective
1503: Input Parameter:
1504: + mesh - The Mesh object
1505: - columnMajor - Flag for column major order
1507: Output Parameter:
1508: + numVertices - The number of vertices
1509: . dim - The embedding dimension
1510: - coords - The array holding local coordinates
1512: Level: intermediate
1514: .keywords: mesh, coordinates
1515: .seealso: MeshCreate()
1516: @*/
1517: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1518: {
1519: ALE::Obj<ALE::Mesh> m;
1520: PetscErrorCode ierr;
1523: MeshGetMesh(mesh, m);
1524: ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1525: return(0);
1526: }
1530: /*@C
1531: MeshGetElements - Creates an array holding the vertices on each element.
1533: Not Collective
1535: Input Parameters:
1536: + mesh - The Mesh object
1537: - columnMajor - Flag for column major order
1539: Output Parameters:
1540: + numElements - The number of elements
1541: . numCorners - The number of vertices per element
1542: - vertices - The array holding vertices on each local element
1544: Level: intermediate
1546: .keywords: mesh, elements
1547: .seealso: MeshCreate()
1548: @*/
1549: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1550: {
1551: ALE::Obj<ALE::Mesh> m;
1552: PetscErrorCode ierr;
1555: MeshGetMesh(mesh, m);
1556: ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1557: return(0);
1558: }
1562: /*@C
1563: MeshDistribute - Distributes the mesh and any associated sections.
1565: Not Collective
1567: Input Parameter:
1568: + serialMesh - The original Mesh object
1569: - partitioner - The partitioning package, or NULL for the default
1571: Output Parameter:
1572: . parallelMesh - The distributed Mesh object
1574: Level: intermediate
1576: .keywords: mesh, elements
1578: .seealso: MeshCreate(), MeshDistributeByFace()
1579: @*/
1580: PetscErrorCode MeshDistribute(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1581: {
1582: ALE::Obj<ALE::Mesh> oldMesh;
1583: PetscErrorCode ierr;
1586: MeshGetMesh(serialMesh, oldMesh);
1587: MeshCreate(oldMesh->comm(), parallelMesh);
1588: if (partitioner == NULL) {
1589: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh);
1590: MeshSetMesh(*parallelMesh, newMesh);
1591: } else {
1592: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 0, partitioner);
1593: MeshSetMesh(*parallelMesh, newMesh);
1594: }
1595: return(0);
1596: }
1600: /*@C
1601: MeshDistribute - Distributes the mesh and any associated sections.
1603: Not Collective
1605: Input Parameter:
1606: + serialMesh - The original Mesh object
1607: - partitioner - The partitioning package, or NULL for the default
1609: Output Parameter:
1610: . parallelMesh - The distributed Mesh object
1612: Level: intermediate
1614: .keywords: mesh, elements
1616: .seealso: MeshCreate(), MeshDistribute()
1617: @*/
1618: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1619: {
1620: ALE::Obj<ALE::Mesh> oldMesh;
1621: PetscErrorCode ierr;
1624: MeshGetMesh(serialMesh, oldMesh);
1625: MeshCreate(oldMesh->comm(), parallelMesh);
1626: if (partitioner == NULL) {
1627: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1);
1628: MeshSetMesh(*parallelMesh, newMesh);
1629: } else {
1630: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1, partitioner);
1631: MeshSetMesh(*parallelMesh, newMesh);
1632: }
1633: return(0);
1634: }
1638: /*@C
1639: MeshGenerate - Generates a mesh.
1641: Not Collective
1643: Input Parameters:
1644: + boundary - The Mesh boundary object
1645: - interpolate - Flag to create intermediate mesh elements
1647: Output Parameter:
1648: . mesh - The Mesh object
1650: Level: intermediate
1652: .keywords: mesh, elements
1653: .seealso: MeshCreate(), MeshRefine()
1654: @*/
1655: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1656: {
1657: ALE::Obj<ALE::Mesh> mB;
1658: PetscErrorCode ierr;
1661: MeshGetMesh(boundary, mB);
1662: MeshCreate(mB->comm(), mesh);
1663: ALE::Obj<ALE::Mesh> m = ALE::Generator::generateMesh(mB, interpolate);
1664: MeshSetMesh(*mesh, m);
1665: return(0);
1666: }
1670: /*@C
1671: MeshRefine - Refines the mesh.
1673: Not Collective
1675: Input Parameters:
1676: + mesh - The original Mesh object
1677: . refinementLimit - The maximum size of any cell
1678: - interpolate - Flag to create intermediate mesh elements
1680: Output Parameter:
1681: . refinedMesh - The refined Mesh object
1683: Level: intermediate
1685: .keywords: mesh, elements
1686: .seealso: MeshCreate(), MeshGenerate()
1687: @*/
1688: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1689: {
1690: ALE::Obj<ALE::Mesh> oldMesh;
1691: PetscErrorCode ierr;
1694: MeshGetMesh(mesh, oldMesh);
1695: MeshCreate(oldMesh->comm(), refinedMesh);
1696: ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, interpolate);
1697: MeshSetMesh(*refinedMesh, newMesh);
1698: return(0);
1699: }
1703: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1704: {
1705: ALE::Obj<ALE::Mesh> oldMesh;
1706: double refinementLimit;
1707: PetscErrorCode ierr;
1710: MeshGetMesh(mesh, oldMesh);
1711: MeshCreate(comm, refinedMesh);
1712: refinementLimit = oldMesh->getMaxVolume()/2.0;
1713: ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, true);
1714: MeshSetMesh(*refinedMesh, newMesh);
1715: const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default");
1716: const Obj<std::set<std::string> >& discs = oldMesh->getDiscretizations();
1718: for(std::set<std::string>::const_iterator f_iter = discs->begin(); f_iter != discs->end(); ++f_iter) {
1719: newMesh->setDiscretization(*f_iter, oldMesh->getDiscretization(*f_iter));
1720: }
1721: newMesh->setupField(s);
1722: return(0);
1723: }
1726: #include "Hierarchy_New.hh"
1732: #include "Hierarchy.hh"
1736: /*@C
1737: MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.
1739: Not Collective
1741: Input Parameters:
1742: + mesh - The original Mesh object
1743: . numLevels - The number of
1744: . coarseningFactor - The expansion factor for coarse meshes
1745: - interpolate - Flag to create intermediate mesh elements
1747: Output Parameter:
1748: . coarseHierarchy - The coarse Mesh objects
1750: Level: intermediate
1752: .keywords: mesh, elements
1753: .seealso: MeshCreate(), MeshGenerate()
1754: @*/
1755: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh **coarseHierarchy)
1756: {
1757: ALE::Obj<ALE::Mesh> oldMesh;
1758: PetscErrorCode ierr;
1761: if (numLevels < 1) {
1762: *coarseHierarchy = PETSC_NULL;
1763: return(0);
1764: }
1765: MeshGetMesh(mesh, oldMesh);
1766: PetscMalloc((numLevels+1) * sizeof(Mesh), coarseHierarchy);
1767: for (int i = 0; i < numLevels+1; i++) {
1768: MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[i]);
1769: }
1770: MeshSpacingFunction(mesh);
1771: MeshCreateHierarchyLabel_Link(mesh, coarseningFactor, numLevels+1, *coarseHierarchy);
1772:
1773: #if 0
1774: if (oldMesh->getDimension() != 2) SETERRQ(PETSC_ERR_SUP, "Coarsening only works in two dimensions right now");
1775: ALE::Coarsener::IdentifyBoundary(oldMesh, 2);
1776: ALE::Coarsener::make_coarsest_boundary(oldMesh, 2, numLevels+1);
1777: ALE::Coarsener::CreateSpacingFunction(oldMesh, 2);
1778: ALE::Coarsener::CreateCoarsenedHierarchyNew(oldMesh, 2, numLevels, coarseningFactor);
1779: PetscMalloc(numLevels * sizeof(Mesh),coarseHierarchy);
1780: for(int l = 0; l < numLevels; l++) {
1781: ALE::Obj<ALE::Mesh> newMesh = new ALE::Mesh(oldMesh->comm(), oldMesh->debug());
1782: const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default");
1784: MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1785: newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1786: newMesh->setDiscretization(oldMesh->getDiscretization());
1787: newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1788: newMesh->setupField(s);
1789: MeshSetMesh((*coarseHierarchy)[l], newMesh);
1790: }
1791: #endif
1792: return(0);
1793: }
1795: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh **coarseHierarchy)
1796: {
1798: double cfactor = 1.5;
1800: PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1801: MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1802: return(0);
1803: }
1805: #if 0
1810: //Interpolate between two meshes whenever the unknowns can be evaluated at points.
1812: PetscErrorCode MeshGetInterpolation_Mesh_General(Mesh coarse_mesh, Mesh fine_mesh, Mat *interpolation, Vec *scaling) {
1813: ALE::Obj<ALE::Mesh> fm, cm;
1814: Mat P;
1815: PetscErrorCode ierr;
1816:
1818: //Stages:
1819: // 1. Create a section on the fine mesh describing the location in the fine mesh of the assorted unknowns.
1820: // 2. Fill in this section by traversing across the mesh via cones and supports, transforming the coordinates of the assorted functional points
1821: // 3. Preallocate the matrix rows/columns
1822: // 4. Assemble the matrix by writing evaluating each unknown as the point
1823: MeshGetMesh(dmFine, fm);
1824: MeshGetMesh(dmCoarse, cm);
1825: // ALE::Obj<ALE::Mesh::label_type> coarsetraversal = cm->createLabel("traversal");
1826: // ALE::Obj<ALE::Mesh::label_type> finetraversal = fm->createLabel ("traversal");
1827: const int debug = fm->debug();
1828: if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1829: const ALE::Obj<ALE::Mesh::real_section_type>& finecoordinates = fm->getRealSection("coordinates");
1830: const ALE::Obj<ALE::Mesh::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
1832: const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse = cm->getRealSection("default");
1833: const ALE::Obj<ALE::Mesh::real_section_type>& sFine = fm->getRealSection("default");
1835: const ALE::Obj<ALE::Mesh::order_type>& coarseOrder = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1836: const ALE::Obj<ALE::Mesh::order_type>& fineOrder = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
1838: std::list<ALE::Mesh::point_type> travlist; // store point
1839: std::list<ALE::Mesh::point_type> travguesslist; // store guess
1840: std::list<ALE::Mesh::point_type> eguesslist; // store the next guesses for the location of the current point.
1842: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> coarse_traversal = ALE::Mesh::sieve_type::supportSet();
1843: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> fine_traversal = ALE::Mesh::sieve_type::supportSet();
1844: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> covering_points = ALE::Mesh::sieve_type::supportSet();
1846: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> uncorrected_points = ALE::Mesh::sieve_type::supportSet();
1847: static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1848: if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}
1850: //set up the new section holding the names of the contained points.
1851:
1852:
1854: const ALE::Obj<ALE::Mesh::int_section_type> & node_locations = fm->getIntSection("node_locations");
1855: for (int i = 0; i < dim; i++) {
1856: const ALE::Obj<ALE::Mesh::label_sequence> & present_level = fm->depthStratum(i);
1857: int current_dimension =
1858: node_locations->setFiberDimension(present_level);
1859: }
1860: node_locations->allocate();
1862:
1864: }
1866: #endif
1872: PetscErrorCode MeshGetInterpolation_Mesh_New(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling) {
1874: ALE::Obj<ALE::Mesh> fm, cm;
1875: Mat P;
1876: PetscErrorCode ierr;
1879: MeshGetMesh(dmFine, fm);
1880: MeshGetMesh(dmCoarse, cm);
1881: // ALE::Obj<ALE::Mesh::label_type> coarsetraversal = cm->createLabel("traversal");
1882: // ALE::Obj<ALE::Mesh::label_type> finetraversal = fm->createLabel ("traversal");
1883: const int debug = fm->debug();
1884: if (debug) {PetscPrintf(fm->comm(), "Fine: %d vertices, Coarse: %d vertices\n", fm->depthStratum(0)->size(), cm->depthStratum(0)->size());}
1885: const ALE::Obj<ALE::Mesh::real_section_type>& finecoordinates = fm->getRealSection("coordinates");
1886: const ALE::Obj<ALE::Mesh::real_section_type>& coarsecoordinates = cm->getRealSection("coordinates");
1887: const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse = cm->getRealSection("default");
1888: const ALE::Obj<ALE::Mesh::real_section_type>& sFine = fm->getRealSection("default");
1889: const ALE::Obj<ALE::Mesh::order_type>& coarseOrder = cm->getFactory()->getGlobalOrder(cm, "default", sCoarse);
1890: const ALE::Obj<ALE::Mesh::order_type>& fineOrder = fm->getFactory()->getGlobalOrder(fm, "default", sFine);
1891: std::list<ALE::Mesh::point_type> travlist; // store point
1892: std::list<ALE::Mesh::point_type> travguesslist; // store guess
1893: std::list<ALE::Mesh::point_type> eguesslist; // store the next guesses for the location of the current point.
1894: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> coarse_traversal = ALE::Mesh::sieve_type::supportSet();
1895: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> fine_traversal = ALE::Mesh::sieve_type::supportSet();
1896: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> uncorrected_points = ALE::Mesh::sieve_type::supportSet();
1897: static double loc[4], v0[3], J[9], invJ[9], detJ; // first point, jacobian, inverse jacobian, and jacobian determinant of a cell
1898: if (debug) {PetscPrintf(fm->comm(), "Starting Interpolation Matrix Build\n");}
1900: MatCreate(fm->comm(), &P);
1901: MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
1902: MatSeqAIJSetPreallocation(P,10,PETSC_NULL);
1903: MatSetFromOptions(P);
1905: const int dim = fm->getDimension();
1906: int maxComparisons = 60; //point is considered a lost cause beyond this many comparisons with volumes
1907: if (dim == 3) maxComparisons = 1000; //3D is odd
1908: if (dim != cm->getDimension()) throw ALE::Exception("Dimensions of the fine and coarse meshes do not match");
1910: //traversal labels on both layers
1911: const ALE::Obj<ALE::Mesh::label_sequence>& finevertices = fm->depthStratum(0);
1912: const ALE::Mesh::label_sequence::iterator fv_iter_end = finevertices->end();
1913: ALE::Mesh::label_sequence::iterator fv_iter = finevertices->begin();
1915: // while (fv_iter != fv_iter_end) {
1916: // fm->setValue(finetraversal, *fv_iter, 0);
1917: // fv_iter++;
1918: // }
1920: const ALE::Obj<ALE::Mesh::label_sequence>& coarseelements = cm->heightStratum(0);
1921: const ALE::Mesh::label_sequence::iterator ce_iter_end = coarseelements->end();
1922: ALE::Mesh::label_sequence::iterator ce_iter = coarseelements->begin();
1923:
1924: // while (ce_iter != ce_iter_end) {
1925: // cm->setValue(coarsetraversal, *ce_iter, 0);
1926: // ce_iter++;
1927: // }
1929: double *fvCoords = new double[dim], *nvCoords = new double[dim];
1930: bool pointIsInElement;
1932: if (debug) {PetscPrintf(fm->comm(), "starting iterations\n");}
1933: fv_iter = finevertices->begin();
1934: while (fv_iter != fv_iter_end) {
1935: // locate an initial point.
1936: // if (fm->getValue(finetraversal, *fv_iter) == 0) {
1937: if ((fine_traversal->find(*fv_iter) == fine_traversal->end()) && (uncorrected_points->find(*fv_iter) == uncorrected_points->end())) {
1938: bool isLocated = false;
1940: ce_iter = coarseelements->begin();
1941: PetscMemcpy(fvCoords, finecoordinates->restrictPoint(*fv_iter), dim*sizeof(double));
1942: while ((ce_iter != ce_iter_end) && (!isLocated)) {
1943: cm->computeElementGeometry(coarsecoordinates, *ce_iter, v0, J, invJ, detJ);
1944: // generalized simplicial location for 2D, 3D:
1945: loc[0] = 1.0;
1946: pointIsInElement = true;
1947: for(int i = 0; i < dim; i++) {
1948: loc[i+1] = 0.0;
1949: for(int j = 0; j < dim; j++) {
1950: loc[i+1] += 0.5*invJ[i*dim+j]*(fvCoords[j] - v0[j]);
1951: }
1952: loc[0] -= loc[i+1];
1953: //PetscPrintf(fm->comm(), "%f, ", loc[i+1]);
1954: if (loc[i+1] < -0.000000000001) pointIsInElement = false;
1955: }
1956: //PetscPrintf(fm->comm(), "%f\n", loc[0]);
1957: if (loc[0] < -0.000000000001) pointIsInElement = false;
1958: if (pointIsInElement) {
1959: //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
1960: //PetscPrintf(fm->comm(), "located by guess.\n");
1961: isLocated = true;
1962: updateOperatorGeneral(P, fm, sFine, fineOrder, *fv_iter, cm, sCoarse, coarseOrder, *ce_iter, loc, INSERT_VALUES);
1963: //fm->setValue(finetraversal, *fv_iter, 1);
1964: fine_traversal->insert(*fv_iter);
1965: const ALE::Obj<ALE::Mesh::sieve_type::coneSet> & neighbors = fm->getSieve()->cone(fm->getSieve()->support(*fv_iter));
1966: const ALE::Mesh::sieve_type::coneSet::iterator n_iter_end = neighbors->end();
1967: ALE::Mesh::sieve_type::coneSet::iterator n_iter = neighbors->begin();
1968: while (n_iter != n_iter_end) {
1969: // if (fm->getValue(finetraversal, *n_iter) == 0) {
1970: if (fine_traversal->find(*n_iter) != fine_traversal->end()) {
1971: travlist.push_back(*n_iter);
1972: // fm->setValue(finetraversal, *n_iter, 1);
1973: fine_traversal->insert(*n_iter);
1974: travguesslist.push_back(*ce_iter);
1975: }
1976: n_iter++;
1977: }
1978: //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.
1979: while (!travlist.empty()) {
1980: ALE::Mesh::point_type curVert = *travlist.begin();
1981: PetscMemcpy(nvCoords, finecoordinates->restrictPoint(curVert), dim*sizeof(double));
1982: ALE::Mesh::point_type curEle = *travguesslist.begin();
1983: travlist.pop_front();
1984: travguesslist.pop_front();
1985: eguesslist.push_front(curEle);
1986: //cm->setValue(coarsetraversal, curEle, 1);
1987: coarse_traversal->insert(curEle);
1988: bool locationDiscovered = false;
1989: //int traversalcomparisons = 0;
1990: while ((!eguesslist.empty()) && (!locationDiscovered) && (int)coarse_traversal->size() < maxComparisons) {
1991: //traversalcomparisons = 0;
1992: ALE::Mesh::point_type curguess = *eguesslist.begin();
1993: eguesslist.pop_front();
1994: pointIsInElement = true;
1995: cm->computeElementGeometry(coarsecoordinates, curguess, v0, J, invJ, detJ);
1996: loc[0] = 1.0;
1997: for(int i = 0; i < dim; i++) {
1998: loc[i+1] = 0.0;
1999: for(int j = 0; j < dim; j++) {
2000: loc[i+1] += 0.5*invJ[i*dim+j]*(nvCoords[j] - v0[j]);
2001: }
2002: loc[0] -= loc[i+1];
2003: if (loc[i+1] < -0.00000000001) pointIsInElement = false;
2004: }
2005: if (loc[0] < -0.00000000001) pointIsInElement = false;
2007: if (pointIsInElement) {
2008: //PetscPrintf(fm->comm(), "%f, %f, %f\n", loc[0], loc[1], loc[2]);
2009: locationDiscovered = true;
2010: //PetscPrintf(fm->comm(), "located by traversal.\n");
2011: //set the label.
2012: //fm->setValue(prolongation, curVert, curguess);
2013: updateOperatorGeneral(P, fm, sFine, fineOrder, curVert, cm, sCoarse, coarseOrder, curguess, loc, INSERT_VALUES);
2014: //PetscPrintf(fm->comm(), "Point %d located in %d.\n", curVert, curguess);
2015: //stick its neighbors in the queue along with its location as a good guess of the location of its neighbors
2016: const ALE::Obj<ALE::Mesh::sieve_type::coneSet> newNeighbors = fm->getSieve()->cone(fm->getSieve()->support(curVert));
2017: const ALE::Mesh::sieve_type::coneSet::iterator nn_iter_end = newNeighbors->end();
2018: ALE::Mesh::sieve_type::coneSet::iterator nn_iter = newNeighbors->begin();
2019: while (nn_iter != nn_iter_end) {
2020: //if (fm->getValue(finetraversal, *nn_iter) == 0) { //unlocated neighbor
2021: if (fine_traversal->find(*nn_iter) == fine_traversal->end()) {
2022: travlist.push_back(*nn_iter);
2023: travguesslist.push_back(curguess);
2024: //fm->setValue(finetraversal, *nn_iter, 1);
2025: fine_traversal->insert(*nn_iter);
2026: }
2027: nn_iter++;
2028: }
2029: } else {
2030: //add the current guesses neighbors to the comparison queue and start over.
2031: const ALE::Obj<ALE::Mesh::sieve_type::supportSet> & curguessneighbors = cm->getSieve()->support(cm->getSieve()->cone(curguess));
2032: const ALE::Mesh::sieve_type::supportSet::iterator cgn_iter_end = curguessneighbors->end();
2033: ALE::Mesh::sieve_type::supportSet::iterator cgn_iter = curguessneighbors->begin();
2034: while (cgn_iter != cgn_iter_end) {
2035: //if (cm->getValue(coarsetraversal, *cgn_iter) == 0) {
2036: if (coarse_traversal->find(*cgn_iter) == coarse_traversal->end()) {
2037: eguesslist.push_back(*cgn_iter);
2038: //cm->setValue(coarsetraversal, *cgn_iter, 1);
2039: coarse_traversal->insert(*cgn_iter);
2040: }
2041: cgn_iter++;
2042: }
2043: }
2044: }
2045: coarse_traversal->clear();
2046: if (!locationDiscovered) { //if a position for it is not discovered, it doesn't get corrected; complain
2047: if (fm->debug())PetscPrintf(fm->comm(), "Point %d (%f, %f) not located.\n", curVert, nvCoords[0], nvCoords[1]);
2048: //fm->setValue(finetraversal, curVert, 2); //don't try again.
2049: uncorrected_points->insert(curVert);
2050: }
2051: eguesslist.clear(); //we've discovered the location of the point or exhausted our possibilities on this contiguous block of elements.
2052: //unset the traversed element list
2053: //const ALE::Obj<ALE::Mesh::label_sequence>& traved_elements = cm->getLabelStratum("traversal", 1);
2054: //const ALE::Mesh::label_sequence::iterator tp_iter_end = traved_elements->end();
2055: //ALE::Mesh::label_sequence::iterator tp_iter = traved_elements->begin();
2056: //PetscPrintf(cm->comm(), "%d\n", traved_elements->size());
2057: //while (tp_iter != tp_iter_end) {
2058: // eguesslist.push_back(*tp_iter);
2059: // tp_iter++;
2060: //}
2061: //while (!eguesslist.empty()) {
2062: // cm->setValue(coarsetraversal, *eguesslist.begin(), 0);
2063: // eguesslist.pop_front();
2064: //}
2065:
2066: }
2067: }
2068: ce_iter++;
2069: }
2070: if (!isLocated) {
2071: if (fm->debug())PetscPrintf(fm->comm(), "NOT located\n");
2072: //fm->setValue(finetraversal, *fv_iter, 2); //don't try again.
2073: uncorrected_points->insert(*fv_iter);
2074: }
2075: }
2076: // printf("-");
2077: fv_iter++;
2078: }
2079: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2080: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2081: //MatView(P, PETSC_VIEWER_STDOUT_SELF);
2082: delete [] fvCoords; delete [] nvCoords;
2083: *interpolation = P;
2084: if (debug) {PetscPrintf(fm->comm(), "Ending Interpolation Matrix Build\n");}
2085: return(0);
2086: }
2091: /*
2092: This method only handle P_1 discretizations at present.
2093: */
2094: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
2095: {
2096: ALE::Obj<ALE::Mesh> coarse;
2097: ALE::Obj<ALE::Mesh> fine;
2098: Mat P;
2099: PetscErrorCode ierr;
2102: MeshGetMesh(dmFine, fine);
2103: MeshGetMesh(dmCoarse, coarse);
2104: const ALE::Obj<ALE::Mesh::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
2105: const ALE::Obj<ALE::Mesh::real_section_type>& fineCoordinates = fine->getRealSection("coordinates");
2106: const ALE::Obj<ALE::Mesh::label_sequence>& vertices = fine->depthStratum(0);
2107: const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse = coarse->getRealSection("default");
2108: const ALE::Obj<ALE::Mesh::real_section_type>& sFine = fine->getRealSection("default");
2109: const ALE::Obj<ALE::Mesh::order_type>& coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
2110: const ALE::Obj<ALE::Mesh::order_type>& fineOrder = fine->getFactory()->getGlobalOrder(fine, "default", sFine);
2112: const int dim = coarse->getDimension();
2113: const int numDof = fine->getDiscretization()->getNumDof(fine->getDimension());
2114: double *v0, *J, *invJ, detJ, *refCoords, *values;
2116: MatCreate(fine->comm(), &P);
2117: MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
2118: MatSetFromOptions(P);
2119: MatSeqAIJSetPreallocation(P, numDof, PETSC_NULL);
2120: MatMPIAIJSetPreallocation(P, numDof, PETSC_NULL, numDof, PETSC_NULL);
2121: PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
2122: bool hasprolong;
2123: if (fine->hasLabel("prolongation")) {
2124: hasprolong = true;
2125: } else {
2126: hasprolong = false;
2127: PetscPrintf(fine->comm(), "WARNING: Point Location Label Does Not Exist");
2128: }
2129: ALE::Mesh::label_sequence::iterator v_iter_end = vertices->end();
2130: ALE::Mesh::real_section_type::value_type *coords = new ALE::Mesh::real_section_type::value_type[dim];
2132: for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != v_iter_end; ++v_iter) {
2133: //const ALE::Mesh::real_section_type::value_type *coords = fineCoordinates->restrictPoint(*v_iter);
2134: PetscMemcpy(coords, fineCoordinates->restrictPoint(*v_iter), dim*sizeof(double));
2135: ALE::Mesh::point_type coarseCell;
2136: ALE::Mesh::point_type cellguess = -1;
2137: if (hasprolong) {
2138: cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
2139: coarseCell = coarse->locatePoint(coords, cellguess);
2140: } else {
2141: coarseCell = coarse->locatePoint(coords);
2142: }
2143: // coarseCell = coarse->locatePoint(coords);
2144: if (coarseCell == -1) {
2145: // do NO CORRECTION!
2146: } else {
2147: coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
2148: for(int d = 0; d < dim; ++d) {
2149: refCoords[d] = 0.0;
2150: for(int e = 0; e < dim; ++e) {
2151: refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
2152: }
2153: refCoords[d] -= 1.0;
2154: }
2155: values[0] = -(refCoords[0] + refCoords[1])/2.0;
2156: values[1] = 0.5*(refCoords[0] + 1.0);
2157: values[2] = 0.5*(refCoords[1] + 1.0);
2158: // PetscPrintf(fine->comm(), "%f, %f, %f\n", values[0], values[1], values[2]);
2159: updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
2160: }
2161: }
2162: PetscFree5(v0,J,invJ,refCoords,values);
2163: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
2164: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
2165: delete [] coords;
2166: *interpolation = P;
2167: return(0);
2168: }
2172: /*@C
2173: MeshHasSectionReal - Determines whether this mesh has a SectionReal with the given name.
2175: Not Collective
2177: Input Parameters:
2178: + mesh - The Mesh object
2179: - name - The section name
2181: Output Parameter:
2182: . flag - True if the SectionReal is present in the Mesh
2184: Level: intermediate
2186: .keywords: mesh, elements
2187: .seealso: MeshCreate()
2188: @*/
2189: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
2190: {
2191: ALE::Obj<ALE::Mesh> m;
2192: PetscErrorCode ierr;
2195: MeshGetMesh(mesh, m);
2196: *flag = (PetscTruth) m->hasRealSection(std::string(name));
2197: return(0);
2198: }
2202: /*@C
2203: MeshGetSectionReal - Returns a SectionReal of the given name from the Mesh.
2205: Collective on Mesh
2207: Input Parameters:
2208: + mesh - The Mesh object
2209: - name - The section name
2211: Output Parameter:
2212: . section - The SectionReal
2214: Note: The section is a new object, and must be destroyed by the user
2216: Level: intermediate
2218: .keywords: mesh, elements
2219: .seealso: MeshCreate()
2220: @*/
2221: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
2222: {
2223: ALE::Obj<ALE::Mesh> m;
2224: PetscErrorCode ierr;
2227: MeshGetMesh(mesh, m);
2228: SectionRealCreate(m->comm(), section);
2229: PetscObjectSetName((PetscObject) *section, name);
2230: SectionRealSetSection(*section, m->getRealSection(std::string(name)));
2231: SectionRealSetBundle(*section, m);
2232: return(0);
2233: }
2237: /*@C
2238: MeshSetSectionReal - Puts a SectionReal of the given name into the Mesh.
2240: Collective on Mesh
2242: Input Parameters:
2243: + mesh - The Mesh object
2244: - section - The SectionReal
2246: Note: This takes the section name from the PETSc object
2248: Level: intermediate
2250: .keywords: mesh, elements
2251: .seealso: MeshCreate()
2252: @*/
2253: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
2254: {
2255: ALE::Obj<ALE::Mesh> m;
2256: ALE::Obj<ALE::Mesh::real_section_type> s;
2257: const char *name;
2258: PetscErrorCode ierr;
2261: MeshGetMesh(mesh, m);
2262: PetscObjectGetName((PetscObject) section, &name);
2263: SectionRealGetSection(section, s);
2264: m->setRealSection(std::string(name), s);
2265: return(0);
2266: }
2270: /*@C
2271: MeshHasSectionInt - Determines whether this mesh has a SectionInt with the given name.
2273: Not Collective
2275: Input Parameters:
2276: + mesh - The Mesh object
2277: - name - The section name
2279: Output Parameter:
2280: . flag - True if the SectionInt is present in the Mesh
2282: Level: intermediate
2284: .keywords: mesh, elements
2285: .seealso: MeshCreate()
2286: @*/
2287: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2288: {
2289: ALE::Obj<ALE::Mesh> m;
2290: PetscErrorCode ierr;
2293: MeshGetMesh(mesh, m);
2294: *flag = (PetscTruth) m->hasIntSection(std::string(name));
2295: return(0);
2296: }
2300: /*@C
2301: MeshGetSectionInt - Returns a SectionInt of the given name from the Mesh.
2303: Collective on Mesh
2305: Input Parameters:
2306: + mesh - The Mesh object
2307: - name - The section name
2309: Output Parameter:
2310: . section - The SectionInt
2312: Note: The section is a new object, and must be destroyed by the user
2314: Level: intermediate
2316: .keywords: mesh, elements
2317: .seealso: MeshCreate()
2318: @*/
2319: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2320: {
2321: ALE::Obj<ALE::Mesh> m;
2322: PetscErrorCode ierr;
2325: MeshGetMesh(mesh, m);
2326: SectionIntCreate(m->comm(), section);
2327: PetscObjectSetName((PetscObject) *section, name);
2328: SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2329: SectionIntSetBundle(*section, m);
2330: return(0);
2331: }
2335: /*@C
2336: MeshSetSectionInt - Puts a SectionInt of the given name into the Mesh.
2338: Collective on Mesh
2340: Input Parameters:
2341: + mesh - The Mesh object
2342: - section - The SectionInt
2344: Note: This takes the section name from the PETSc object
2346: Level: intermediate
2348: .keywords: mesh, elements
2349: .seealso: MeshCreate()
2350: @*/
2351: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2352: {
2353: ALE::Obj<ALE::Mesh> m;
2354: ALE::Obj<ALE::Mesh::int_section_type> s;
2355: const char *name;
2356: PetscErrorCode ierr;
2359: MeshGetMesh(mesh, m);
2360: PetscObjectGetName((PetscObject) section, &name);
2361: SectionIntGetSection(section, s);
2362: m->setIntSection(std::string(name), s);
2363: return(0);
2364: }
2368: /*@C
2369: SectionGetArray - Returns the array underlying the Section.
2371: Not Collective
2373: Input Parameters:
2374: + mesh - The Mesh object
2375: - name - The section name
2377: Output Parameters:
2378: + numElements - The number of mesh element with values
2379: . fiberDim - The number of values per element
2380: - array - The array
2382: Level: intermediate
2384: .keywords: mesh, elements
2385: .seealso: MeshCreate()
2386: @*/
2387: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2388: {
2389: ALE::Obj<ALE::Mesh> m;
2390: PetscErrorCode ierr;
2393: MeshGetMesh(mesh, m);
2394: const Obj<ALE::Mesh::real_section_type>& section = m->getRealSection(std::string(name));
2395: if (section->size() == 0) {
2396: *numElements = 0;
2397: *fiberDim = 0;
2398: *array = NULL;
2399: return(0);
2400: }
2401: const ALE::Mesh::real_section_type::chart_type& chart = section->getChart();
2402: /* const int depth = m->depth(*chart.begin()); */
2403: /* *numElements = m->depthStratum(depth)->size(); */
2404: /* *fiberDim = section->getFiberDimension(*chart.begin()); */
2405: /* *array = (PetscScalar *) m->restrict(section); */
2406: int fiberDimMin = section->getFiberDimension(*chart.begin());
2407: int numElem = 0;
2409: for(ALE::Mesh::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2410: const int fiberDim = section->getFiberDimension(*c_iter);
2412: if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2413: }
2414: for(ALE::Mesh::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2415: const int fiberDim = section->getFiberDimension(*c_iter);
2417: numElem += fiberDim/fiberDimMin;
2418: }
2419: *numElements = numElem;
2420: *fiberDim = fiberDimMin;
2421: *array = (PetscScalar *) section->restrict();
2422: return(0);
2423: }
2427: PetscErrorCode WritePyLithVertices(Mesh mesh, PetscViewer viewer)
2428: {
2429: ALE::Obj<ALE::Mesh> m;
2432: MeshGetMesh(mesh, m);
2433: return ALE::PyLith::Viewer::writeVertices(m, viewer);
2434: }
2438: PetscErrorCode WritePyLithElements(Mesh mesh, SectionInt material, PetscViewer viewer)
2439: {
2440: ALE::Obj<ALE::Mesh> m;
2441: ALE::Obj<ALE::Mesh::int_section_type> s;
2444: MeshGetMesh(mesh, m);
2445: SectionIntGetSection(material, s);
2446: return ALE::PyLith::Viewer::writeElements(m, s, viewer);
2447: }
2451: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2452: {
2453: ALE::Obj<ALE::Mesh> m;
2456: MeshGetMesh(mesh, m);
2457: return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2458: }
2462: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2463: {
2464: ALE::Obj<ALE::Mesh> m;
2465: ALE::Obj<ALE::Mesh::int_section_type> s;
2468: MeshGetMesh(mesh, m);
2469: SectionIntGetSection(material, s);
2470: return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2471: }
2473: #if 0
2476: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2477: {
2478: ALE::Obj<ALE::Mesh> m;
2481: MeshGetMesh(mesh, m);
2482: return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2483: }
2484: #endif
2488: /*@C
2489: MeshCompatGetMesh - Gets the internal mesh object
2491: Not collective
2493: Input Parameter:
2494: . mesh - the mesh object
2496: Output Parameter:
2497: . m - the internal mesh object
2499: Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2500: developing for that tool.
2501:
2502: Level: developer
2504: .seealso MeshCreate(), MeshSetMesh()
2506: @*/
2507: PetscErrorCode MeshCompatGetMesh(Mesh mesh, ALE::Obj<ALECompat::Mesh>& m)
2508: {
2511: m = mesh->mcompat;
2512: return(0);
2513: }
2517: /*@C
2518: MeshCompatSetMesh - Sets the internal mesh object
2520: Not collective
2522: Input Parameters:
2523: + mesh - the mesh object
2524: - m - the internal mesh object
2526: Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2527: developing for that tool.
2528:
2529: Level: developer
2531: .seealso MeshCreate(), MeshGetMesh()
2533: @*/
2534: PetscErrorCode MeshCompatSetMesh(Mesh mesh, const ALE::Obj<ALECompat::Mesh>& m)
2535: {
2538: mesh->mcompat = m;
2539: return(0);
2540: }
2544: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2545: {
2546: const int end = interval.prefix + interval.index;
2547: for(int i = interval.index; i < end; i++) {
2548: indices[indx++] = i;
2549: }
2550: }
2554: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2555: {
2556: for(int i = 0; i < interval.prefix; i++) {
2557: indices[(*indx)++] = interval.index + i;
2558: }
2559: for(int i = 0; i < -interval.prefix; i++) {
2560: indices[(*indx)++] = -1;
2561: }
2562: }
2566: PetscErrorCode ExpandIntervals(ALE::Obj<ALECompat::Mesh::real_section_type::IndexArray> intervals, PetscInt *indices)
2567: {
2568: int k = 0;
2571: for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_itor = intervals->begin(); i_itor != intervals->end(); i_itor++) {
2572: ExpandInterval_New(*i_itor, indices, &k);
2573: }
2574: return(0);
2575: }
2579: template<typename Section>
2580: PetscErrorCode MeshCompatCreateGlobalScatter(const ALE::Obj<ALECompat::Mesh>& m, const ALE::Obj<Section>& s, VecScatter *scatter)
2581: {
2582: typedef ALECompat::Mesh::real_section_type::index_type index_type;
2587: const ALE::Obj<ALECompat::Mesh::topology_type>& topology = m->getTopology();
2588: const ALE::Obj<ALECompat::Mesh::real_section_type::atlas_type>& atlas = s->getAtlas();
2589: const ALECompat::Mesh::real_section_type::patch_type patch = 0;
2590: const ALECompat::Mesh::real_section_type::atlas_type::chart_type& chart = atlas->getPatch(patch);
2591: const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(topology, patch, s->getName(), atlas);
2592: int *localIndices, *globalIndices;
2593: int localSize = s->size(patch);
2594: int localIndx = 0, globalIndx = 0;
2595: Vec globalVec, localVec;
2596: IS localIS, globalIS;
2598: VecCreate(m->comm(), &globalVec);
2599: VecSetSizes(globalVec, globalOrder->getLocalSize(), PETSC_DETERMINE);
2600: VecSetFromOptions(globalVec);
2601: // Loop over all local points
2602: PetscMalloc(localSize*sizeof(int), &localIndices);
2603: PetscMalloc(localSize*sizeof(int), &globalIndices);
2604: for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator p_iter = chart.begin(); p_iter != chart.end(); ++p_iter) {
2605: const ALECompat::Mesh::real_section_type::index_type& idx = atlas->restrictPoint(patch, *p_iter)[0];
2607: // Map local indices to global indices
2608: ExpandInterval(idx, localIndices, localIndx);
2609: ExpandInterval(index_type(idx.prefix, globalOrder->getIndex(*p_iter)), globalIndices, globalIndx);
2610: }
2611: if (localIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of local indices %d, should be %d", localIndx, localSize);
2612: if (globalIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of global indices %d, should be %d", globalIndx, localSize);
2613: if (m->debug()) {
2614: globalOrder->view("Global Order");
2615: for(int i = 0; i < localSize; ++i) {
2616: printf("[%d] localIndex[%d]: %d globalIndex[%d]: %d\n", m->commRank(), i, localIndices[i], i, globalIndices[i]);
2617: }
2618: }
2619: ISCreateGeneral(PETSC_COMM_SELF, localSize, localIndices, &localIS);
2620: ISCreateGeneral(PETSC_COMM_SELF, localSize, globalIndices, &globalIS);
2621: PetscFree(localIndices);
2622: PetscFree(globalIndices);
2623: VecCreateSeqWithArray(PETSC_COMM_SELF, localSize, s->restrict(patch), &localVec);
2624: VecScatterCreate(localVec, localIS, globalVec, globalIS, scatter);
2625: ISDestroy(globalIS);
2626: ISDestroy(localIS);
2627: VecDestroy(localVec);
2628: VecDestroy(globalVec);
2630: return(0);
2631: }
2635: PetscErrorCode MeshCompatGetGlobalScatter(Mesh mesh, VecScatter *scatter)
2636: {
2642: if (!mesh->globalScatter) {
2643: ALE::Obj<ALECompat::Mesh> m;
2645: MeshCompatGetMesh(mesh, m);
2646: MeshCompatCreateGlobalScatter(m, m->getRealSection("default"), &mesh->globalScatter);
2647: }
2648: *scatter = mesh->globalScatter;
2649: return(0);
2650: }
2654: template<typename Atlas>
2655: PetscErrorCode preallocateOperatorCompat(const ALE::Obj<ALECompat::Mesh::topology_type>& topology, const ALE::Obj<Atlas>& atlas, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, Mat A)
2656: {
2657: typedef ALECompat::New::NumberingFactory<ALECompat::Mesh::topology_type> NumberingFactory;
2658: const ALE::Obj<ALECompat::Mesh::sieve_type> adjGraph = new ALECompat::Mesh::sieve_type(topology->comm(), topology->debug());
2659: const ALE::Obj<ALECompat::Mesh::topology_type> adjTopology = new ALECompat::Mesh::topology_type(topology->comm(), topology->debug());
2660: const ALECompat::Mesh::real_section_type::patch_type patch = 0;
2661: const ALE::Obj<ALECompat::Mesh::sieve_type>& sieve = topology->getPatch(patch);
2662: PetscInt numLocalRows, firstRow;
2663: PetscInt *dnz, *onz;
2667: adjTopology->setPatch(patch, adjGraph);
2668: numLocalRows = globalOrder->getLocalSize();
2669: firstRow = globalOrder->getGlobalOffsets()[topology->commRank()];
2670: PetscMalloc2(numLocalRows, PetscInt, &dnz, numLocalRows, PetscInt, &onz);
2671: /* Create local adjacency graph */
2672: /* In general, we need to get FIAT info that attaches dual basis vectors to sieve points */
2673: const ALECompat::Mesh::real_section_type::atlas_type::chart_type& chart = atlas->getPatch(patch);
2675: for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2676: const ALECompat::Mesh::real_section_type::atlas_type::point_type& point = *c_iter;
2678: adjGraph->addCone(sieve->cone(sieve->support(point)), point);
2679: }
2680: /* Distribute adjacency graph */
2681: topology->constructOverlap(patch);
2682: const Obj<ALECompat::Mesh::send_overlap_type>& vertexSendOverlap = topology->getSendOverlap();
2683: const Obj<ALECompat::Mesh::recv_overlap_type>& vertexRecvOverlap = topology->getRecvOverlap();
2684: const Obj<ALECompat::Mesh::send_overlap_type> nbrSendOverlap = new ALECompat::Mesh::send_overlap_type(topology->comm(), topology->debug());
2685: const Obj<ALECompat::Mesh::recv_overlap_type> nbrRecvOverlap = new ALECompat::Mesh::recv_overlap_type(topology->comm(), topology->debug());
2686: const Obj<ALECompat::Mesh::send_section_type> sendSection = new ALECompat::Mesh::send_section_type(topology->comm(), topology->debug());
2687: const Obj<ALECompat::Mesh::recv_section_type> recvSection = new ALECompat::Mesh::recv_section_type(topology->comm(), sendSection->getTag(), topology->debug());
2689: ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::coneCompletion(vertexSendOverlap, vertexRecvOverlap, adjTopology, sendSection, recvSection);
2690: /* Distribute indices for new points */
2691: ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::updateOverlap(sendSection, recvSection, nbrSendOverlap, nbrRecvOverlap);
2692: NumberingFactory::singleton(topology->debug())->completeOrder(globalOrder, nbrSendOverlap, nbrRecvOverlap, patch, true);
2693: /* Read out adjacency graph */
2694: const ALE::Obj<ALECompat::Mesh::sieve_type> graph = adjTopology->getPatch(patch);
2696: PetscMemzero(dnz, numLocalRows * sizeof(PetscInt));
2697: PetscMemzero(onz, numLocalRows * sizeof(PetscInt));
2698: for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2699: const ALECompat::Mesh::real_section_type::atlas_type::point_type& point = *c_iter;
2701: if (globalOrder->isLocal(point)) {
2702: const ALE::Obj<ALECompat::Mesh::sieve_type::traits::coneSequence>& adj = graph->cone(point);
2703: const ALECompat::Mesh::order_type::value_type& rIdx = globalOrder->restrictPoint(patch, point)[0];
2704: const int row = rIdx.prefix;
2705: const int rSize = rIdx.index;
2707: for(ALECompat::Mesh::sieve_type::traits::coneSequence::iterator v_iter = adj->begin(); v_iter != adj->end(); ++v_iter) {
2708: const ALECompat::Mesh::real_section_type::atlas_type::point_type& neighbor = *v_iter;
2709: const ALECompat::Mesh::order_type::value_type& cIdx = globalOrder->restrictPoint(patch, neighbor)[0];
2710: const int& cSize = cIdx.index;
2712: if (cSize > 0) {
2713: if (globalOrder->isLocal(neighbor)) {
2714: for(int r = 0; r < rSize; ++r) {dnz[row - firstRow + r] += cSize;}
2715: } else {
2716: for(int r = 0; r < rSize; ++r) {onz[row - firstRow + r] += cSize;}
2717: }
2718: }
2719: }
2720: }
2721: }
2722: if (topology->debug()) {
2723: int rank = topology->commRank();
2724: for(int r = 0; r < numLocalRows; r++) {
2725: std::cout << "["<<rank<<"]: dnz["<<r<<"]: " << dnz[r] << " onz["<<r<<"]: " << onz[r] << std::endl;
2726: }
2727: }
2728: MatSeqAIJSetPreallocation(A, 0, dnz);
2729: MatMPIAIJSetPreallocation(A, 0, dnz, 0, onz);
2730: PetscFree2(dnz, onz);
2731: MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);
2732: return(0);
2733: }
2737: PetscErrorCode preallocateMatrixCompat(const ALE::Obj<ALECompat::Mesh::topology_type>& topology, const ALE::Obj<ALECompat::Mesh::real_section_type::atlas_type>& atlas, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, Mat A)
2738: {
2739: return preallocateOperatorCompat(topology, atlas, globalOrder, A);
2740: }
2744: PetscErrorCode updateOperatorCompat(Mat A, const ALE::Obj<ALECompat::Mesh::real_section_type>& section, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, const ALECompat::Mesh::point_type& e, PetscScalar array[], InsertMode mode)
2745: {
2746: ALECompat::Mesh::real_section_type::patch_type patch = 0;
2747: static PetscInt indicesSize = 0;
2748: static PetscInt *indices = NULL;
2749: PetscInt numIndices = 0;
2750: PetscErrorCode ierr;
2753: const ALE::Obj<ALECompat::Mesh::real_section_type::IndexArray> intervals = section->getIndices(patch, e, globalOrder);
2756: if (section->debug()) {printf("[%d]mat for element %d\n", section->commRank(), e);}
2757: for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_iter = intervals->begin(); i_iter != intervals->end(); ++i_iter) {
2758: numIndices += std::abs(i_iter->prefix);
2759: if (section->debug()) {
2760: printf("[%d]mat interval (%d, %d)\n", section->commRank(), i_iter->prefix, i_iter->index);
2761: }
2762: }
2763: if (indicesSize && (indicesSize != numIndices)) {
2764: PetscFree(indices);
2765: indices = NULL;
2766: }
2767: if (!indices) {
2768: indicesSize = numIndices;
2769: PetscMalloc(indicesSize * sizeof(PetscInt), &indices);
2770: }
2771: ExpandIntervals(intervals, indices);
2772: if (section->debug()) {
2773: for(int i = 0; i < numIndices; i++) {
2774: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2775: }
2776: for(int i = 0; i < numIndices; i++) {
2777: printf("[%d]", section->commRank());
2778: for(int j = 0; j < numIndices; j++) {
2779: printf(" %g", array[i*numIndices+j]);
2780: }
2781: printf("\n");
2782: }
2783: }
2784: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
2785: if (ierr) {
2786: printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
2787: for(int i = 0; i < numIndices; i++) {
2788: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2789: }
2790:
2791: }
2793: return(0);
2794: }
2798: /*@C
2799: MeshCompatCreatePyLith - Create a Mesh from PyLith files.
2801: Not Collective
2803: Input Parameters:
2804: + dim - The topological mesh dimension
2805: . baseFilename - The basename for mesh files
2806: . zeroBase - Use 0 to start numbering
2807: - interpolate - The flag for mesh interpolation
2809: Output Parameter:
2810: . mesh - The Mesh object
2812: Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2813: developing for that tool.
2815: Level: developer
2817: .keywords: mesh, PCICE
2818: .seealso: MeshCreate()
2819: @*/
2820: PetscErrorCode MeshCompatCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
2821: {
2822: ALE::Obj<ALECompat::Mesh> m;
2823: PetscInt debug = 0;
2824: PetscTruth flag;
2825: PetscErrorCode ierr;
2828: MeshCreate(comm, mesh);
2829: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
2830: try {
2831: m = ALECompat::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
2832: } catch(ALE::Exception e) {
2833: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
2834: }
2835: MeshCompatSetMesh(*mesh, m);
2836: return(0);
2837: }