Actual source code: mesh.c
1:
2: #include private/meshimpl.h
3: #include <Distribution.hh>
4: #include <Generator.hh>
5: #include src/dm/mesh/meshvtk.h
6: #include src/dm/mesh/meshpcice.h
7: #include src/dm/mesh/meshpylith.h
9: /* Logging support */
10: PetscCookie MESH_COOKIE = 0;
11: PetscEvent Mesh_View = 0, Mesh_GetGlobalScatter = 0, Mesh_restrictVector = 0, Mesh_assembleVector = 0,
12: Mesh_assembleVectorComplete = 0, Mesh_assembleMatrix = 0, Mesh_updateOperator = 0;
14: PetscTruth MeshRegisterAllCalled = PETSC_FALSE;
15: PetscFList MeshList;
17: EXTERN PetscErrorCode MeshView_Mesh(Mesh, PetscViewer);
18: EXTERN PetscErrorCode MeshRefine_Mesh(Mesh, MPI_Comm, Mesh *);
19: EXTERN PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh, int, Mesh **);
20: EXTERN PetscErrorCode MeshGetInterpolation_Mesh(Mesh, Mesh, Mat *, Vec *);
22: EXTERN PetscErrorCode updateOperatorCompat(Mat, const ALE::Obj<ALECompat::Mesh::real_section_type>&, const ALE::Obj<ALECompat::Mesh::order_type>&, const ALECompat::Mesh::point_type&, PetscScalar[], InsertMode);
27: /*
28: Private routine to delete internal tag storage when a communicator is freed.
30: This is called by MPI, not by users.
34: we do not use PetscFree() since it is unsafe after PetscFinalize()
35: */
36: PetscMPIInt Mesh_DelTag(MPI_Comm comm,PetscMPIInt keyval,void* attr_val,void* extra_state)
37: {
38: free(attr_val);
39: return(MPI_SUCCESS);
40: }
45: PetscErrorCode MeshFinalize()
46: {
48: ALE::Mesh::NumberingFactory::singleton(0, 0, true);
49: return(0);
50: }
54: PetscErrorCode MeshView_Sieve_Ascii(const ALE::Obj<ALE::Mesh>& mesh, PetscViewer viewer)
55: {
56: PetscViewerFormat format;
57: PetscErrorCode ierr;
60: PetscViewerGetFormat(viewer, &format);
61: if (format == PETSC_VIEWER_ASCII_VTK) {
62: VTKViewer::writeHeader(viewer);
63: VTKViewer::writeVertices(mesh, viewer);
64: VTKViewer::writeElements(mesh, viewer);
65: } else if (format == PETSC_VIEWER_ASCII_PYLITH) {
66: char *filename;
67: char connectFilename[2048];
68: char coordFilename[2048];
70: PetscViewerFileGetName(viewer, &filename);
71: PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
72: PetscStrcpy(connectFilename, filename);
73: PetscStrcat(connectFilename, ".connect");
74: PetscViewerFileSetName(viewer, connectFilename);
75: ALE::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
76: PetscStrcpy(coordFilename, filename);
77: PetscStrcat(coordFilename, ".coord");
78: PetscViewerFileSetName(viewer, coordFilename);
79: ALE::PyLith::Viewer::writeVertices(mesh, viewer);
80: PetscViewerFileSetMode(viewer, FILE_MODE_READ);
81: PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
82: if (PetscExceptionValue(ierr)) {
83: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
84: } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
85: 0;
86: }
87:
88: } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
89: PetscViewer connectViewer, coordViewer;
90: char *filename;
91: char localFilename[2048];
92: int rank = mesh->commRank();
94: PetscViewerFileGetName(viewer, &filename);
96: sprintf(localFilename, "%s.%d.connect", filename, rank);
97: PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
98: PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
99: PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
100: PetscViewerFileSetName(connectViewer, localFilename);
101: ALE::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
102: PetscViewerDestroy(connectViewer);
104: sprintf(localFilename, "%s.%d.coord", filename, rank);
105: PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
106: PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
107: PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
108: PetscViewerFileSetName(coordViewer, localFilename);
109: ALE::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
110: PetscViewerDestroy(coordViewer);
111: } else if (format == PETSC_VIEWER_ASCII_PCICE) {
112: char *filename;
113: char coordFilename[2048];
114: PetscTruth isConnect;
115: size_t len;
117: PetscViewerFileGetName(viewer, &filename);
118: PetscStrlen(filename, &len);
119: PetscStrcmp(&(filename[len-5]), ".lcon", &isConnect);
120: if (!isConnect) {
121: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid element connectivity filename: %s", filename);
122: }
123: ALE::PCICE::Viewer::writeElements(mesh, viewer);
124: PetscStrncpy(coordFilename, filename, len-5);
125: coordFilename[len-5] = '\0';
126: PetscStrcat(coordFilename, ".nodes");
127: PetscViewerFileSetName(viewer, coordFilename);
128: ALE::PCICE::Viewer::writeVertices(mesh, viewer);
129: } else {
130: int dim = mesh->getDimension();
132: PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
133: for(int d = 0; d <= dim; d++) {
134: // FIX: Need to globalize
135: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->depthStratum(d)->size(), d);
136: }
137: }
138: PetscViewerFlush(viewer);
139: return(0);
140: }
144: PetscErrorCode MeshCompatView_Sieve_Ascii(const ALE::Obj<ALECompat::Mesh>& mesh, PetscViewer viewer)
145: {
146: PetscViewerFormat format;
147: PetscErrorCode ierr;
150: PetscViewerGetFormat(viewer, &format);
151: if (format == PETSC_VIEWER_ASCII_PYLITH) {
152: char *filename;
153: char connectFilename[2048];
154: char coordFilename[2048];
156: PetscViewerFileGetName(viewer, &filename);
157: PetscViewerFileSetMode(viewer, FILE_MODE_WRITE);
158: PetscStrcpy(connectFilename, filename);
159: PetscStrcat(connectFilename, ".connect");
160: PetscViewerFileSetName(viewer, connectFilename);
161: ALECompat::PyLith::Viewer::writeElements(mesh, mesh->getIntSection("material"), viewer);
162: PetscStrcpy(coordFilename, filename);
163: PetscStrcat(coordFilename, ".coord");
164: PetscViewerFileSetName(viewer, coordFilename);
165: ALECompat::PyLith::Viewer::writeVertices(mesh, viewer);
166: PetscViewerFileSetMode(viewer, FILE_MODE_READ);
167: PetscExceptionTry1(PetscViewerFileSetName(viewer, filename), PETSC_ERR_FILE_OPEN);
168: if (PetscExceptionValue(ierr)) {
169: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
170: } else if (PetscExceptionCaught(ierr, PETSC_ERR_FILE_OPEN)) {
171: 0;
172: }
173:
174: } else if (format == PETSC_VIEWER_ASCII_PYLITH_LOCAL) {
175: PetscViewer connectViewer, coordViewer;
176: char *filename;
177: char localFilename[2048];
178: int rank = mesh->commRank();
180: PetscViewerFileGetName(viewer, &filename);
182: sprintf(localFilename, "%s.%d.connect", filename, rank);
183: PetscViewerCreate(PETSC_COMM_SELF, &connectViewer);
184: PetscViewerSetType(connectViewer, PETSC_VIEWER_ASCII);
185: PetscViewerSetFormat(connectViewer, PETSC_VIEWER_ASCII_PYLITH);
186: PetscViewerFileSetName(connectViewer, localFilename);
187: ALECompat::PyLith::Viewer::writeElementsLocal(mesh, mesh->getIntSection("material"), connectViewer);
188: PetscViewerDestroy(connectViewer);
190: sprintf(localFilename, "%s.%d.coord", filename, rank);
191: PetscViewerCreate(PETSC_COMM_SELF, &coordViewer);
192: PetscViewerSetType(coordViewer, PETSC_VIEWER_ASCII);
193: PetscViewerSetFormat(coordViewer, PETSC_VIEWER_ASCII_PYLITH);
194: PetscViewerFileSetName(coordViewer, localFilename);
195: ALECompat::PyLith::Viewer::writeVerticesLocal(mesh, coordViewer);
196: PetscViewerDestroy(coordViewer);
198: if (mesh->hasPairSection("split")) {
199: PetscViewer splitViewer;
201: sprintf(localFilename, "%s.%d.split", filename, rank);
202: PetscViewerCreate(PETSC_COMM_SELF, &splitViewer);
203: PetscViewerSetType(splitViewer, PETSC_VIEWER_ASCII);
204: PetscViewerSetFormat(splitViewer, PETSC_VIEWER_ASCII_PYLITH);
205: PetscViewerFileSetName(splitViewer, localFilename);
206: ALECompat::PyLith::Viewer::writeSplitLocal(mesh, mesh->getPairSection("split"), splitViewer);
207: PetscViewerDestroy(splitViewer);
208: }
210: if (mesh->hasRealSection("traction")) {
211: PetscViewer tractionViewer;
213: sprintf(localFilename, "%s.%d.traction", filename, rank);
214: PetscViewerCreate(PETSC_COMM_SELF, &tractionViewer);
215: PetscViewerSetType(tractionViewer, PETSC_VIEWER_ASCII);
216: PetscViewerSetFormat(tractionViewer, PETSC_VIEWER_ASCII_PYLITH);
217: PetscViewerFileSetName(tractionViewer, localFilename);
218: ALECompat::PyLith::Viewer::writeTractionsLocal(mesh, mesh->getRealSection("traction"), tractionViewer);
219: PetscViewerDestroy(tractionViewer);
220: }
221: } else {
222: int dim = mesh->getDimension();
224: PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
225: for(int d = 0; d <= dim; d++) {
226: // FIX: Need to globalize
227: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->getTopology()->depthStratum(0, d)->size(), d);
228: }
229: }
230: PetscViewerFlush(viewer);
231: return(0);
232: }
236: PetscErrorCode MeshView_Sieve(const ALE::Obj<ALE::Mesh>& mesh, PetscViewer viewer)
237: {
238: PetscTruth iascii, isbinary, isdraw;
242: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_ASCII, &iascii);
243: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_BINARY, &isbinary);
244: PetscTypeCompare((PetscObject) viewer, PETSC_VIEWER_DRAW, &isdraw);
246: if (iascii){
247: MeshView_Sieve_Ascii(mesh, viewer);
248: } else if (isbinary) {
249: SETERRQ(PETSC_ERR_SUP, "Binary viewer not implemented for Mesh");
250: } else if (isdraw){
251: SETERRQ(PETSC_ERR_SUP, "Draw viewer not implemented for Mesh");
252: } else {
253: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
254: }
255: return(0);
256: }
260: PetscErrorCode MeshView_Mesh(Mesh mesh, PetscViewer viewer)
261: {
265: if (!mesh->mcompat.isNull()) {
266: MeshCompatView_Sieve_Ascii(mesh->mcompat, viewer);
267: } else {
268: MeshView_Sieve(mesh->m, viewer);
269: }
270: return(0);
271: }
275: /*@C
276: MeshView - Views a Mesh object.
278: Collective on Mesh
280: Input Parameters:
281: + mesh - the mesh
282: - viewer - an optional visualization context
284: Notes:
285: The available visualization contexts include
286: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
287: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
288: output where only the first processor opens
289: the file. All other processors send their
290: data to the first processor to print.
292: You can change the format the mesh is printed using the
293: option PetscViewerSetFormat().
295: The user can open alternative visualization contexts with
296: + PetscViewerASCIIOpen() - Outputs mesh to a specified file
297: . PetscViewerBinaryOpen() - Outputs mesh in binary to a
298: specified file; corresponding input uses MeshLoad()
299: . PetscViewerDrawOpen() - Outputs mesh to an X window display
301: The user can call PetscViewerSetFormat() to specify the output
302: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
303: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
304: + PETSC_VIEWER_ASCII_DEFAULT - default, prints mesh information
305: - PETSC_VIEWER_ASCII_VTK - outputs a VTK file describing the mesh
307: Level: beginner
309: Concepts: mesh^printing
310: Concepts: mesh^saving to disk
312: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerBinaryOpen(),
313: MeshLoad(), PetscViewerCreate()
314: @*/
315: PetscErrorCode MeshView(Mesh mesh, PetscViewer viewer)
316: {
322: if (!viewer) {
323: PetscViewerASCIIGetStdout(mesh->comm,&viewer);
324: }
329: (*mesh->ops->view)(mesh, viewer);
331: return(0);
332: }
336: /*@C
337: MeshLoad - Create a mesh topology from the saved data in a viewer.
339: Collective on Viewer
341: Input Parameter:
342: . viewer - The viewer containing the data
344: Output Parameters:
345: . mesh - the mesh object
347: Level: advanced
349: .seealso MeshView()
351: @*/
352: PetscErrorCode MeshLoad(PetscViewer viewer, Mesh *mesh)
353: {
354: SETERRQ(PETSC_ERR_SUP, "");
355: }
359: /*@C
360: MeshGetMesh - Gets the internal mesh object
362: Not collective
364: Input Parameter:
365: . mesh - the mesh object
367: Output Parameter:
368: . m - the internal mesh object
369:
370: Level: advanced
372: .seealso MeshCreate(), MeshSetMesh()
374: @*/
375: PetscErrorCode MeshGetMesh(Mesh mesh, ALE::Obj<ALE::Mesh>& m)
376: {
379: m = mesh->m;
380: return(0);
381: }
385: /*@C
386: MeshSetMesh - Sets the internal mesh object
388: Not collective
390: Input Parameters:
391: + mesh - the mesh object
392: - m - the internal mesh object
393:
394: Level: advanced
396: .seealso MeshCreate(), MeshGetMesh()
398: @*/
399: PetscErrorCode MeshSetMesh(Mesh mesh, const ALE::Obj<ALE::Mesh>& m)
400: {
403: mesh->m = m;
404: return(0);
405: }
409: template<typename Section>
410: PetscErrorCode MeshCreateMatrix(const Obj<ALE::Mesh>& mesh, const Obj<Section>& section, MatType mtype, Mat *J)
411: {
412: const ALE::Obj<typename ALE::Mesh::order_type>& order = mesh->getFactory()->getGlobalOrder(mesh, "default", section);
413: int localSize = order->getLocalSize();
414: int globalSize = order->getGlobalSize();
415: PetscTruth isShell, isBlock, isSeqBlock, isMPIBlock;
419: MatCreate(mesh->comm(), J);
420: MatSetSizes(*J, localSize, localSize, globalSize, globalSize);
421: MatSetType(*J, mtype);
422: MatSetFromOptions(*J);
423: PetscStrcmp(mtype, MATSHELL, &isShell);
424: PetscStrcmp(mtype, MATBAIJ, &isBlock);
425: PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);
426: PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);
427: if (!isShell) {
428: int bs = 1;
430: if (isBlock || isSeqBlock || isMPIBlock) {
431: bs = section->getFiberDimension(*section->getChart().begin());
432: }
433: preallocateOperator(mesh, bs, section->getAtlas(), order, *J);
434: }
435: return(0);
436: }
440: PetscErrorCode MeshCreateMatrix(Mesh mesh, SectionReal section, MatType mtype, Mat *J)
441: {
442: ALE::Obj<ALE::Mesh> m;
443: ALE::Obj<ALE::Mesh::real_section_type> s;
447: MeshGetMesh(mesh, m);
448: SectionRealGetSection(section, s);
449: MeshCreateMatrix(m, s, mtype, J);
450: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
451: return(0);
452: }
456: PetscErrorCode MeshGetVertexMatrix(Mesh mesh, MatType mtype, Mat *J)
457: {
458: SectionReal section;
462: MeshGetVertexSectionReal(mesh, 1, §ion);
463: MeshCreateMatrix(mesh, section, mtype, J);
464: SectionRealDestroy(section);
465: return(0);
466: }
470: /*@C
471: MeshGetMatrix - Creates a matrix with the correct parallel layout required for
472: computing the Jacobian on a function defined using the informatin in Mesh.
474: Collective on Mesh
476: Input Parameter:
477: + mesh - the mesh object
478: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
479: or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).
481: Output Parameters:
482: . J - matrix with the correct nonzero preallocation
483: (obviously without the correct Jacobian values)
485: Level: advanced
487: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
488: do not need to do it yourself.
490: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DASetBlockFills()
492: @*/
493: PetscErrorCode MeshGetMatrix(Mesh mesh, MatType mtype, Mat *J)
494: {
495: ALE::Obj<ALE::Mesh> m;
496: PetscTruth flag;
497: PetscErrorCode ierr;
500: MeshHasSectionReal(mesh, "default", &flag);
501: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
502: MeshGetMesh(mesh, m);
503: MeshCreateMatrix(m, m->getRealSection("default"), mtype, J);
504: PetscObjectCompose((PetscObject) *J, "mesh", (PetscObject) mesh);
505: return(0);
506: }
510: /*@C
511: MeshCreate - Creates a DM object, used to manage data for an unstructured problem
512: described by a Sieve.
514: Collective on MPI_Comm
516: Input Parameter:
517: . comm - the processors that will share the global vector
519: Output Parameters:
520: . mesh - the mesh object
522: Level: advanced
524: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
526: @*/
527: PetscErrorCode MeshCreate(MPI_Comm comm,Mesh *mesh)
528: {
530: Mesh p;
534: *mesh = PETSC_NULL;
535: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
536: DMInitializePackage(PETSC_NULL);
537: #endif
539: PetscHeaderCreate(p,_p_Mesh,struct _MeshOps,MESH_COOKIE,0,"Mesh",comm,MeshDestroy,MeshView);
540: p->ops->view = MeshView_Mesh;
541: p->ops->destroy = PETSC_NULL;
542: p->ops->createglobalvector = MeshCreateGlobalVector;
543: p->ops->getcoloring = PETSC_NULL;
544: p->ops->getmatrix = MeshGetMatrix;
545: p->ops->getinterpolation = MeshGetInterpolation_Mesh;
546: p->ops->getinjection = PETSC_NULL;
547: p->ops->refine = MeshRefine_Mesh;
548: p->ops->coarsen = PETSC_NULL;
549: p->ops->refinehierarchy = PETSC_NULL;
550: p->ops->coarsenhierarchy = MeshCoarsenHierarchy_Mesh;
552: PetscObjectChangeTypeName((PetscObject) p, "sieve");
554: p->m = PETSC_NULL;
555: p->globalScatter = PETSC_NULL;
556: p->lf = PETSC_NULL;
557: p->lj = PETSC_NULL;
558: p->mcompat = PETSC_NULL;
559: p->data = PETSC_NULL;
560: *mesh = p;
561: return(0);
562: }
566: /*@
567: MeshDestroy - Destroys a mesh.
569: Collective on Mesh
571: Input Parameter:
572: . mesh - the mesh object
574: Level: advanced
576: .seealso MeshCreate(), MeshCreateGlobalVector(), MeshGetGlobalIndices()
577: @*/
578: PetscErrorCode MeshDestroy(Mesh mesh)
579: {
580: PetscErrorCode ierr;
583: if (--mesh->refct > 0) return(0);
584: if (mesh->globalScatter) {VecScatterDestroy(mesh->globalScatter);}
585: mesh->m = PETSC_NULL;
586: PetscHeaderDestroy(mesh);
587: return(0);
588: }
592: /*@C
593: MeshSetType - Sets the Mesh type
595: Collective on Mesh
597: Input Parameters:
598: + mesh - the Mesh context
599: - type - the type
601: Options Database Key:
602: . -mesh_type <method> - Sets the type; use -help for a list
603: of available types (for instance, cartesian or sieve)
605: Notes:
606: See "petsc/include/petscmesh.h" for available types (for instance,
607: MESHCARTESIAN or MESHSIEVE).
609: Level: intermediate
611: .keywords: Mesh, set, typr
612: .seealso: MeshGetType(), MeshType
613: @*/
614: PetscErrorCode MeshSetType(Mesh mesh, MeshType type)
615: {
616: PetscErrorCode ierr,(*r)(Mesh);
617: PetscTruth match;
623: PetscTypeCompare((PetscObject)mesh,type,&match);
624: if (match) return(0);
626: PetscFListFind(MeshList,mesh->comm,type,(void (**)(void)) &r);
627: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested Mesh type %s",type);
628: /* Destroy the previous private Mesh context */
629: if (mesh->ops->destroy) { (*mesh->ops->destroy)(mesh); }
630: /* Reinitialize function pointers in MeshOps structure */
631: PetscMemzero(mesh->ops, sizeof(struct _MeshOps));
632: /* Call the MeshCreate_XXX routine for this particular mesh */
633: (*r)(mesh);
634: PetscObjectChangeTypeName((PetscObject) mesh, type);
635: return(0);
636: }
640: /*@C
641: MeshGetType - Gets the Mesh type as a string from the Mesh object.
643: Not Collective
645: Input Parameter:
646: . mesh - Mesh context
648: Output Parameter:
649: . name - name of Mesh type
651: Level: intermediate
653: .keywords: Mesh, get, type
654: .seealso: MeshSetType()
655: @*/
656: PetscErrorCode MeshGetType(Mesh mesh,MeshType *type)
657: {
661: *type = mesh->type_name;
662: return(0);
663: }
667: /*@C
668: MeshRegister - See MeshRegisterDynamic()
670: Level: advanced
671: @*/
672: PetscErrorCode MeshRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mesh))
673: {
675: char fullname[PETSC_MAX_PATH_LEN];
678: PetscFListConcat(path,name,fullname);
679: PetscFListAdd(&MeshList,sname,fullname,(void (*)(void))function);
680: return(0);
681: }
684: EXTERN PetscErrorCode MeshCreate_Cartesian(Mesh);
689: /*@C
690: MeshRegisterAll - Registers all of the Mesh types in the Mesh package.
692: Not Collective
694: Level: advanced
696: .keywords: Mesh, register, all
697: .seealso: MeshRegisterDestroy()
698: @*/
699: PetscErrorCode MeshRegisterAll(const char path[])
700: {
704: MeshRegisterAllCalled = PETSC_TRUE;
706: MeshRegisterDynamic(MESHCARTESIAN, path, "MeshCreate_Cartesian", MeshCreate_Cartesian);
707: return(0);
708: }
712: /*@
713: MeshRegisterDestroy - Frees the list of Mesh types that were
714: registered by MeshRegister().
716: Not Collective
718: Level: advanced
720: .keywords: Mesh, register, destroy
721: .seealso: MeshRegister(), MeshRegisterAll()
722: @*/
723: PetscErrorCode MeshRegisterDestroy(void)
724: {
728: PetscFListDestroy(&MeshList);
729: MeshRegisterAllCalled = PETSC_FALSE;
730: return(0);
731: }
735: /*@C
736: MeshCreateGlobalVector - Creates a vector of the correct size to be gathered into
737: by the mesh.
739: Collective on Mesh
741: Input Parameter:
742: . mesh - the mesh object
744: Output Parameters:
745: . gvec - the global vector
747: Level: advanced
749: Notes: Once this has been created you cannot add additional arrays or vectors to be packed.
751: .seealso MeshDestroy(), MeshCreate(), MeshGetGlobalIndices()
753: @*/
754: PetscErrorCode MeshCreateGlobalVector(Mesh mesh, Vec *gvec)
755: {
756: ALE::Obj<ALE::Mesh> m;
757: PetscTruth flag;
761: MeshHasSectionReal(mesh, "default", &flag);
762: if (!flag) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
763: MeshGetMesh(mesh, m);
764: const ALE::Obj<ALE::Mesh::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));
766: VecCreate(m->comm(), gvec);
767: VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
768: VecSetFromOptions(*gvec);
769: return(0);
770: }
774: /*@C
775: MeshGetGlobalIndices - Gets the global indices for all the local entries
777: Collective on Mesh
779: Input Parameter:
780: . mesh - the mesh object
782: Output Parameters:
783: . idx - the individual indices for each packed vector/array
784:
785: Level: advanced
787: Notes:
788: The idx parameters should be freed by the calling routine with PetscFree()
790: .seealso MeshDestroy(), MeshCreateGlobalVector(), MeshCreate()
792: @*/
793: PetscErrorCode MeshGetGlobalIndices(Mesh mesh,PetscInt *idx[])
794: {
795: SETERRQ(PETSC_ERR_SUP, "");
796: }
800: PetscErrorCode MeshCreateGlobalScatter(Mesh mesh, SectionReal section, VecScatter *scatter)
801: {
802: ALE::Obj<ALE::Mesh> m;
803: ALE::Obj<ALE::Mesh::real_section_type> s;
807: MeshGetMesh(mesh, m);
808: SectionRealGetSection(section, s);
809: MeshCreateGlobalScatter(m, s, scatter);
810: return(0);
811: }
815: template<typename Section>
816: PetscErrorCode MeshCreateGlobalScatter(const ALE::Obj<ALE::Mesh>& m, const ALE::Obj<Section>& s, VecScatter *scatter)
817: {
818: typedef ALE::Mesh::real_section_type::index_type index_type;
823: const ALE::Mesh::real_section_type::chart_type& chart = s->getChart();
824: const ALE::Obj<ALE::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, s->getName(), s);
825: int *localIndices, *globalIndices;
826: int localSize = s->size();
827: int localIndx = 0, globalIndx = 0;
828: Vec globalVec, localVec;
829: IS localIS, globalIS;
831: VecCreate(m->comm(), &globalVec);
832: VecSetSizes(globalVec, globalOrder->getLocalSize(), PETSC_DETERMINE);
833: VecSetFromOptions(globalVec);
834: // Loop over all local points
835: PetscMalloc(localSize*sizeof(int), &localIndices);
836: PetscMalloc(localSize*sizeof(int), &globalIndices);
837: for(ALE::Mesh::real_section_type::chart_type::const_iterator p_iter = chart.begin(); p_iter != chart.end(); ++p_iter) {
838: // Map local indices to global indices
839: s->getIndices(*p_iter, localIndices, &localIndx, 0, true);
840: s->getIndices(*p_iter, globalOrder, globalIndices, &globalIndx, 0, true);
841: }
842: if (localIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of local indices %d, should be %d", localIndx, localSize);
843: if (globalIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of global indices %d, should be %d", globalIndx, localSize);
844: if (m->debug()) {
845: globalOrder->view("Global Order");
846: for(int i = 0; i < localSize; ++i) {
847: printf("[%d] localIndex[%d]: %d globalIndex[%d]: %d\n", m->commRank(), i, localIndices[i], i, globalIndices[i]);
848: }
849: }
850: ISCreateGeneral(PETSC_COMM_SELF, localSize, localIndices, &localIS);
851: ISCreateGeneral(PETSC_COMM_SELF, localSize, globalIndices, &globalIS);
852: PetscFree(localIndices);
853: PetscFree(globalIndices);
854: VecCreateSeqWithArray(PETSC_COMM_SELF, s->sizeWithBC(), s->restrict(), &localVec);
855: VecScatterCreate(localVec, localIS, globalVec, globalIS, scatter);
856: ISDestroy(globalIS);
857: ISDestroy(localIS);
858: VecDestroy(localVec);
859: VecDestroy(globalVec);
861: return(0);
862: }
866: PetscErrorCode MeshGetGlobalScatter(Mesh mesh, VecScatter *scatter)
867: {
873: if (!mesh->globalScatter) {
874: SectionReal section;
876: MeshGetSectionReal(mesh, "default", §ion);
877: MeshCreateGlobalScatter(mesh, section, &mesh->globalScatter);
878: SectionRealDestroy(section);
879: }
880: *scatter = mesh->globalScatter;
881: return(0);
882: }
886: PetscErrorCode MeshSetLocalFunction(Mesh mesh, PetscErrorCode (*lf)(Mesh, SectionReal, SectionReal, void *))
887: {
890: mesh->lf = lf;
891: return(0);
892: }
896: PetscErrorCode MeshSetLocalJacobian(Mesh mesh, PetscErrorCode (*lj)(Mesh, SectionReal, Mat, void *))
897: {
900: mesh->lj = lj;
901: return(0);
902: }
906: PetscErrorCode MeshFormFunction(Mesh mesh, SectionReal X, SectionReal F, void *ctx)
907: {
914: if (mesh->lf) {
915: (*mesh->lf)(mesh, X, F, ctx);
916: }
917: return(0);
918: }
922: PetscErrorCode MeshFormJacobian(Mesh mesh, SectionReal X, Mat J, void *ctx)
923: {
930: if (mesh->lj) {
931: (*mesh->lj)(mesh, X, J, ctx);
932: }
933: return(0);
934: }
938: // Here we assume:
939: // - Assumes 3D and tetrahedron
940: // - The section takes values on vertices and is P1
941: // - Points have the same dimension as the mesh
942: // - All values have the same dimension
943: PetscErrorCode MeshInterpolatePoints(Mesh mesh, SectionReal section, int numPoints, double *points, double **values)
944: {
945: Obj<ALE::Mesh> m;
946: Obj<ALE::Mesh::real_section_type> s;
947: double *v0, *J, *invJ, detJ;
951: MeshGetMesh(mesh, m);
952: SectionRealGetSection(section, s);
953: const Obj<ALE::Mesh::real_section_type>& coordinates = m->getRealSection("coordinates");
954: int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
955: int dim = s->getFiberDimension(*m->depthStratum(0)->begin());
957: PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
958: PetscMalloc(numPoints*dim * sizeof(double), &values);
959: for(int p = 0; p < numPoints; p++) {
960: double *point = &points[p*embedDim];
961: ALE::Mesh::point_type e = m->locatePoint(point);
962: const ALE::Mesh::real_section_type::value_type *coeff = s->restrictPoint(e);
964: m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
965: double xi = (invJ[0*embedDim+0]*(point[0] - v0[0]) + invJ[0*embedDim+1]*(point[1] - v0[1]) + invJ[0*embedDim+2]*(point[2] - v0[2]))*0.5;
966: double eta = (invJ[1*embedDim+0]*(point[0] - v0[0]) + invJ[1*embedDim+1]*(point[1] - v0[1]) + invJ[1*embedDim+2]*(point[2] - v0[2]))*0.5;
967: double zeta = (invJ[2*embedDim+0]*(point[0] - v0[0]) + invJ[2*embedDim+1]*(point[1] - v0[1]) + invJ[2*embedDim+2]*(point[2] - v0[2]))*0.5;
969: for(int d = 0; d < dim; d++) {
970: (*values)[p*dim+d] = coeff[0*dim+d]*(1 - xi - eta - zeta) + coeff[1*dim+d]*xi + coeff[2*dim+d]*eta + coeff[3*dim+d]*zeta;
971: }
972: }
973: PetscFree3(v0, J, invJ);
974: return(0);
975: }
979: /*@
980: MeshGetMaximumDegree - Return the maximum degree of any mesh vertex
982: Collective on mesh
984: Input Parameter:
985: . mesh - The Mesh
987: Output Parameter:
988: . maxDegree - The maximum number of edges at any vertex
990: Level: beginner
992: .seealso: MeshCreate()
993: @*/
994: PetscErrorCode MeshGetMaximumDegree(Mesh mesh, PetscInt *maxDegree)
995: {
996: Obj<ALE::Mesh> m;
1000: MeshGetMesh(mesh, m);
1001: const ALE::Obj<ALE::Mesh::label_sequence>& vertices = m->depthStratum(0);
1002: const ALE::Obj<ALE::Mesh::sieve_type>& sieve = m->getSieve();
1003: PetscInt maxDeg = -1;
1005: for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
1006: maxDeg = PetscMax(maxDeg, (PetscInt) sieve->support(*v_iter)->size());
1007: }
1008: *maxDegree = maxDeg;
1009: return(0);
1010: }
1012: EXTERN PetscErrorCode assembleFullField(VecScatter, Vec, Vec, InsertMode);
1016: /*@C
1017: restrictVector - Insert values from a global vector into a local ghosted vector
1019: Collective on g
1021: Input Parameters:
1022: + g - The global vector
1023: . l - The local vector
1024: - mode - either ADD_VALUES or INSERT_VALUES, where
1025: ADD_VALUES adds values to any existing entries, and
1026: INSERT_VALUES replaces existing entries with new values
1028: Level: beginner
1030: .seealso: MatSetOption()
1031: @*/
1032: PetscErrorCode restrictVector(Vec g, Vec l, InsertMode mode)
1033: {
1034: VecScatter injection;
1039: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1040: if (injection) {
1041: VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
1042: VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
1043: } else {
1044: if (mode == INSERT_VALUES) {
1045: VecCopy(g, l);
1046: } else {
1047: VecAXPY(l, 1.0, g);
1048: }
1049: }
1051: return(0);
1052: }
1056: /*@C
1057: assembleVectorComplete - Insert values from a local ghosted vector into a global vector
1059: Collective on g
1061: Input Parameters:
1062: + g - The global vector
1063: . l - The local vector
1064: - mode - either ADD_VALUES or INSERT_VALUES, where
1065: ADD_VALUES adds values to any existing entries, and
1066: INSERT_VALUES replaces existing entries with new values
1068: Level: beginner
1070: .seealso: MatSetOption()
1071: @*/
1072: PetscErrorCode assembleVectorComplete(Vec g, Vec l, InsertMode mode)
1073: {
1074: VecScatter injection;
1079: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
1080: if (injection) {
1081: VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
1082: VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
1083: } else {
1084: if (mode == INSERT_VALUES) {
1085: VecCopy(l, g);
1086: } else {
1087: VecAXPY(g, 1.0, l);
1088: }
1089: }
1091: return(0);
1092: }
1096: /*@C
1097: assembleVector - Insert values into a vector
1099: Collective on A
1101: Input Parameters:
1102: + b - the vector
1103: . e - The element number
1104: . v - The values
1105: - mode - either ADD_VALUES or INSERT_VALUES, where
1106: ADD_VALUES adds values to any existing entries, and
1107: INSERT_VALUES replaces existing entries with new values
1109: Level: beginner
1111: .seealso: VecSetOption()
1112: @*/
1113: PetscErrorCode assembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
1114: {
1115: Mesh mesh;
1116: ALE::Obj<ALE::Mesh> m;
1117: PetscInt firstElement;
1118: PetscErrorCode ierr;
1122: PetscObjectQuery((PetscObject) b, "mesh", (PetscObject *) &mesh);
1123: MeshGetMesh(mesh, m);
1124: //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
1125: firstElement = 0;
1126: // Must relate b to field
1127: if (mode == INSERT_VALUES) {
1128: m->update(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1129: } else {
1130: m->updateAdd(m->getRealSection(std::string("x")), ALE::Mesh::point_type(e + firstElement), v);
1131: }
1133: return(0);
1134: }
1138: PetscErrorCode updateOperator(Mat A, const ALE::Obj<ALE::Mesh>& m, const ALE::Obj<ALE::Mesh::real_section_type>& section, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, const ALE::Mesh::point_type& e, PetscScalar array[], InsertMode mode)
1139: {
1143: const ALE::Mesh::indices_type indicesBlock = m->getIndices(section, e, globalOrder);
1144: const PetscInt *indices = indicesBlock.first;
1145: const int& numIndices = indicesBlock.second;
1148: if (section->debug()) {
1149: printf("[%d]mat for element %d\n", section->commRank(), e);
1150: for(int i = 0; i < numIndices; i++) {
1151: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1152: }
1153: for(int i = 0; i < numIndices; i++) {
1154: printf("[%d]", section->commRank());
1155: for(int j = 0; j < numIndices; j++) {
1156: printf(" %g", array[i*numIndices+j]);
1157: }
1158: printf("\n");
1159: }
1160: }
1161: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
1162: if (ierr) {
1163: printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
1164: for(int i = 0; i < numIndices; i++) {
1165: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
1166: }
1167:
1168: }
1170: return(0);
1171: }
1175: PetscErrorCode updateOperatorGeneral(Mat A, const ALE::Obj<ALE::Mesh>& rowM, const ALE::Obj<ALE::Mesh::real_section_type>& rowSection, const ALE::Obj<ALE::Mesh::order_type>& rowGlobalOrder, const ALE::Mesh::point_type& rowE, const ALE::Obj<ALE::Mesh>& colM, const ALE::Obj<ALE::Mesh::real_section_type>& colSection, const ALE::Obj<ALE::Mesh::order_type>& colGlobalOrder, const ALE::Mesh::point_type& colE, PetscScalar array[], InsertMode mode)
1176: {
1180: const ALE::Mesh::indices_type rowIndicesBlock = rowM->getIndices(rowSection, rowE, rowGlobalOrder);
1181: const PetscInt *rowIndices = rowIndicesBlock.first;
1182: const int& numRowIndices = rowIndicesBlock.second;
1183: const ALE::Mesh::indices_type colIndicesBlock = colM->getIndices(colSection, colE, colGlobalOrder);
1184: const PetscInt *colIndices = colIndicesBlock.first;
1185: const int& numColIndices = colIndicesBlock.second;
1188: if (rowSection->debug()) {
1189: printf("[%d]mat for elements %d %d\n", rowSection->commRank(), rowE, colE);
1190: for(int i = 0; i < numRowIndices; i++) {
1191: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1192: }
1193: }
1194: if (colSection->debug()) {
1195: for(int i = 0; i < numColIndices; i++) {
1196: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1197: }
1198: for(int i = 0; i < numRowIndices; i++) {
1199: printf("[%d]", rowSection->commRank());
1200: for(int j = 0; j < numColIndices; j++) {
1201: printf(" %g", array[i*numColIndices+j]);
1202: }
1203: printf("\n");
1204: }
1205: }
1206: MatSetValues(A, numRowIndices, rowIndices, numColIndices, colIndices, array, mode);
1207: if (ierr) {
1208: printf("[%d]ERROR in updateOperator: points %d %d\n", colSection->commRank(), rowE, colE);
1209: for(int i = 0; i < numRowIndices; i++) {
1210: printf("[%d]mat row indices[%d] = %d\n", rowSection->commRank(), i, rowIndices[i]);
1211: }
1212: for(int i = 0; i < numColIndices; i++) {
1213: printf("[%d]mat col indices[%d] = %d\n", colSection->commRank(), i, colIndices[i]);
1214: }
1215:
1216: }
1218: return(0);
1219: }
1223: /*@C
1224: assembleMatrix - Insert values into a matrix
1226: Collective on A
1228: Input Parameters:
1229: + A - the matrix
1230: . e - The element number
1231: . v - The values
1232: - mode - either ADD_VALUES or INSERT_VALUES, where
1233: ADD_VALUES adds values to any existing entries, and
1234: INSERT_VALUES replaces existing entries with new values
1236: Level: beginner
1238: .seealso: MatSetOption()
1239: @*/
1240: PetscErrorCode assembleMatrix(Mat A, PetscInt e, PetscScalar v[], InsertMode mode)
1241: {
1242: Mesh mesh;
1247: PetscObjectQuery((PetscObject) A, "mesh", (PetscObject *) &mesh);
1248: try {
1249: if (!mesh->mcompat.isNull()) {
1250: Obj<ALECompat::Mesh> m;
1252: MeshCompatGetMesh(mesh, m);
1253: const ALE::Obj<ALECompat::Mesh::topology_type>& topology = m->getTopology();
1254: const ALE::Obj<ALECompat::Mesh::numbering_type>& cNumbering = m->getFactory()->getLocalNumbering(topology, 0, topology->depth());
1255: const ALE::Obj<ALECompat::Mesh::real_section_type>& s = m->getRealSection("default");
1256: const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(topology, 0, "default", s->getAtlas());
1258: if (m->debug()) {
1259: std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1260: }
1261: updateOperatorCompat(A, s, globalOrder, cNumbering->getPoint(e), v, mode);
1262: } else {
1263: Obj<ALE::Mesh> m;
1265: MeshGetMesh(mesh, m);
1266: const ALE::Obj<ALE::Mesh::numbering_type>& cNumbering = m->getFactory()->getLocalNumbering(m, m->depth());
1267: const ALE::Obj<ALE::Mesh::real_section_type>& s = m->getRealSection("default");
1268: const ALE::Obj<ALE::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, "default", s);
1270: if (m->debug()) {
1271: std::cout << "Assembling matrix for element number " << e << " --> point " << cNumbering->getPoint(e) << std::endl;
1272: }
1273: updateOperator(A, m, s, globalOrder, cNumbering->getPoint(e), v, mode);
1274: }
1275: } catch (ALE::Exception e) {
1276: std::cout << e.msg() << std::endl;
1277: }
1279: return(0);
1280: }
1284: template<typename Atlas>
1285: PetscErrorCode preallocateOperator(const ALE::Obj<ALE::Mesh>& mesh, const int bs, const ALE::Obj<Atlas>& atlas, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, Mat A)
1286: {
1287: typedef ALE::SieveAlg<ALE::Mesh> sieve_alg_type;
1288: MPI_Comm comm = mesh->comm();
1289: const ALE::Obj<ALE::Mesh> adjBundle = new ALE::Mesh(comm, mesh->debug());
1290: const ALE::Obj<ALE::Mesh::sieve_type> adjGraph = new ALE::Mesh::sieve_type(comm, mesh->debug());
1291: PetscInt numLocalRows, firstRow;
1292: PetscInt *dnz, *onz;
1296: adjBundle->setSieve(adjGraph);
1297: numLocalRows = globalOrder->getLocalSize();
1298: firstRow = globalOrder->getGlobalOffsets()[mesh->commRank()];
1299: PetscMalloc2(numLocalRows, PetscInt, &dnz, numLocalRows, PetscInt, &onz);
1300: /* Create local adjacency graph */
1301: /* In general, we need to get FIAT info that attaches dual basis vectors to sieve points */
1302: const typename Atlas::chart_type& chart = atlas->getChart();
1304: for(typename Atlas::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
1305: const Obj<typename sieve_alg_type::supportArray>& star = sieve_alg_type::star(mesh, *c_iter);
1307: for(typename sieve_alg_type::supportArray::const_iterator s_iter = star->begin(); s_iter != star->end(); ++s_iter) {
1308: const Obj<typename sieve_alg_type::coneArray>& closure = sieve_alg_type::closure(mesh, *s_iter);
1310: for(typename sieve_alg_type::coneArray::const_iterator cl_iter = closure->begin(); cl_iter != closure->end(); ++cl_iter) {
1311: adjGraph->addCone(*cl_iter, *c_iter);
1312: }
1313: }
1314: }
1315: /* Distribute adjacency graph */
1316: adjBundle->constructOverlap();
1317: typedef typename ALE::Mesh::sieve_type::point_type point_type;
1318: typedef typename ALE::Mesh::send_overlap_type send_overlap_type;
1319: typedef typename ALE::Mesh::recv_overlap_type recv_overlap_type;
1320: typedef typename ALE::Field<send_overlap_type, int, ALE::Section<point_type, point_type> > send_section_type;
1321: typedef typename ALE::Field<recv_overlap_type, int, ALE::Section<point_type, point_type> > recv_section_type;
1322: const Obj<send_overlap_type>& vertexSendOverlap = mesh->getSendOverlap();
1323: const Obj<recv_overlap_type>& vertexRecvOverlap = mesh->getRecvOverlap();
1324: const Obj<send_overlap_type> nbrSendOverlap = new send_overlap_type(comm, mesh->debug());
1325: const Obj<recv_overlap_type> nbrRecvOverlap = new recv_overlap_type(comm, mesh->debug());
1326: const Obj<send_section_type> sendSection = new send_section_type(comm, mesh->debug());
1327: const Obj<recv_section_type> recvSection = new recv_section_type(comm, sendSection->getTag(), mesh->debug());
1329: ALE::Distribution<ALE::Mesh>::coneCompletion(vertexSendOverlap, vertexRecvOverlap, adjBundle, sendSection, recvSection);
1330: /* Distribute indices for new points */
1331: ALE::Distribution<ALE::Mesh>::updateOverlap(sendSection, recvSection, nbrSendOverlap, nbrRecvOverlap);
1332: mesh->getFactory()->completeOrder(globalOrder, nbrSendOverlap, nbrRecvOverlap, true);
1333: /* Read out adjacency graph */
1334: const ALE::Obj<ALE::Mesh::sieve_type> graph = adjBundle->getSieve();
1336: PetscMemzero(dnz, numLocalRows/bs * sizeof(PetscInt));
1337: PetscMemzero(onz, numLocalRows/bs * sizeof(PetscInt));
1338: for(typename Atlas::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
1339: const typename Atlas::point_type& point = *c_iter;
1341: if (globalOrder->isLocal(point)) {
1342: const ALE::Obj<ALE::Mesh::sieve_type::traits::coneSequence>& adj = graph->cone(point);
1343: const ALE::Mesh::order_type::value_type& rIdx = globalOrder->restrictPoint(point)[0];
1344: const int row = rIdx.prefix;
1345: const int rSize = rIdx.index/bs;
1347: if (rSize == 0) continue;
1348: for(ALE::Mesh::sieve_type::traits::coneSequence::iterator v_iter = adj->begin(); v_iter != adj->end(); ++v_iter) {
1349: const ALE::Mesh::point_type& neighbor = *v_iter;
1350: const ALE::Mesh::order_type::value_type& cIdx = globalOrder->restrictPoint(neighbor)[0];
1351: const int& cSize = cIdx.index/bs;
1353: if (cSize > 0) {
1354: if (globalOrder->isLocal(neighbor)) {
1355: for(int r = 0; r < rSize; ++r) {dnz[(row - firstRow)/bs + r] += cSize;}
1356: } else {
1357: for(int r = 0; r < rSize; ++r) {onz[(row - firstRow)/bs + r] += cSize;}
1358: }
1359: }
1360: }
1361: }
1362: }
1363: if (mesh->debug()) {
1364: int rank = mesh->commRank();
1365: for(int r = 0; r < numLocalRows/bs; r++) {
1366: std::cout << "["<<rank<<"]: dnz["<<r<<"]: " << dnz[r] << " onz["<<r<<"]: " << onz[r] << std::endl;
1367: }
1368: }
1369: MatSeqAIJSetPreallocation(A, 0, dnz);
1370: MatMPIAIJSetPreallocation(A, 0, dnz, 0, onz);
1371: MatSeqBAIJSetPreallocation(A, bs, 0, dnz);
1372: MatMPIBAIJSetPreallocation(A, bs, 0, dnz, 0, onz);
1373: PetscFree2(dnz, onz);
1374: MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR);
1375: return(0);
1376: }
1380: PetscErrorCode preallocateMatrix(const ALE::Obj<ALE::Mesh>& mesh, const int bs, const ALE::Obj<ALE::Mesh::real_section_type::atlas_type>& atlas, const ALE::Obj<ALE::Mesh::order_type>& globalOrder, Mat A)
1381: {
1382: return preallocateOperator(mesh, bs, atlas, globalOrder, A);
1383: }
1385: /******************************** C Wrappers **********************************/
1389: PetscErrorCode WriteVTKHeader(PetscViewer viewer)
1390: {
1391: return VTKViewer::writeHeader(viewer);
1392: }
1396: PetscErrorCode WriteVTKVertices(Mesh mesh, PetscViewer viewer)
1397: {
1398: ALE::Obj<ALE::Mesh> m;
1401: MeshGetMesh(mesh, m);
1402: return VTKViewer::writeVertices(m, viewer);
1403: }
1407: PetscErrorCode WriteVTKElements(Mesh mesh, PetscViewer viewer)
1408: {
1409: ALE::Obj<ALE::Mesh> m;
1412: MeshGetMesh(mesh, m);
1413: return VTKViewer::writeElements(m, viewer);
1414: }
1418: PetscErrorCode WritePCICEVertices(Mesh mesh, PetscViewer viewer)
1419: {
1420: ALE::Obj<ALE::Mesh> m;
1423: MeshGetMesh(mesh, m);
1424: return ALE::PCICE::Viewer::writeVertices(m, viewer);
1425: }
1429: PetscErrorCode WritePCICEElements(Mesh mesh, PetscViewer viewer)
1430: {
1431: ALE::Obj<ALE::Mesh> m;
1434: MeshGetMesh(mesh, m);
1435: return ALE::PCICE::Viewer::writeElements(m, viewer);
1436: }
1440: PetscErrorCode WritePCICERestart(Mesh mesh, PetscViewer viewer)
1441: {
1442: ALE::Obj<ALE::Mesh> m;
1445: MeshGetMesh(mesh, m);
1446: return ALE::PCICE::Viewer::writeRestart(m, viewer);
1447: }
1451: /*@C
1452: MeshCreatePCICE - Create a Mesh from PCICE files.
1454: Not Collective
1456: Input Parameters:
1457: + dim - The topological mesh dimension
1458: . coordFilename - The file containing vertex coordinates
1459: . adjFilename - The file containing the vertices for each element
1460: . interpolate - The flag for construction of intermediate elements
1461: . bcFilename - The file containing the boundary topology and conditions
1462: . numBdFaces - The number of boundary faces (or edges)
1463: - numBdVertices - The number of boundary vertices
1465: Output Parameter:
1466: . mesh - The Mesh object
1468: Level: beginner
1470: .keywords: mesh, PCICE
1471: .seealso: MeshCreate()
1472: @*/
1473: PetscErrorCode MeshCreatePCICE(MPI_Comm comm, const int dim, const char coordFilename[], const char adjFilename[], PetscTruth interpolate, const char bcFilename[], Mesh *mesh)
1474: {
1475: ALE::Obj<ALE::Mesh> m;
1476: PetscInt debug = 0;
1477: PetscTruth flag;
1478: PetscErrorCode ierr;
1481: MeshCreate(comm, mesh);
1482: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1483: try {
1484: m = ALE::PCICE::Builder::readMesh(comm, dim, std::string(coordFilename), std::string(adjFilename), false, interpolate, debug);
1485: if (debug) {m->view("Mesh");}
1486: } catch(ALE::Exception e) {
1487: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1488: }
1489: if (bcFilename) {
1490: ALE::PCICE::Builder::readBoundary(m, std::string(bcFilename));
1491: }
1492: MeshSetMesh(*mesh, m);
1493: return(0);
1494: }
1498: /*@C
1499: MeshCreatePyLith - Create a Mesh from PyLith files.
1501: Not Collective
1503: Input Parameters:
1504: + dim - The topological mesh dimension
1505: . baseFilename - The basename for mesh files
1506: . zeroBase - Use 0 to start numbering
1507: - interpolate - The flag for mesh interpolation
1509: Output Parameter:
1510: . mesh - The Mesh object
1512: Level: beginner
1514: .keywords: mesh, PCICE
1515: .seealso: MeshCreate()
1516: @*/
1517: PetscErrorCode MeshCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
1518: {
1519: ALE::Obj<ALE::Mesh> m;
1520: PetscInt debug = 0;
1521: PetscTruth flag;
1522: PetscErrorCode ierr;
1525: MeshCreate(comm, mesh);
1526: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
1527: try {
1528: m = ALE::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
1529: } catch(ALE::Exception e) {
1530: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
1531: }
1532: MeshSetMesh(*mesh, m);
1533: return(0);
1534: }
1538: /*@C
1539: MeshGetCoordinates - Creates an array holding the coordinates.
1541: Not Collective
1543: Input Parameter:
1544: + mesh - The Mesh object
1545: - columnMajor - Flag for column major order
1547: Output Parameter:
1548: + numVertices - The number of vertices
1549: . dim - The embedding dimension
1550: - coords - The array holding local coordinates
1552: Level: intermediate
1554: .keywords: mesh, coordinates
1555: .seealso: MeshCreate()
1556: @*/
1557: PetscErrorCode MeshGetCoordinates(Mesh mesh, PetscTruth columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1558: {
1559: ALE::Obj<ALE::Mesh> m;
1560: PetscErrorCode ierr;
1563: MeshGetMesh(mesh, m);
1564: ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1565: return(0);
1566: }
1570: /*@C
1571: MeshGetElements - Creates an array holding the vertices on each element.
1573: Not Collective
1575: Input Parameters:
1576: + mesh - The Mesh object
1577: - columnMajor - Flag for column major order
1579: Output Parameters:
1580: + numElements - The number of elements
1581: . numCorners - The number of vertices per element
1582: - vertices - The array holding vertices on each local element
1584: Level: intermediate
1586: .keywords: mesh, elements
1587: .seealso: MeshCreate()
1588: @*/
1589: PetscErrorCode MeshGetElements(Mesh mesh, PetscTruth columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1590: {
1591: ALE::Obj<ALE::Mesh> m;
1592: PetscErrorCode ierr;
1595: MeshGetMesh(mesh, m);
1596: ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1597: return(0);
1598: }
1602: /*@C
1603: MeshDistribute - Distributes the mesh and any associated sections.
1605: Not Collective
1607: Input Parameter:
1608: + serialMesh - The original Mesh object
1609: - partitioner - The partitioning package, or NULL for the default
1611: Output Parameter:
1612: . parallelMesh - The distributed Mesh object
1614: Level: intermediate
1616: .keywords: mesh, elements
1618: .seealso: MeshCreate(), MeshDistributeByFace()
1619: @*/
1620: PetscErrorCode MeshDistribute(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1621: {
1622: ALE::Obj<ALE::Mesh> oldMesh;
1623: PetscErrorCode ierr;
1626: MeshGetMesh(serialMesh, oldMesh);
1627: MeshCreate(oldMesh->comm(), parallelMesh);
1628: if (partitioner == NULL) {
1629: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh);
1630: MeshSetMesh(*parallelMesh, newMesh);
1631: } else {
1632: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 0, partitioner);
1633: MeshSetMesh(*parallelMesh, newMesh);
1634: }
1635: return(0);
1636: }
1640: /*@C
1641: MeshDistribute - Distributes the mesh and any associated sections.
1643: Not Collective
1645: Input Parameter:
1646: + serialMesh - The original Mesh object
1647: - partitioner - The partitioning package, or NULL for the default
1649: Output Parameter:
1650: . parallelMesh - The distributed Mesh object
1652: Level: intermediate
1654: .keywords: mesh, elements
1656: .seealso: MeshCreate(), MeshDistribute()
1657: @*/
1658: PetscErrorCode MeshDistributeByFace(Mesh serialMesh, const char partitioner[], Mesh *parallelMesh)
1659: {
1660: ALE::Obj<ALE::Mesh> oldMesh;
1661: PetscErrorCode ierr;
1664: MeshGetMesh(serialMesh, oldMesh);
1665: MeshCreate(oldMesh->comm(), parallelMesh);
1666: if (partitioner == NULL) {
1667: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1);
1668: MeshSetMesh(*parallelMesh, newMesh);
1669: } else {
1670: ALE::Obj<ALE::Mesh> newMesh = ALE::Distribution<ALE::Mesh>::distributeMesh(oldMesh, 1, partitioner);
1671: MeshSetMesh(*parallelMesh, newMesh);
1672: }
1673: return(0);
1674: }
1678: /*@C
1679: MeshGenerate - Generates a mesh.
1681: Not Collective
1683: Input Parameters:
1684: + boundary - The Mesh boundary object
1685: - interpolate - Flag to create intermediate mesh elements
1687: Output Parameter:
1688: . mesh - The Mesh object
1690: Level: intermediate
1692: .keywords: mesh, elements
1693: .seealso: MeshCreate(), MeshRefine()
1694: @*/
1695: PetscErrorCode MeshGenerate(Mesh boundary, PetscTruth interpolate, Mesh *mesh)
1696: {
1697: ALE::Obj<ALE::Mesh> mB;
1698: PetscErrorCode ierr;
1701: MeshGetMesh(boundary, mB);
1702: MeshCreate(mB->comm(), mesh);
1703: ALE::Obj<ALE::Mesh> m = ALE::Generator::generateMesh(mB, interpolate);
1704: MeshSetMesh(*mesh, m);
1705: return(0);
1706: }
1710: /*@C
1711: MeshRefine - Refines the mesh.
1713: Not Collective
1715: Input Parameters:
1716: + mesh - The original Mesh object
1717: . refinementLimit - The maximum size of any cell
1718: - interpolate - Flag to create intermediate mesh elements
1720: Output Parameter:
1721: . refinedMesh - The refined Mesh object
1723: Level: intermediate
1725: .keywords: mesh, elements
1726: .seealso: MeshCreate(), MeshGenerate()
1727: @*/
1728: PetscErrorCode MeshRefine(Mesh mesh, double refinementLimit, PetscTruth interpolate, Mesh *refinedMesh)
1729: {
1730: ALE::Obj<ALE::Mesh> oldMesh;
1731: PetscErrorCode ierr;
1734: MeshGetMesh(mesh, oldMesh);
1735: MeshCreate(oldMesh->comm(), refinedMesh);
1736: ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, interpolate);
1737: MeshSetMesh(*refinedMesh, newMesh);
1738: return(0);
1739: }
1743: PetscErrorCode MeshRefine_Mesh(Mesh mesh, MPI_Comm comm, Mesh *refinedMesh)
1744: {
1745: ALE::Obj<ALE::Mesh> oldMesh;
1746: double refinementLimit;
1747: PetscErrorCode ierr;
1750: MeshGetMesh(mesh, oldMesh);
1751: MeshCreate(comm, refinedMesh);
1752: refinementLimit = oldMesh->getMaxVolume()/2.0;
1753: ALE::Obj<ALE::Mesh> newMesh = ALE::Generator::refineMesh(oldMesh, refinementLimit, true);
1754: MeshSetMesh(*refinedMesh, newMesh);
1755: const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default");
1757: newMesh->setDiscretization(oldMesh->getDiscretization());
1758: newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1759: newMesh->setupField(s);
1760: return(0);
1761: }
1763: #include "Hierarchy.hh"
1767: /*@C
1768: MeshCoarsenHierarchy - Coarsens the mesh into a hierarchy.
1770: Not Collective
1772: Input Parameters:
1773: + mesh - The original Mesh object
1774: . numLevels - The number of
1775: . coarseningFactor - The expansion factor for coarse meshes
1776: - interpolate - Flag to create intermediate mesh elements
1778: Output Parameter:
1779: . coarseHierarchy - The coarse Mesh objects
1781: Level: intermediate
1783: .keywords: mesh, elements
1784: .seealso: MeshCreate(), MeshGenerate()
1785: @*/
1786: PetscErrorCode MeshCoarsenHierarchy(Mesh mesh, int numLevels, double coarseningFactor, PetscTruth interpolate, Mesh **coarseHierarchy)
1787: {
1788: ALE::Obj<ALE::Mesh> oldMesh;
1789: PetscErrorCode ierr;
1792: if (numLevels < 1) {
1793: *coarseHierarchy = PETSC_NULL;
1794: return(0);
1795: }
1796: MeshGetMesh(mesh, oldMesh);
1797: PetscMalloc((numLevels+1) * sizeof(Mesh), coarseHierarchy);
1798: for (int i = 0; i < numLevels+1; i++) {
1799: MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[i]);
1800: }
1801: MeshSpacingFunction(mesh);
1802: MeshCreateHierarchyLabel(mesh, coarseningFactor, numLevels+1, *coarseHierarchy);
1803:
1804: #if 0
1805: if (oldMesh->getDimension() != 2) SETERRQ(PETSC_ERR_SUP, "Coarsening only works in two dimensions right now");
1806: ALE::Coarsener::IdentifyBoundary(oldMesh, 2);
1807: ALE::Coarsener::make_coarsest_boundary(oldMesh, 2, numLevels+1);
1808: ALE::Coarsener::CreateSpacingFunction(oldMesh, 2);
1809: ALE::Coarsener::CreateCoarsenedHierarchyNew(oldMesh, 2, numLevels, coarseningFactor);
1810: PetscMalloc(numLevels * sizeof(Mesh),coarseHierarchy);
1811: for(int l = 0; l < numLevels; l++) {
1812: ALE::Obj<ALE::Mesh> newMesh = new ALE::Mesh(oldMesh->comm(), oldMesh->debug());
1813: const ALE::Obj<ALE::Mesh::real_section_type>& s = newMesh->getRealSection("default");
1815: MeshCreate(oldMesh->comm(), &(*coarseHierarchy)[l]);
1816: newMesh->getTopology()->setPatch(0, oldMesh->getTopology()->getPatch(l+1));
1817: newMesh->setDiscretization(oldMesh->getDiscretization());
1818: newMesh->setBoundaryCondition(oldMesh->getBoundaryCondition());
1819: newMesh->setupField(s);
1820: MeshSetMesh((*coarseHierarchy)[l], newMesh);
1821: }
1822: #endif
1823: return(0);
1824: }
1826: PetscErrorCode MeshCoarsenHierarchy_Mesh(Mesh mesh, int numLevels, Mesh **coarseHierarchy)
1827: {
1829: double cfactor = 1.5;
1831: PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1832: MeshCoarsenHierarchy(mesh, numLevels, cfactor, PETSC_FALSE, coarseHierarchy);
1833: return(0);
1834: }
1838: /*
1839: This method only handle P_1 discretizations at present.
1840: */
1841: PetscErrorCode MeshGetInterpolation_Mesh(Mesh dmCoarse, Mesh dmFine, Mat *interpolation, Vec *scaling)
1842: {
1843: ALE::Obj<ALE::Mesh> coarse;
1844: ALE::Obj<ALE::Mesh> fine;
1845: Mesh coarseMesh = (Mesh) dmCoarse;
1846: Mesh fineMesh = (Mesh) dmFine;
1847: Mat P;
1851: MeshGetMesh(fineMesh, fine);
1852: MeshGetMesh(coarseMesh, coarse);
1853: const ALE::Obj<ALE::Mesh::real_section_type>& coarseCoordinates = coarse->getRealSection("coordinates");
1854: const ALE::Obj<ALE::Mesh::real_section_type>& fineCoordinates = fine->getRealSection("coordinates");
1855: const ALE::Obj<ALE::Mesh::label_sequence>& vertices = fine->depthStratum(0);
1856: const ALE::Obj<ALE::Mesh::real_section_type>& sCoarse = coarse->getRealSection("default");
1857: const ALE::Obj<ALE::Mesh::real_section_type>& sFine = fine->getRealSection("default");
1858: const ALE::Obj<ALE::Mesh::order_type>& coarseOrder = coarse->getFactory()->getGlobalOrder(coarse, "default", sCoarse);
1859: const ALE::Obj<ALE::Mesh::order_type>& fineOrder = fine->getFactory()->getGlobalOrder(fine, "default", sFine);
1861: const int dim = coarse->getDimension();
1862: double *v0, *J, *invJ, detJ, *refCoords, *values;
1864: MatCreate(fine->comm(), &P);
1865: MatSetSizes(P, sFine->size(), sCoarse->size(), PETSC_DETERMINE, PETSC_DETERMINE);
1866: MatSetFromOptions(P);
1867: MatSetUpPreallocation(P);
1868: PetscMalloc5(dim,double,&v0,dim*dim,double,&J,dim*dim,double,&invJ,dim,double,&refCoords,dim+1,double,&values);
1869: for(ALE::Mesh::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
1870: const ALE::Mesh::real_section_type::value_type *coords = fineCoordinates->restrictPoint(*v_iter);
1872: ALE::Mesh::point_type coarseCell;
1873: ALE::Mesh::point_type cellguess = -1;
1874: if (fine->hasLabel("prolongation")) {
1875: cellguess = fine->getValue(fine->getLabel("prolongation"), *v_iter);
1876: coarseCell = coarse->locatePoint(coords, cellguess);
1877: } else {
1878: coarseCell = coarse->locatePoint(coords);
1879: }
1880: // coarseCell = coarse->locatePoint(coords);
1881: if (coarseCell == -1) {
1882: // do NO CORRECTION!
1883: } else {
1884: coarse->computeElementGeometry(coarseCoordinates, coarseCell, v0, J, invJ, detJ);
1885: for(int d = 0; d < dim; ++d) {
1886: refCoords[d] = 0.0;
1887: for(int e = 0; e < dim; ++e) {
1888: refCoords[d] += invJ[d*dim+e]*(coords[e] - v0[e]);
1889: }
1890: refCoords[d] -= 1.0;
1891: }
1892: values[0] = -(refCoords[0] + refCoords[1])/2.0;
1893: values[1] = 0.5*(refCoords[0] + 1.0);
1894: values[2] = 0.5*(refCoords[1] + 1.0);
1895: updateOperatorGeneral(P, fine, sFine, fineOrder, *v_iter, coarse, sCoarse, coarseOrder, coarseCell, values, INSERT_VALUES);
1896: }
1897: }
1898: PetscFree5(v0,J,invJ,refCoords,values);
1899: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
1900: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
1901: *interpolation = P;
1902: return(0);
1903: }
1907: /*@C
1908: MeshHasSectionReal - Determines whether this mesh has a SectionReal with the given name.
1910: Not Collective
1912: Input Parameters:
1913: + mesh - The Mesh object
1914: - name - The section name
1916: Output Parameter:
1917: . flag - True if the SectionReal is present in the Mesh
1919: Level: intermediate
1921: .keywords: mesh, elements
1922: .seealso: MeshCreate()
1923: @*/
1924: PetscErrorCode MeshHasSectionReal(Mesh mesh, const char name[], PetscTruth *flag)
1925: {
1926: ALE::Obj<ALE::Mesh> m;
1927: PetscErrorCode ierr;
1930: MeshGetMesh(mesh, m);
1931: *flag = (PetscTruth) m->hasRealSection(std::string(name));
1932: return(0);
1933: }
1937: /*@C
1938: MeshGetSectionReal - Returns a SectionReal of the given name from the Mesh.
1940: Collective on Mesh
1942: Input Parameters:
1943: + mesh - The Mesh object
1944: - name - The section name
1946: Output Parameter:
1947: . section - The SectionReal
1949: Note: The section is a new object, and must be destroyed by the user
1951: Level: intermediate
1953: .keywords: mesh, elements
1954: .seealso: MeshCreate()
1955: @*/
1956: PetscErrorCode MeshGetSectionReal(Mesh mesh, const char name[], SectionReal *section)
1957: {
1958: ALE::Obj<ALE::Mesh> m;
1959: PetscErrorCode ierr;
1962: MeshGetMesh(mesh, m);
1963: SectionRealCreate(m->comm(), section);
1964: PetscObjectSetName((PetscObject) *section, name);
1965: SectionRealSetSection(*section, m->getRealSection(std::string(name)));
1966: SectionRealSetBundle(*section, m);
1967: return(0);
1968: }
1972: /*@C
1973: MeshSetSectionReal - Puts a SectionReal of the given name into the Mesh.
1975: Collective on Mesh
1977: Input Parameters:
1978: + mesh - The Mesh object
1979: - section - The SectionReal
1981: Note: This takes the section name from the PETSc object
1983: Level: intermediate
1985: .keywords: mesh, elements
1986: .seealso: MeshCreate()
1987: @*/
1988: PetscErrorCode MeshSetSectionReal(Mesh mesh, SectionReal section)
1989: {
1990: ALE::Obj<ALE::Mesh> m;
1991: ALE::Obj<ALE::Mesh::real_section_type> s;
1992: const char *name;
1993: PetscErrorCode ierr;
1996: MeshGetMesh(mesh, m);
1997: PetscObjectGetName((PetscObject) section, &name);
1998: SectionRealGetSection(section, s);
1999: m->setRealSection(std::string(name), s);
2000: return(0);
2001: }
2005: /*@C
2006: MeshHasSectionInt - Determines whether this mesh has a SectionInt with the given name.
2008: Not Collective
2010: Input Parameters:
2011: + mesh - The Mesh object
2012: - name - The section name
2014: Output Parameter:
2015: . flag - True if the SectionInt is present in the Mesh
2017: Level: intermediate
2019: .keywords: mesh, elements
2020: .seealso: MeshCreate()
2021: @*/
2022: PetscErrorCode MeshHasSectionInt(Mesh mesh, const char name[], PetscTruth *flag)
2023: {
2024: ALE::Obj<ALE::Mesh> m;
2025: PetscErrorCode ierr;
2028: MeshGetMesh(mesh, m);
2029: *flag = (PetscTruth) m->hasIntSection(std::string(name));
2030: return(0);
2031: }
2035: /*@C
2036: MeshGetSectionInt - Returns a SectionInt of the given name from the Mesh.
2038: Collective on Mesh
2040: Input Parameters:
2041: + mesh - The Mesh object
2042: - name - The section name
2044: Output Parameter:
2045: . section - The SectionInt
2047: Note: The section is a new object, and must be destroyed by the user
2049: Level: intermediate
2051: .keywords: mesh, elements
2052: .seealso: MeshCreate()
2053: @*/
2054: PetscErrorCode MeshGetSectionInt(Mesh mesh, const char name[], SectionInt *section)
2055: {
2056: ALE::Obj<ALE::Mesh> m;
2057: PetscErrorCode ierr;
2060: MeshGetMesh(mesh, m);
2061: SectionIntCreate(m->comm(), section);
2062: PetscObjectSetName((PetscObject) *section, name);
2063: SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2064: SectionIntSetBundle(*section, m);
2065: return(0);
2066: }
2070: /*@C
2071: MeshSetSectionInt - Puts a SectionInt of the given name into the Mesh.
2073: Collective on Mesh
2075: Input Parameters:
2076: + mesh - The Mesh object
2077: - section - The SectionInt
2079: Note: This takes the section name from the PETSc object
2081: Level: intermediate
2083: .keywords: mesh, elements
2084: .seealso: MeshCreate()
2085: @*/
2086: PetscErrorCode MeshSetSectionInt(Mesh mesh, SectionInt section)
2087: {
2088: ALE::Obj<ALE::Mesh> m;
2089: ALE::Obj<ALE::Mesh::int_section_type> s;
2090: const char *name;
2091: PetscErrorCode ierr;
2094: MeshGetMesh(mesh, m);
2095: PetscObjectGetName((PetscObject) section, &name);
2096: SectionIntGetSection(section, s);
2097: m->setIntSection(std::string(name), s);
2098: return(0);
2099: }
2103: /*@C
2104: SectionGetArray - Returns the array underlying the Section.
2106: Not Collective
2108: Input Parameters:
2109: + mesh - The Mesh object
2110: - name - The section name
2112: Output Parameters:
2113: + numElements - The number of mesh element with values
2114: . fiberDim - The number of values per element
2115: - array - The array
2117: Level: intermediate
2119: .keywords: mesh, elements
2120: .seealso: MeshCreate()
2121: @*/
2122: PetscErrorCode SectionGetArray(Mesh mesh, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2123: {
2124: ALE::Obj<ALE::Mesh> m;
2125: PetscErrorCode ierr;
2128: MeshGetMesh(mesh, m);
2129: const Obj<ALE::Mesh::real_section_type>& section = m->getRealSection(std::string(name));
2130: if (section->size() == 0) {
2131: *numElements = 0;
2132: *fiberDim = 0;
2133: *array = NULL;
2134: return(0);
2135: }
2136: const ALE::Mesh::real_section_type::chart_type& chart = section->getChart();
2137: /* const int depth = m->depth(*chart.begin()); */
2138: /* *numElements = m->depthStratum(depth)->size(); */
2139: /* *fiberDim = section->getFiberDimension(*chart.begin()); */
2140: /* *array = (PetscScalar *) m->restrict(section); */
2141: int fiberDimMin = section->getFiberDimension(*chart.begin());
2142: int numElem = 0;
2144: for(ALE::Mesh::real_section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2145: const int fiberDim = section->getFiberDimension(*c_iter);
2147: if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2148: }
2149: for(ALE::Mesh::real_section_type::chart_type::iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2150: const int fiberDim = section->getFiberDimension(*c_iter);
2152: numElem += fiberDim/fiberDimMin;
2153: }
2154: *numElements = numElem;
2155: *fiberDim = fiberDimMin;
2156: *array = (PetscScalar *) section->restrict();
2157: return(0);
2158: }
2162: PetscErrorCode WritePyLithVertices(Mesh mesh, PetscViewer viewer)
2163: {
2164: ALE::Obj<ALE::Mesh> m;
2167: MeshGetMesh(mesh, m);
2168: return ALE::PyLith::Viewer::writeVertices(m, viewer);
2169: }
2173: PetscErrorCode WritePyLithElements(Mesh mesh, SectionInt material, PetscViewer viewer)
2174: {
2175: ALE::Obj<ALE::Mesh> m;
2176: ALE::Obj<ALE::Mesh::int_section_type> s;
2179: MeshGetMesh(mesh, m);
2180: SectionIntGetSection(material, s);
2181: return ALE::PyLith::Viewer::writeElements(m, s, viewer);
2182: }
2186: PetscErrorCode WritePyLithVerticesLocal(Mesh mesh, PetscViewer viewer)
2187: {
2188: ALE::Obj<ALE::Mesh> m;
2191: MeshGetMesh(mesh, m);
2192: return ALE::PyLith::Viewer::writeVerticesLocal(m, viewer);
2193: }
2197: PetscErrorCode WritePyLithElementsLocal(Mesh mesh, SectionInt material, PetscViewer viewer)
2198: {
2199: ALE::Obj<ALE::Mesh> m;
2200: ALE::Obj<ALE::Mesh::int_section_type> s;
2203: MeshGetMesh(mesh, m);
2204: SectionIntGetSection(material, s);
2205: return ALE::PyLith::Viewer::writeElementsLocal(m, s, viewer);
2206: }
2208: #if 0
2211: PetscErrorCode WritePyLithTractionsLocal(Mesh mesh, PetscViewer viewer)
2212: {
2213: ALE::Obj<ALE::Mesh> m;
2216: MeshGetMesh(mesh, m);
2217: return ALE::PyLith::Viewer::writeTractionsLocal(m, m->getRealSection("tractions"), viewer);
2218: }
2219: #endif
2223: /*@C
2224: MeshCompatGetMesh - Gets the internal mesh object
2226: Not collective
2228: Input Parameter:
2229: . mesh - the mesh object
2231: Output Parameter:
2232: . m - the internal mesh object
2234: Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2235: developing for that tool.
2236:
2237: Level: developer
2239: .seealso MeshCreate(), MeshSetMesh()
2241: @*/
2242: PetscErrorCode MeshCompatGetMesh(Mesh mesh, ALE::Obj<ALECompat::Mesh>& m)
2243: {
2246: m = mesh->mcompat;
2247: return(0);
2248: }
2252: /*@C
2253: MeshCompatSetMesh - Sets the internal mesh object
2255: Not collective
2257: Input Parameters:
2258: + mesh - the mesh object
2259: - m - the internal mesh object
2261: Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2262: developing for that tool.
2263:
2264: Level: developer
2266: .seealso MeshCreate(), MeshGetMesh()
2268: @*/
2269: PetscErrorCode MeshCompatSetMesh(Mesh mesh, const ALE::Obj<ALECompat::Mesh>& m)
2270: {
2273: mesh->mcompat = m;
2274: return(0);
2275: }
2279: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2280: {
2281: const int end = interval.prefix + interval.index;
2282: for(int i = interval.index; i < end; i++) {
2283: indices[indx++] = i;
2284: }
2285: }
2289: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2290: {
2291: for(int i = 0; i < interval.prefix; i++) {
2292: indices[(*indx)++] = interval.index + i;
2293: }
2294: for(int i = 0; i < -interval.prefix; i++) {
2295: indices[(*indx)++] = -1;
2296: }
2297: }
2301: PetscErrorCode ExpandIntervals(ALE::Obj<ALECompat::Mesh::real_section_type::IndexArray> intervals, PetscInt *indices)
2302: {
2303: int k = 0;
2306: for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_itor = intervals->begin(); i_itor != intervals->end(); i_itor++) {
2307: ExpandInterval_New(*i_itor, indices, &k);
2308: }
2309: return(0);
2310: }
2314: template<typename Section>
2315: PetscErrorCode MeshCompatCreateGlobalScatter(const ALE::Obj<ALECompat::Mesh>& m, const ALE::Obj<Section>& s, VecScatter *scatter)
2316: {
2317: typedef ALECompat::Mesh::real_section_type::index_type index_type;
2322: const ALE::Obj<ALECompat::Mesh::topology_type>& topology = m->getTopology();
2323: const ALE::Obj<ALECompat::Mesh::real_section_type::atlas_type>& atlas = s->getAtlas();
2324: const ALECompat::Mesh::real_section_type::patch_type patch = 0;
2325: const ALECompat::Mesh::real_section_type::atlas_type::chart_type& chart = atlas->getPatch(patch);
2326: const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder = m->getFactory()->getGlobalOrder(topology, patch, s->getName(), atlas);
2327: int *localIndices, *globalIndices;
2328: int localSize = s->size(patch);
2329: int localIndx = 0, globalIndx = 0;
2330: Vec globalVec, localVec;
2331: IS localIS, globalIS;
2333: VecCreate(m->comm(), &globalVec);
2334: VecSetSizes(globalVec, globalOrder->getLocalSize(), PETSC_DETERMINE);
2335: VecSetFromOptions(globalVec);
2336: // Loop over all local points
2337: PetscMalloc(localSize*sizeof(int), &localIndices);
2338: PetscMalloc(localSize*sizeof(int), &globalIndices);
2339: for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator p_iter = chart.begin(); p_iter != chart.end(); ++p_iter) {
2340: const ALECompat::Mesh::real_section_type::index_type& idx = atlas->restrictPoint(patch, *p_iter)[0];
2342: // Map local indices to global indices
2343: ExpandInterval(idx, localIndices, localIndx);
2344: ExpandInterval(index_type(idx.prefix, globalOrder->getIndex(*p_iter)), globalIndices, globalIndx);
2345: }
2346: if (localIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of local indices %d, should be %d", localIndx, localSize);
2347: if (globalIndx != localSize) SETERRQ2(PETSC_ERR_ARG_SIZ, "Invalid number of global indices %d, should be %d", globalIndx, localSize);
2348: if (m->debug()) {
2349: globalOrder->view("Global Order");
2350: for(int i = 0; i < localSize; ++i) {
2351: printf("[%d] localIndex[%d]: %d globalIndex[%d]: %d\n", m->commRank(), i, localIndices[i], i, globalIndices[i]);
2352: }
2353: }
2354: ISCreateGeneral(PETSC_COMM_SELF, localSize, localIndices, &localIS);
2355: ISCreateGeneral(PETSC_COMM_SELF, localSize, globalIndices, &globalIS);
2356: PetscFree(localIndices);
2357: PetscFree(globalIndices);
2358: VecCreateSeqWithArray(PETSC_COMM_SELF, localSize, s->restrict(patch), &localVec);
2359: VecScatterCreate(localVec, localIS, globalVec, globalIS, scatter);
2360: ISDestroy(globalIS);
2361: ISDestroy(localIS);
2362: VecDestroy(localVec);
2363: VecDestroy(globalVec);
2365: return(0);
2366: }
2370: PetscErrorCode MeshCompatGetGlobalScatter(Mesh mesh, VecScatter *scatter)
2371: {
2377: if (!mesh->globalScatter) {
2378: ALE::Obj<ALECompat::Mesh> m;
2380: MeshCompatGetMesh(mesh, m);
2381: MeshCompatCreateGlobalScatter(m, m->getRealSection("default"), &mesh->globalScatter);
2382: }
2383: *scatter = mesh->globalScatter;
2384: return(0);
2385: }
2389: template<typename Atlas>
2390: PetscErrorCode preallocateOperatorCompat(const ALE::Obj<ALECompat::Mesh::topology_type>& topology, const ALE::Obj<Atlas>& atlas, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, Mat A)
2391: {
2392: typedef ALECompat::New::NumberingFactory<ALECompat::Mesh::topology_type> NumberingFactory;
2393: const ALE::Obj<ALECompat::Mesh::sieve_type> adjGraph = new ALECompat::Mesh::sieve_type(topology->comm(), topology->debug());
2394: const ALE::Obj<ALECompat::Mesh::topology_type> adjTopology = new ALECompat::Mesh::topology_type(topology->comm(), topology->debug());
2395: const ALECompat::Mesh::real_section_type::patch_type patch = 0;
2396: const ALE::Obj<ALECompat::Mesh::sieve_type>& sieve = topology->getPatch(patch);
2397: PetscInt numLocalRows, firstRow;
2398: PetscInt *dnz, *onz;
2402: adjTopology->setPatch(patch, adjGraph);
2403: numLocalRows = globalOrder->getLocalSize();
2404: firstRow = globalOrder->getGlobalOffsets()[topology->commRank()];
2405: PetscMalloc2(numLocalRows, PetscInt, &dnz, numLocalRows, PetscInt, &onz);
2406: /* Create local adjacency graph */
2407: /* In general, we need to get FIAT info that attaches dual basis vectors to sieve points */
2408: const ALECompat::Mesh::real_section_type::atlas_type::chart_type& chart = atlas->getPatch(patch);
2410: for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2411: const ALECompat::Mesh::real_section_type::atlas_type::point_type& point = *c_iter;
2413: adjGraph->addCone(sieve->cone(sieve->support(point)), point);
2414: }
2415: /* Distribute adjacency graph */
2416: topology->constructOverlap(patch);
2417: const Obj<ALECompat::Mesh::send_overlap_type>& vertexSendOverlap = topology->getSendOverlap();
2418: const Obj<ALECompat::Mesh::recv_overlap_type>& vertexRecvOverlap = topology->getRecvOverlap();
2419: const Obj<ALECompat::Mesh::send_overlap_type> nbrSendOverlap = new ALECompat::Mesh::send_overlap_type(topology->comm(), topology->debug());
2420: const Obj<ALECompat::Mesh::recv_overlap_type> nbrRecvOverlap = new ALECompat::Mesh::recv_overlap_type(topology->comm(), topology->debug());
2421: const Obj<ALECompat::Mesh::send_section_type> sendSection = new ALECompat::Mesh::send_section_type(topology->comm(), topology->debug());
2422: const Obj<ALECompat::Mesh::recv_section_type> recvSection = new ALECompat::Mesh::recv_section_type(topology->comm(), sendSection->getTag(), topology->debug());
2424: ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::coneCompletion(vertexSendOverlap, vertexRecvOverlap, adjTopology, sendSection, recvSection);
2425: /* Distribute indices for new points */
2426: ALECompat::New::Distribution<ALECompat::Mesh::topology_type>::updateOverlap(sendSection, recvSection, nbrSendOverlap, nbrRecvOverlap);
2427: NumberingFactory::singleton(topology->debug())->completeOrder(globalOrder, nbrSendOverlap, nbrRecvOverlap, patch, true);
2428: /* Read out adjacency graph */
2429: const ALE::Obj<ALECompat::Mesh::sieve_type> graph = adjTopology->getPatch(patch);
2431: PetscMemzero(dnz, numLocalRows * sizeof(PetscInt));
2432: PetscMemzero(onz, numLocalRows * sizeof(PetscInt));
2433: for(ALECompat::Mesh::real_section_type::atlas_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2434: const ALECompat::Mesh::real_section_type::atlas_type::point_type& point = *c_iter;
2436: if (globalOrder->isLocal(point)) {
2437: const ALE::Obj<ALECompat::Mesh::sieve_type::traits::coneSequence>& adj = graph->cone(point);
2438: const ALECompat::Mesh::order_type::value_type& rIdx = globalOrder->restrictPoint(patch, point)[0];
2439: const int row = rIdx.prefix;
2440: const int rSize = rIdx.index;
2442: for(ALECompat::Mesh::sieve_type::traits::coneSequence::iterator v_iter = adj->begin(); v_iter != adj->end(); ++v_iter) {
2443: const ALECompat::Mesh::real_section_type::atlas_type::point_type& neighbor = *v_iter;
2444: const ALECompat::Mesh::order_type::value_type& cIdx = globalOrder->restrictPoint(patch, neighbor)[0];
2445: const int& cSize = cIdx.index;
2447: if (cSize > 0) {
2448: if (globalOrder->isLocal(neighbor)) {
2449: for(int r = 0; r < rSize; ++r) {dnz[row - firstRow + r] += cSize;}
2450: } else {
2451: for(int r = 0; r < rSize; ++r) {onz[row - firstRow + r] += cSize;}
2452: }
2453: }
2454: }
2455: }
2456: }
2457: if (topology->debug()) {
2458: int rank = topology->commRank();
2459: for(int r = 0; r < numLocalRows; r++) {
2460: std::cout << "["<<rank<<"]: dnz["<<r<<"]: " << dnz[r] << " onz["<<r<<"]: " << onz[r] << std::endl;
2461: }
2462: }
2463: MatSeqAIJSetPreallocation(A, 0, dnz);
2464: MatMPIAIJSetPreallocation(A, 0, dnz, 0, onz);
2465: PetscFree2(dnz, onz);
2466: MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR);
2467: return(0);
2468: }
2472: PetscErrorCode preallocateMatrixCompat(const ALE::Obj<ALECompat::Mesh::topology_type>& topology, const ALE::Obj<ALECompat::Mesh::real_section_type::atlas_type>& atlas, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, Mat A)
2473: {
2474: return preallocateOperatorCompat(topology, atlas, globalOrder, A);
2475: }
2479: PetscErrorCode updateOperatorCompat(Mat A, const ALE::Obj<ALECompat::Mesh::real_section_type>& section, const ALE::Obj<ALECompat::Mesh::order_type>& globalOrder, const ALECompat::Mesh::point_type& e, PetscScalar array[], InsertMode mode)
2480: {
2481: ALECompat::Mesh::real_section_type::patch_type patch = 0;
2482: static PetscInt indicesSize = 0;
2483: static PetscInt *indices = NULL;
2484: PetscInt numIndices = 0;
2485: PetscErrorCode ierr;
2488: const ALE::Obj<ALECompat::Mesh::real_section_type::IndexArray> intervals = section->getIndices(patch, e, globalOrder);
2491: if (section->debug()) {printf("[%d]mat for element %d\n", section->commRank(), e);}
2492: for(ALECompat::Mesh::real_section_type::IndexArray::iterator i_iter = intervals->begin(); i_iter != intervals->end(); ++i_iter) {
2493: numIndices += std::abs(i_iter->prefix);
2494: if (section->debug()) {
2495: printf("[%d]mat interval (%d, %d)\n", section->commRank(), i_iter->prefix, i_iter->index);
2496: }
2497: }
2498: if (indicesSize && (indicesSize != numIndices)) {
2499: PetscFree(indices);
2500: indices = NULL;
2501: }
2502: if (!indices) {
2503: indicesSize = numIndices;
2504: PetscMalloc(indicesSize * sizeof(PetscInt), &indices);
2505: }
2506: ExpandIntervals(intervals, indices);
2507: if (section->debug()) {
2508: for(int i = 0; i < numIndices; i++) {
2509: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2510: }
2511: for(int i = 0; i < numIndices; i++) {
2512: printf("[%d]", section->commRank());
2513: for(int j = 0; j < numIndices; j++) {
2514: printf(" %g", array[i*numIndices+j]);
2515: }
2516: printf("\n");
2517: }
2518: }
2519: MatSetValues(A, numIndices, indices, numIndices, indices, array, mode);
2520: if (ierr) {
2521: printf("[%d]ERROR in updateOperator: point %d\n", section->commRank(), e);
2522: for(int i = 0; i < numIndices; i++) {
2523: printf("[%d]mat indices[%d] = %d\n", section->commRank(), i, indices[i]);
2524: }
2525:
2526: }
2528: return(0);
2529: }
2533: /*@C
2534: MeshCompatCreatePyLith - Create a Mesh from PyLith files.
2536: Not Collective
2538: Input Parameters:
2539: + dim - The topological mesh dimension
2540: . baseFilename - The basename for mesh files
2541: . zeroBase - Use 0 to start numbering
2542: - interpolate - The flag for mesh interpolation
2544: Output Parameter:
2545: . mesh - The Mesh object
2547: Notes: This is part of the PyLith 0.8 compatibility layer. DO NOT USE unless you are
2548: developing for that tool.
2550: Level: developer
2552: .keywords: mesh, PCICE
2553: .seealso: MeshCreate()
2554: @*/
2555: PetscErrorCode MeshCompatCreatePyLith(MPI_Comm comm, const int dim, const char baseFilename[], PetscTruth zeroBase, PetscTruth interpolate, Mesh *mesh)
2556: {
2557: ALE::Obj<ALECompat::Mesh> m;
2558: PetscInt debug = 0;
2559: PetscTruth flag;
2560: PetscErrorCode ierr;
2563: MeshCreate(comm, mesh);
2564: PetscOptionsGetInt(PETSC_NULL, "-debug", &debug, &flag);
2565: try {
2566: m = ALECompat::PyLith::Builder::readMesh(comm, dim, std::string(baseFilename), zeroBase, interpolate, debug);
2567: } catch(ALE::Exception e) {
2568: SETERRQ(PETSC_ERR_FILE_OPEN, e.message());
2569: }
2570: MeshCompatSetMesh(*mesh, m);
2571: return(0);
2572: }