Actual source code: mesh.c
1: #include <private/meshimpl.h> /*I "petscdmmesh.h" I*/
2: #include <petscdmmesh_viewers.hh>
3: #include <petscdmmesh_formats.hh>
5: /* Logging support */
6: PetscLogEvent DMMesh_View, DMMesh_GetGlobalScatter, DMMesh_restrictVector, DMMesh_assembleVector, DMMesh_assembleVectorComplete, DMMesh_assembleMatrix, DMMesh_updateOperator;
8: ALE::MemoryLogger Petsc_MemoryLogger;
13: /*
14: Private routine to delete internal tag storage when a communicator is freed.
16: This is called by MPI, not by users.
20: we do not use PetscFree() since it is unsafe after PetscFinalize()
21: */
22: PetscMPIInt DMMesh_DelTag(MPI_Comm comm,PetscMPIInt keyval,void* attr_val,void* extra_state)
23: {
24: free(attr_val);
25: return(MPI_SUCCESS);
26: }
31: PetscErrorCode DMMeshFinalize()
32: {
34: PETSC_MESH_TYPE::MeshNumberingFactory::singleton(0, 0, true);
35: return(0);
36: }
40: /*@C
41: DMMeshGetMesh - Gets the internal mesh object
43: Not collective
45: Input Parameter:
46: . mesh - the mesh object
48: Output Parameter:
49: . m - the internal mesh object
51: Level: advanced
53: .seealso DMMeshCreate(), DMMeshSetMesh()
54: @*/
55: PetscErrorCode DMMeshGetMesh(DM dm, ALE::Obj<PETSC_MESH_TYPE>& m)
56: {
59: m = ((DM_Mesh*) dm->data)->m;
60: return(0);
61: }
65: /*@C
66: DMMeshSetMesh - Sets the internal mesh object
68: Not collective
70: Input Parameters:
71: + mesh - the mesh object
72: - m - the internal mesh object
74: Level: advanced
76: .seealso DMMeshCreate(), DMMeshGetMesh()
77: @*/
78: PetscErrorCode DMMeshSetMesh(DM dm, const ALE::Obj<PETSC_MESH_TYPE>& m)
79: {
80: DM_Mesh *mesh = (DM_Mesh *) dm->data;
85: mesh->m = m;
86: VecScatterDestroy(&mesh->globalScatter);
87: return(0);
88: }
92: PetscErrorCode DMMeshView_Sieve_Ascii(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
93: {
94: PetscViewerFormat format;
95: PetscErrorCode ierr;
98: PetscViewerGetFormat(viewer, &format);
99: if (format == PETSC_VIEWER_ASCII_VTK) {
100: VTKViewer::writeHeader(mesh, viewer);
101: VTKViewer::writeVertices(mesh, viewer);
102: VTKViewer::writeElements(mesh, viewer);
103: const ALE::Obj<PETSC_MESH_TYPE::int_section_type>& p = mesh->getIntSection("Partition");
104: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& cells = mesh->heightStratum(0);
105: const PETSC_MESH_TYPE::label_sequence::iterator end = cells->end();
106: const int rank = mesh->commRank();
108: p->setChart(PETSC_MESH_TYPE::int_section_type::chart_type(*cells));
109: p->setFiberDimension(cells, 1);
110: p->allocatePoint();
111: for(PETSC_MESH_TYPE::label_sequence::iterator c_iter = cells->begin(); c_iter != end; ++c_iter) {
112: p->updatePoint(*c_iter, &rank);
113: }
114: PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_VTK_CELL);
115: SectionView_Sieve_Ascii(mesh, p, "Partition", viewer);
116: PetscViewerPopFormat(viewer);
117: } else if (format == PETSC_VIEWER_ASCII_PCICE) {
118: char *filename;
119: char coordFilename[2048];
120: PetscBool isConnect;
121: size_t len;
123: PetscViewerFileGetName(viewer, (const char **) &filename);
124: PetscStrlen(filename, &len);
125: PetscStrcmp(&(filename[len-5]), ".lcon", &isConnect);
126: if (!isConnect) {
127: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid element connectivity filename: %s", filename);
128: }
129: ALE::PCICE::Viewer::writeElements(mesh, viewer);
130: PetscStrncpy(coordFilename, filename, len-5);
131: coordFilename[len-5] = '\0';
132: PetscStrcat(coordFilename, ".nodes");
133: PetscViewerFileSetName(viewer, coordFilename);
134: ALE::PCICE::Viewer::writeVertices(mesh, viewer);
135: } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
136: mesh->view("");
137: } else {
138: int dim = mesh->getDimension();
140: PetscViewerASCIIPrintf(viewer, "Mesh in %d dimensions:\n", dim);
141: if (mesh->depth() == 1) {
142: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->depthStratum(0)->size(), 0);
143: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->heightStratum(0)->size(), dim);
144: } else {
145: for(int d = 0; d <= dim; d++) {
146: // FIX: Need to globalize
147: PetscViewerASCIIPrintf(viewer, " %d %d-cells\n", mesh->depthStratum(d)->size(), d);
148: }
149: }
150: }
151: PetscViewerFlush(viewer);
152: return(0);
153: }
158: PetscErrorCode DMMeshView_Sieve_Binary(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
159: {
160: char *filename;
161: PetscErrorCode ierr;
164: PetscViewerFileGetName(viewer, (const char **) &filename);
165: ALE::MeshSerializer::writeMesh(filename, *mesh);
166: return(0);
167: }
171: PetscErrorCode DMMeshView_Sieve(const ALE::Obj<PETSC_MESH_TYPE>& mesh, PetscViewer viewer)
172: {
173: PetscBool iascii, isbinary, isdraw;
177: PetscTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);
178: PetscTypeCompare((PetscObject) viewer, PETSCVIEWERBINARY, &isbinary);
179: PetscTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);
181: if (iascii){
182: DMMeshView_Sieve_Ascii(mesh, viewer);
183: } else if (isbinary) {
184: DMMeshView_Sieve_Binary(mesh, viewer);
185: } else if (isdraw){
186: SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP, "Draw viewer not implemented for DMMesh");
187: } else {
188: SETERRQ1(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Viewer type %s not supported by this mesh object", ((PetscObject)viewer)->type_name);
189: }
190: return(0);
191: }
195: PetscErrorCode DMView_Mesh(DM dm, PetscViewer viewer)
196: {
197: DM_Mesh *mesh = (DM_Mesh *) dm->data;
201: DMMeshView_Sieve(mesh->m, viewer);
202: return(0);
203: }
207: /*@
208: DMMeshLoad - Create a mesh topology from the saved data in a viewer.
210: Collective on Viewer
212: Input Parameter:
213: . viewer - The viewer containing the data
215: Output Parameters:
216: . mesh - the mesh object
218: Level: advanced
220: .seealso DMView()
221: @*/
222: PetscErrorCode DMMeshLoad(PetscViewer viewer, DM dm)
223: {
224: DM_Mesh *mesh = (DM_Mesh *) dm->data;
225: char *filename;
229: if (!mesh->m) {
230: MPI_Comm comm;
232: PetscObjectGetComm((PetscObject) viewer, &comm);
233: ALE::Obj<PETSC_MESH_TYPE> m = new PETSC_MESH_TYPE(comm, 1);
234: DMMeshSetMesh(dm, m);
235: }
236: PetscViewerFileGetName(viewer, (const char **) &filename);
237: ALE::MeshSerializer::loadMesh(filename, *mesh->m);
238: return(0);
239: }
243: /*@C
244: DMMeshCreateMatrix - Creates a matrix with the correct parallel layout required for
245: computing the Jacobian on a function defined using the information in the Section.
247: Collective on DMMesh
249: Input Parameters:
250: + mesh - the mesh object
251: . section - the section which determines data layout
252: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ,
253: or any type which inherits from one of these (such as MATAIJ, MATLUSOL, etc.).
255: Output Parameter:
256: . J - matrix with the correct nonzero preallocation
257: (obviously without the correct Jacobian values)
259: Level: advanced
261: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
262: do not need to do it yourself.
264: .seealso ISColoringView(), ISColoringGetIS(), MatFDColoringCreate(), DMDASetBlockFills()
265: @*/
266: PetscErrorCode DMMeshCreateMatrix(DM dm, SectionReal section, const MatType mtype, Mat *J)
267: {
268: ALE::Obj<PETSC_MESH_TYPE> m;
269: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
273: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
274: MatInitializePackage(PETSC_NULL);
275: #endif
276: if (!mtype) mtype = MATAIJ;
277: DMMeshGetMesh(dm, m);
278: SectionRealGetSection(section, s);
279: try {
280: DMMeshCreateMatrix(m, s, mtype, J, -1, !dm->prealloc_only);
281: } catch(ALE::Exception e) {
282: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB, e.message());
283: }
284: PetscObjectCompose((PetscObject) *J, "DM", (PetscObject) dm);
285: return(0);
286: }
290: PetscErrorCode DMMeshGetVertexMatrix(DM dm, const MatType mtype, Mat *J)
291: {
292: SectionReal section;
296: DMMeshGetVertexSectionReal(dm, "default", 1, §ion);
297: DMMeshCreateMatrix(dm, section, mtype, J);
298: SectionRealDestroy(§ion);
299: return(0);
300: }
304: PetscErrorCode DMMeshGetCellMatrix(DM dm, const MatType mtype, Mat *J)
305: {
306: SectionReal section;
310: DMMeshGetCellSectionReal(dm, "default", 1, §ion);
311: DMMeshCreateMatrix(dm, section, mtype, J);
312: SectionRealDestroy(§ion);
313: return(0);
314: }
318: PetscErrorCode DMGetMatrix_Mesh(DM dm, const MatType mtype, Mat *J)
319: {
320: SectionReal section;
321: ISLocalToGlobalMapping ltog;
322: PetscBool flag;
323: PetscErrorCode ierr;
326: DMMeshHasSectionReal(dm, "default", &flag);
327: if (!flag) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
328: DMMeshGetSectionReal(dm, "default", §ion);
329: DMMeshCreateMatrix(dm, section, mtype, J);
330: DMGetLocalToGlobalMapping(dm, <og);
331: MatSetLocalToGlobalMapping(*J, ltog, ltog);
332: SectionRealDestroy(§ion);
333: return(0);
334: }
338: PetscErrorCode DMDestroy_Mesh(DM dm)
339: {
340: DM_Mesh *mesh = (DM_Mesh *) dm->data;
344: mesh->m = PETSC_NULL;
345: VecScatterDestroy(&mesh->globalScatter);
346: return(0);
347: }
351: PetscErrorCode DMCreateGlobalVector_Mesh(DM dm, Vec *gvec)
352: {
353: ALE::Obj<PETSC_MESH_TYPE> m;
354: PetscBool flag;
358: DMMeshHasSectionReal(dm, "default", &flag);
359: if (!flag) SETERRQ(((PetscObject) dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
360: DMMeshGetMesh(dm, m);
361: const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, "default", m->getRealSection("default"));
363: VecCreate(((PetscObject) dm)->comm, gvec);
364: VecSetSizes(*gvec, order->getLocalSize(), order->getGlobalSize());
365: VecSetFromOptions(*gvec);
366: PetscObjectCompose((PetscObject) *gvec, "DM", (PetscObject) dm);
367: return(0);
368: }
372: /*@
373: DMMeshCreateVector - Creates a global vector matching the input section
375: Collective on DMMesh
377: Input Parameters:
378: + mesh - the DMMesh
379: - section - the Section
381: Output Parameter:
382: . vec - the global vector
384: Level: advanced
386: Notes: The vector can safely be destroyed using VecDestroy().
387: .seealso DMMeshCreate()
388: @*/
389: PetscErrorCode DMMeshCreateVector(DM mesh, SectionReal section, Vec *vec)
390: {
391: ALE::Obj<PETSC_MESH_TYPE> m;
392: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
396: DMMeshGetMesh(mesh, m);
397: SectionRealGetSection(section, s);
398: const ALE::Obj<PETSC_MESH_TYPE::order_type>& order = m->getFactory()->getGlobalOrder(m, s->getName(), s);
400: VecCreate(m->comm(), vec);
401: VecSetSizes(*vec, order->getLocalSize(), order->getGlobalSize());
402: VecSetFromOptions(*vec);
403: return(0);
404: }
408: PetscErrorCode DMCreateLocalVector_Mesh(DM dm, Vec *lvec)
409: {
410: ALE::Obj<PETSC_MESH_TYPE> m;
411: PetscBool flag;
415: DMMeshHasSectionReal(dm, "default", &flag);
416: if (!flag) SETERRQ(((PetscObject) dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
417: DMMeshGetMesh(dm, m);
418: const int size = m->getRealSection("default")->getStorageSize();
420: VecCreate(PETSC_COMM_SELF, lvec);
421: VecSetSizes(*lvec, size, size);
422: VecSetFromOptions(*lvec);
423: PetscObjectCompose((PetscObject) *lvec, "DM", (PetscObject) dm);
424: return(0);
425: }
429: PetscErrorCode DMCreateLocalToGlobalMapping_Mesh(DM dm)
430: {
431: ALE::Obj<PETSC_MESH_TYPE> m;
432: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
433: SectionReal section;
434: PetscBool flag;
438: DMMeshHasSectionReal(dm, "default", &flag);
439: if (!flag) SETERRQ(((PetscObject) dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Must set default section");
440: DMMeshGetSectionReal(dm ,"default", §ion);
441: DMMeshGetMesh(dm, m);
442: SectionRealGetSection(section, s);
443: const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, s->getName(), s);
444: PetscInt *ltog;
446: PetscMalloc(s->size() * sizeof(PetscInt), <og); // We want the local+overlap size
447: for(PetscInt p = s->getChart().min(), l = 0; p < s->getChart().max(); ++p) {
448: PetscInt g = globalOrder->getIndex(p);
450: for(PetscInt c = 0; c < s->getConstrainedFiberDimension(p); ++c, ++l) {
451: ltog[l] = g+c;
452: }
453: }
454: ISLocalToGlobalMappingCreate(PETSC_COMM_SELF, s->size(), ltog, PETSC_OWN_POINTER, &dm->ltogmap);
455: PetscLogObjectParent(dm, dm->ltogmap);
456: SectionRealDestroy(§ion);
457: return(0);
458: }
462: /*@
463: DMMeshCreateGlobalScatter - Create a VecScatter which maps from local, overlapping
464: storage in the Section to a global Vec
466: Collective on DMMesh
468: Input Parameters:
469: + mesh - the mesh object
470: - section - The Scetion which determines data layout
472: Output Parameter:
473: . scatter - the VecScatter
475: Level: advanced
477: .seealso DMDestroy(), DMMeshCreateGlobalRealVector(), DMMeshCreate()
478: @*/
479: PetscErrorCode DMMeshCreateGlobalScatter(DM dm, SectionReal section, VecScatter *scatter)
480: {
481: ALE::Obj<PETSC_MESH_TYPE> m;
482: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
486: DMMeshGetMesh(dm, m);
487: SectionRealGetSection(section, s);
488: if (m->hasLabel("marker")) {
489: DMMeshCreateGlobalScatter(m, s, m->getLabel("marker"), scatter);
490: } else {
491: DMMeshCreateGlobalScatter(m, s, scatter);
492: }
493: return(0);
494: }
498: /*@
499: DMMeshGetGlobalScatter - Retrieve the VecScatter which maps from local, overlapping storage in the default Section to a global Vec
501: Collective on DMMesh
503: Input Parameters:
504: . mesh - the mesh object
506: Output Parameter:
507: . scatter - the VecScatter
509: Level: advanced
511: .seealso MeshDestroy(), DMMeshCreateGlobalrealVector(), DMMeshCreate()
512: @*/
513: PetscErrorCode DMMeshGetGlobalScatter(DM dm, VecScatter *scatter)
514: {
515: DM_Mesh *mesh = (DM_Mesh *) dm->data;
521: if (!mesh->globalScatter) {
522: SectionReal section;
524: DMMeshGetSectionReal(dm, "default", §ion);
525: DMMeshCreateGlobalScatter(dm, section, &mesh->globalScatter);
526: SectionRealDestroy(§ion);
527: }
528: *scatter = mesh->globalScatter;
529: return(0);
530: }
534: PetscErrorCode DMGlobalToLocalBegin_Mesh(DM dm, Vec g, InsertMode mode, Vec l)
535: {
536: VecScatter injection;
540: DMMeshGetGlobalScatter(dm, &injection);
541: VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
542: return(0);
543: }
547: PetscErrorCode DMGlobalToLocalEnd_Mesh(DM dm, Vec g, InsertMode mode, Vec l)
548: {
549: VecScatter injection;
553: DMMeshGetGlobalScatter(dm, &injection);
554: VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
555: return(0);
556: }
560: PetscErrorCode DMLocalToGlobalBegin_Mesh(DM dm, Vec l, InsertMode mode, Vec g)
561: {
562: VecScatter injection;
566: DMMeshGetGlobalScatter(dm, &injection);
567: VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
568: return(0);
569: }
573: PetscErrorCode DMLocalToGlobalEnd_Mesh(DM dm, Vec l, InsertMode mode, Vec g)
574: {
575: VecScatter injection;
579: DMMeshGetGlobalScatter(dm, &injection);
580: VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
581: return(0);
582: }
586: PetscErrorCode DMMeshGetLocalFunction(DM dm, PetscErrorCode (**lf)(DM, Vec, Vec, void *))
587: {
588: DM_Mesh *mesh = (DM_Mesh *) dm->data;
592: if (lf) *lf = mesh->lf;
593: return(0);
594: }
598: PetscErrorCode DMMeshSetLocalFunction(DM dm, PetscErrorCode (*lf)(DM, Vec, Vec, void *))
599: {
600: DM_Mesh *mesh = (DM_Mesh *) dm->data;
604: mesh->lf = lf;
605: return(0);
606: }
610: PetscErrorCode DMMeshGetLocalJacobian(DM dm, PetscErrorCode (**lj)(DM, Vec, Mat, void *))
611: {
612: DM_Mesh *mesh = (DM_Mesh *) dm->data;
616: if (lj) *lj = mesh->lj;
617: return(0);
618: }
622: PetscErrorCode DMMeshSetLocalJacobian(DM dm, PetscErrorCode (*lj)(DM, Vec, Mat, void *))
623: {
624: DM_Mesh *mesh = (DM_Mesh *) dm->data;
628: mesh->lj = lj;
629: return(0);
630: }
634: // Here we assume:
635: // - Assumes 3D and tetrahedron
636: // - The section takes values on vertices and is P1
637: // - Points have the same dimension as the mesh
638: // - All values have the same dimension
639: PetscErrorCode DMMeshInterpolatePoints(DM dm, SectionReal section, int numPoints, PetscReal *points, PetscScalar **values)
640: {
641: Obj<PETSC_MESH_TYPE> m;
642: Obj<PETSC_MESH_TYPE::real_section_type> s;
643: PetscReal *v0, *J, *invJ, detJ;
647: DMMeshGetMesh(dm, m);
648: SectionRealGetSection(section, s);
649: const Obj<PETSC_MESH_TYPE::real_section_type>& coordinates = m->getRealSection("coordinates");
650: int embedDim = coordinates->getFiberDimension(*m->depthStratum(0)->begin());
651: int dim = s->getFiberDimension(*m->depthStratum(0)->begin());
653: PetscMalloc3(embedDim,double,&v0,embedDim*embedDim,double,&J,embedDim*embedDim,double,&invJ);
654: PetscMalloc(numPoints*dim * sizeof(PetscScalar), &values);
655: for(int p = 0; p < numPoints; p++) {
656: PetscReal *point = &points[p*embedDim];
658: PETSC_MESH_TYPE::point_type e = m->locatePoint(point);
659: const PETSC_MESH_TYPE::real_section_type::value_type *coeff = s->restrictPoint(e);
661: m->computeElementGeometry(coordinates, e, v0, J, invJ, detJ);
662: 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;
663: 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;
664: 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;
666: for(int d = 0; d < dim; d++) {
667: (*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;
668: }
669: }
670: PetscFree3(v0, J, invJ);
671: return(0);
672: }
676: /*@
677: DMMeshGetDimension - Return the topological mesh dimension
679: Collective on mesh
681: Input Parameter:
682: . mesh - The DMMesh
684: Output Parameter:
685: . dim - The topological mesh dimension
687: Level: beginner
689: .seealso: DMMeshCreate()
690: @*/
691: PetscErrorCode DMMeshGetDimension(DM dm, PetscInt *dim)
692: {
693: Obj<PETSC_MESH_TYPE> m;
697: DMMeshGetMesh(dm, m);
698: *dim = m->getDimension();
699: return(0);
700: }
704: /*@C
705: DMMeshGetMaximumDegree - Return the maximum degree of any mesh vertex
707: Collective on mesh
709: Input Parameter:
710: . mesh - The DMMesh
712: Output Parameter:
713: . maxDegree - The maximum number of edges at any vertex
715: Level: beginner
717: .seealso: DMMeshCreate()
718: @*/
719: PetscErrorCode DMMeshGetMaximumDegree(DM dm, PetscInt *maxDegree)
720: {
721: Obj<PETSC_MESH_TYPE> m;
725: DMMeshGetMesh(dm, m);
726: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& vertices = m->depthStratum(0);
727: const ALE::Obj<PETSC_MESH_TYPE::sieve_type>& sieve = m->getSieve();
728: PetscInt maxDeg = -1;
730: for(PETSC_MESH_TYPE::label_sequence::iterator v_iter = vertices->begin(); v_iter != vertices->end(); ++v_iter) {
731: maxDeg = PetscMax(maxDeg, (PetscInt) sieve->getSupportSize(*v_iter));
732: }
733: *maxDegree = maxDeg;
734: return(0);
735: }
741: /*@
742: DMMeshRestrictVector - Insert values from a global vector into a local ghosted vector
744: Collective on g
746: Input Parameters:
747: + g - The global vector
748: . l - The local vector
749: - mode - either ADD_VALUES or INSERT_VALUES, where
750: ADD_VALUES adds values to any existing entries, and
751: INSERT_VALUES replaces existing entries with new values
753: Level: beginner
755: .seealso: MatSetOption()
756: @*/
757: PetscErrorCode DMMeshRestrictVector(Vec g, Vec l, InsertMode mode)
758: {
759: VecScatter injection;
763: PetscLogEventBegin(DMMesh_restrictVector,0,0,0,0);
764: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
765: if (injection) {
766: VecScatterBegin(injection, g, l, mode, SCATTER_REVERSE);
767: VecScatterEnd(injection, g, l, mode, SCATTER_REVERSE);
768: } else {
769: if (mode == INSERT_VALUES) {
770: VecCopy(g, l);
771: } else {
772: VecAXPY(l, 1.0, g);
773: }
774: }
775: PetscLogEventEnd(DMMesh_restrictVector,0,0,0,0);
776: return(0);
777: }
781: /*@
782: DMMeshAssembleVectorComplete - Insert values from a local ghosted vector into a global vector
784: Collective on g
786: Input Parameters:
787: + g - The global vector
788: . l - The local vector
789: - mode - either ADD_VALUES or INSERT_VALUES, where
790: ADD_VALUES adds values to any existing entries, and
791: INSERT_VALUES replaces existing entries with new values
793: Level: beginner
795: .seealso: MatSetOption()
796: @*/
797: PetscErrorCode DMMeshAssembleVectorComplete(Vec g, Vec l, InsertMode mode)
798: {
799: VecScatter injection;
803: PetscLogEventBegin(DMMesh_assembleVectorComplete,0,0,0,0);
804: PetscObjectQuery((PetscObject) g, "injection", (PetscObject *) &injection);
805: if (injection) {
806: VecScatterBegin(injection, l, g, mode, SCATTER_FORWARD);
807: VecScatterEnd(injection, l, g, mode, SCATTER_FORWARD);
808: } else {
809: if (mode == INSERT_VALUES) {
810: VecCopy(l, g);
811: } else {
812: VecAXPY(g, 1.0, l);
813: }
814: }
815: PetscLogEventEnd(DMMesh_assembleVectorComplete,0,0,0,0);
816: return(0);
817: }
821: /*@
822: DMMeshAssembleVector - Insert values into a vector
824: Collective on A
826: Input Parameters:
827: + b - the vector
828: . e - The element number
829: . v - The values
830: - mode - either ADD_VALUES or INSERT_VALUES, where
831: ADD_VALUES adds values to any existing entries, and
832: INSERT_VALUES replaces existing entries with new values
834: Level: beginner
836: .seealso: VecSetOption()
837: @*/
838: PetscErrorCode DMMeshAssembleVector(Vec b, PetscInt e, PetscScalar v[], InsertMode mode)
839: {
840: DM dm;
841: SectionReal section;
845: PetscObjectQuery((PetscObject) b, "DM", (PetscObject *) &dm);
846: DMMeshGetSectionReal(dm, "x", §ion);
847: DMMeshAssembleVector(b, dm, section, e, v, mode);
848: SectionRealDestroy(§ion);
849: return(0);
850: }
852: PetscErrorCode DMMeshAssembleVector(Vec b, DM dm, SectionReal section, PetscInt e, PetscScalar v[], InsertMode mode)
853: {
854: ALE::Obj<PETSC_MESH_TYPE> m;
855: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
856: PetscInt firstElement;
857: PetscErrorCode ierr;
860: PetscLogEventBegin(DMMesh_assembleVector,0,0,0,0);
861: DMMeshGetMesh(dm, m);
862: SectionRealGetSection(section, s);
863: //firstElement = elementBundle->getLocalSizes()[bundle->getCommRank()];
864: firstElement = 0;
865: #ifdef PETSC_USE_COMPLEX
866: SETERRQ(((PetscObject)mesh)->comm,PETSC_ERR_SUP, "SectionReal does not support complex update");
867: #else
868: if (mode == INSERT_VALUES) {
869: m->update(s, PETSC_MESH_TYPE::point_type(e + firstElement), v);
870: } else {
871: m->updateAdd(s, PETSC_MESH_TYPE::point_type(e + firstElement), v);
872: }
873: #endif
874: PetscLogEventEnd(DMMesh_assembleVector,0,0,0,0);
875: return(0);
876: }
880: /*@C
881: MatSetValuesTopology - Sets values in a matrix using DM Mesh points rather than indices
883: Not Collective
885: Input Parameters:
886: + mat - the matrix
887: . dmr - The row DM
888: . nrow, rowPoints - number of rows and their local Sieve points
889: . dmc - The column DM
890: . ncol, colPoints - number of columns and their local Sieve points
891: . v - a logically two-dimensional array of values
892: - mode - either ADD_VALUES or INSERT_VALUES, where
893: ADD_VALUES adds values to any existing entries, and
894: INSERT_VALUES replaces existing entries with new values
896: Level: intermediate
898: .seealso: DMMeshCreate(), MatSetValuesStencil()
899: @*/
900: PetscErrorCode MatSetValuesTopology(Mat mat, DM dmr, PetscInt nrow, const PetscInt rowPoints[], DM dmc, PetscInt ncol, const PetscInt colPoints[], const PetscScalar v[], InsertMode mode)
901: {
902: ALE::Obj<PETSC_MESH_TYPE> mr;
903: ALE::Obj<PETSC_MESH_TYPE> mc;
909: if (!nrow || !ncol) return(0); /* no values to insert */
915: DMMeshGetMesh(dmr, mr);
916: DMMeshGetMesh(dmc, mc);
917: typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
918: visitor_type rV(*mr->getRealSection("default"), *mr->getFactory()->getLocalOrder(mr, "default", mr->getRealSection("default")),
919: (int) pow((double) mr->getSieve()->getMaxConeSize(), mr->depth())*mr->getMaxDof()*nrow, mr->depth() > 1);
920: visitor_type cV(*mc->getRealSection("default"), *mc->getFactory()->getLocalOrder(mc, "default", mc->getRealSection("default")),
921: (int) pow((double) mc->getSieve()->getMaxConeSize(), mc->depth())*mc->getMaxDof()*ncol, mc->depth() > 1);
923: try {
924: for(PetscInt r = 0; r < nrow; ++r) {
925: ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(*mr->getSieve(), rowPoints[r], rV);
926: }
927: } catch(ALE::Exception e) {
928: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB, e.message());
929: }
930: const PetscInt *rowIndices = rV.getValues();
931: const int numRowIndices = rV.getSize();
932: try {
933: for(PetscInt c = 0; c < ncol; ++c) {
934: ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(*mc->getSieve(), colPoints[c], cV);
935: }
936: } catch(ALE::Exception e) {
937: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB, e.message());
938: }
939: const PetscInt *colIndices = cV.getValues();
940: const int numColIndices = cV.getSize();
942: MatSetValuesLocal(mat, numRowIndices, rowIndices, numColIndices, colIndices, v, mode);
943: return(0);
944: }
948: PetscErrorCode DMMeshUpdateOperator(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& m, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& section, const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder, const PETSC_MESH_TYPE::point_type& e, PetscScalar array[], InsertMode mode)
949: {
953: typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
954: visitor_type iV(*section, *globalOrder, (int) pow((double) m->getSieve()->getMaxConeSize(), m->depth())*m->getMaxDof(), m->depth() > 1);
956: updateOperator(A, *m->getSieve(), iV, e, array, mode);
957: return(0);
958: }
962: PetscErrorCode DMMeshUpdateOperatorGeneral(Mat A, const ALE::Obj<PETSC_MESH_TYPE>& rowM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& rowSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& rowGlobalOrder, const PETSC_MESH_TYPE::point_type& rowE, const ALE::Obj<PETSC_MESH_TYPE>& colM, const ALE::Obj<PETSC_MESH_TYPE::real_section_type>& colSection, const ALE::Obj<PETSC_MESH_TYPE::order_type>& colGlobalOrder, const PETSC_MESH_TYPE::point_type& colE, PetscScalar array[], InsertMode mode)
963: {
964: typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
965: visitor_type iVr(*rowSection, *rowGlobalOrder, (int) pow((double) rowM->getSieve()->getMaxConeSize(), rowM->depth())*rowM->getMaxDof(), rowM->depth() > 1);
966: visitor_type iVc(*colSection, *colGlobalOrder, (int) pow((double) colM->getSieve()->getMaxConeSize(), colM->depth())*colM->getMaxDof(), colM->depth() > 1);
968: PetscErrorCode updateOperator(A, *rowM->getSieve(), iVr, rowE, *colM->getSieve(), iVc, colE, array, mode);
969: return(0);
970: }
974: /*@
975: DMMeshSetMaxDof - Sets the maximum number of degrees of freedom on any sieve point
977: Logically Collective on A
979: Input Parameters:
980: + A - the matrix
981: . mesh - DMMesh needed for orderings
982: . section - A Section which describes the layout
983: . e - The element number
984: . v - The values
985: - mode - either ADD_VALUES or INSERT_VALUES, where
986: ADD_VALUES adds values to any existing entries, and
987: INSERT_VALUES replaces existing entries with new values
989: Notes: This is used by routines like DMMeshUpdateOperator() to bound buffer sizes
991: Level: developer
993: .seealso: DMMeshUpdateOperator(), DMMeshAssembleMatrix()
994: @*/
995: PetscErrorCode DMMeshSetMaxDof(DM dm, PetscInt maxDof)
996: {
997: Obj<PETSC_MESH_TYPE> m;
998: PetscErrorCode ierr;
1001: DMMeshGetMesh(dm, m);
1002: m->setMaxDof(maxDof);
1003: return(0);
1004: }
1008: /*@
1009: DMMeshAssembleMatrix - Insert values into a matrix
1011: Collective on A
1013: Input Parameters:
1014: + A - the matrix
1015: . dm - DMMesh needed for orderings
1016: . section - A Section which describes the layout
1017: . e - The element
1018: . v - The values
1019: - mode - either ADD_VALUES or INSERT_VALUES, where
1020: ADD_VALUES adds values to any existing entries, and
1021: INSERT_VALUES replaces existing entries with new values
1023: Level: beginner
1025: .seealso: MatSetOption()
1026: @*/
1027: PetscErrorCode DMMeshAssembleMatrix(Mat A, DM dm, SectionReal section, PetscInt e, PetscScalar v[], InsertMode mode)
1028: {
1032: PetscLogEventBegin(DMMesh_assembleMatrix,0,0,0,0);
1033: try {
1034: Obj<PETSC_MESH_TYPE> m;
1035: Obj<PETSC_MESH_TYPE::real_section_type> s;
1037: DMMeshGetMesh(dm, m);
1038: SectionRealGetSection(section, s);
1039: const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder = m->getFactory()->getGlobalOrder(m, s->getName(), s);
1041: if (m->debug()) {
1042: std::cout << "Assembling matrix for element number " << e << " --> point " << e << std::endl;
1043: }
1044: DMMeshUpdateOperator(A, m, s, globalOrder, e, v, mode);
1045: } catch (ALE::Exception e) {
1046: std::cout << e.msg() << std::endl;
1047: }
1048: PetscLogEventEnd(DMMesh_assembleMatrix,0,0,0,0);
1049: return(0);
1050: }
1052: /******************************** C Wrappers **********************************/
1056: /*@C
1057: DMMeshGetLabelSize - Get the number of different integer ids in a Label
1059: Not Collective
1061: Input Parameters:
1062: + dm - The DMMesh object
1063: - name - The label name
1065: Output Parameter:
1066: . size - The label size (number of different integer ids)
1068: Level: beginner
1070: .keywords: mesh, ExodusII
1071: .seealso: DMMeshCreateExodus()
1072: @*/
1073: PetscErrorCode DMMeshGetLabelSize(DM dm, const char name[], PetscInt *size)
1074: {
1075: ALE::Obj<PETSC_MESH_TYPE> m;
1076: PetscErrorCode ierr;
1079: DMMeshGetMesh(dm, m);
1080: *size = m->getLabel(name)->getCapSize();
1081: return(0);
1082: }
1086: /*@C
1087: DMMeshGetLabelIds - Get the integer ids in a label
1089: Not Collective
1091: Input Parameters:
1092: + mesh - The DMMesh object
1093: . name - The label name
1094: - ids - The id storage array
1096: Output Parameter:
1097: . ids - The integer ids
1099: Level: beginner
1101: .keywords: mesh, ExodusII
1102: .seealso: DMMeshCreateExodus()
1103: @*/
1104: PetscErrorCode DMMeshGetLabelIds(DM dm, const char name[], PetscInt *ids)
1105: {
1106: ALE::Obj<PETSC_MESH_TYPE> m;
1107: PetscErrorCode ierr;
1110: DMMeshGetMesh(dm, m);
1111: const ALE::Obj<PETSC_MESH_TYPE::label_type::capSequence>& labelIds = m->getLabel(name)->cap();
1112: const PETSC_MESH_TYPE::label_type::capSequence::const_iterator iEnd = labelIds->end();
1113: PetscInt i = 0;
1115: for(PETSC_MESH_TYPE::label_type::capSequence::const_iterator i_iter = labelIds->begin(); i_iter != iEnd; ++i_iter, ++i) {
1116: ids[i] = *i_iter;
1117: }
1118: return(0);
1119: }
1123: /*@C
1124: DMMeshGetStratumSize - Get the number of points in a label stratum
1126: Not Collective
1128: Input Parameters:
1129: + dm - The DMMesh object
1130: . name - The label name
1131: - value - The stratum value
1133: Output Parameter:
1134: . size - The stratum size
1136: Level: beginner
1138: .keywords: mesh, ExodusII
1139: .seealso: DMMeshCreateExodus()
1140: @*/
1141: PetscErrorCode DMMeshGetStratumSize(DM dm, const char name[], PetscInt value, PetscInt *size)
1142: {
1143: ALE::Obj<PETSC_MESH_TYPE> m;
1144: PetscErrorCode ierr;
1147: DMMeshGetMesh(dm, m);
1148: *size = m->getLabelStratum(name, value)->size();
1149: return(0);
1150: }
1154: /*@C
1155: DMMeshGetStratum - Get the points in a label stratum
1157: Not Collective
1159: Input Parameters:
1160: + dm - The DMMesh object
1161: . name - The label name
1162: . value - The stratum value
1163: - points - The stratum points storage array
1165: Output Parameter:
1166: . points - The stratum points
1168: Level: beginner
1170: .keywords: mesh, ExodusII
1171: .seealso: DMMeshCreateExodus()
1172: @*/
1173: PetscErrorCode DMMeshGetStratum(DM dm, const char name[], PetscInt value, PetscInt *points)
1174: {
1175: ALE::Obj<PETSC_MESH_TYPE> m;
1176: PetscErrorCode ierr;
1179: DMMeshGetMesh(dm, m);
1180: const ALE::Obj<PETSC_MESH_TYPE::label_sequence>& stratum = m->getLabelStratum(name, value);
1181: const PETSC_MESH_TYPE::label_sequence::iterator sEnd = stratum->end();
1182: PetscInt s = 0;
1184: for(PETSC_MESH_TYPE::label_sequence::iterator s_iter = stratum->begin(); s_iter != sEnd; ++s_iter, ++s) {
1185: points[s] = *s_iter;
1186: }
1187: return(0);
1188: }
1192: PetscErrorCode WriteVTKHeader(DM dm, PetscViewer viewer)
1193: {
1194: ALE::Obj<PETSC_MESH_TYPE> m;
1197: DMMeshGetMesh(dm, m);
1198: return VTKViewer::writeHeader(m, viewer);
1199: }
1203: PetscErrorCode WriteVTKVertices(DM dm, PetscViewer viewer)
1204: {
1205: ALE::Obj<PETSC_MESH_TYPE> m;
1208: DMMeshGetMesh(dm, m);
1209: return VTKViewer::writeVertices(m, viewer);
1210: }
1214: PetscErrorCode WriteVTKElements(DM dm, PetscViewer viewer)
1215: {
1216: ALE::Obj<PETSC_MESH_TYPE> m;
1219: DMMeshGetMesh(dm, m);
1220: return VTKViewer::writeElements(m, viewer);
1221: }
1225: /*@C
1226: DMMeshGetCoordinates - Creates an array holding the coordinates.
1228: Not Collective
1230: Input Parameter:
1231: + dm - The DMMesh object
1232: - columnMajor - Flag for column major order
1234: Output Parameter:
1235: + numVertices - The number of vertices
1236: . dim - The embedding dimension
1237: - coords - The array holding local coordinates
1239: Level: intermediate
1241: .keywords: mesh, coordinates
1242: .seealso: DMMeshCreate()
1243: @*/
1244: PetscErrorCode DMMeshGetCoordinates(DM dm, PetscBool columnMajor, PetscInt *numVertices, PetscInt *dim, PetscReal *coords[])
1245: {
1246: ALE::Obj<PETSC_MESH_TYPE> m;
1247: PetscErrorCode ierr;
1250: DMMeshGetMesh(dm, m);
1251: ALE::PCICE::Builder::outputVerticesLocal(m, numVertices, dim, coords, columnMajor);
1252: return(0);
1253: }
1257: /*@C
1258: DMMeshGetElements - Creates an array holding the vertices on each element.
1260: Not Collective
1262: Input Parameters:
1263: + dm - The DMMesh object
1264: - columnMajor - Flag for column major order
1266: Output Parameters:
1267: + numElements - The number of elements
1268: . numCorners - The number of vertices per element
1269: - vertices - The array holding vertices on each local element
1271: Level: intermediate
1273: .keywords: mesh, elements
1274: .seealso: DMMeshCreate()
1275: @*/
1276: PetscErrorCode DMMeshGetElements(DM dm, PetscBool columnMajor, PetscInt *numElements, PetscInt *numCorners, PetscInt *vertices[])
1277: {
1278: ALE::Obj<PETSC_MESH_TYPE> m;
1279: PetscErrorCode ierr;
1282: DMMeshGetMesh(dm, m);
1283: ALE::PCICE::Builder::outputElementsLocal(m, numElements, numCorners, vertices, columnMajor);
1284: return(0);
1285: }
1289: /*@C
1290: DMMeshGetCone - Creates an array holding the cone of a given point
1292: Not Collective
1294: Input Parameters:
1295: + dm - The DMMesh object
1296: - p - The mesh point
1298: Output Parameters:
1299: + numPoints - The number of points in the cone
1300: - points - The array holding the cone points
1302: Level: intermediate
1304: .keywords: mesh, cone
1305: .seealso: DMMeshCreate()
1306: @*/
1307: PetscErrorCode DMMeshGetCone(DM dm, PetscInt p, PetscInt *numPoints, PetscInt *points[])
1308: {
1309: ALE::Obj<PETSC_MESH_TYPE> m;
1310: PetscErrorCode ierr;
1313: DMMeshGetMesh(dm, m);
1314: *numPoints = m->getSieve()->getConeSize(p);
1315: ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type> v(*numPoints);
1317: m->getSieve()->cone(p, v);
1318: *points = const_cast<PetscInt*>(v.getPoints());
1319: return(0);
1320: }
1324: /*@C
1325: DMMeshDistribute - Distributes the mesh and any associated sections.
1327: Not Collective
1329: Input Parameter:
1330: + serialMesh - The original DMMesh object
1331: - partitioner - The partitioning package, or NULL for the default
1333: Output Parameter:
1334: . parallelMesh - The distributed DMMesh object
1336: Level: intermediate
1338: .keywords: mesh, elements
1340: .seealso: DMMeshCreate(), DMMeshDistributeByFace()
1341: @*/
1342: PetscErrorCode DMMeshDistribute(DM serialMesh, const char partitioner[], DM *parallelMesh)
1343: {
1344: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1345: PetscMPIInt commSize;
1346: PetscErrorCode ierr;
1349: MPI_Comm_size(((PetscObject) serialMesh)->comm, &commSize);
1350: if (commSize == 1) return(0);
1351: DMMeshGetMesh(serialMesh, oldMesh);
1352: DMMeshCreate(oldMesh->comm(), parallelMesh);
1353: const Obj<PETSC_MESH_TYPE> newMesh = new PETSC_MESH_TYPE(oldMesh->comm(), oldMesh->getDimension(), oldMesh->debug());
1354: const Obj<PETSC_MESH_TYPE::sieve_type> newSieve = new PETSC_MESH_TYPE::sieve_type(oldMesh->comm(), oldMesh->debug());
1356: newMesh->setSieve(newSieve);
1357: ALE::DistributionNew<PETSC_MESH_TYPE>::distributeMeshAndSectionsV(oldMesh, newMesh);
1358: DMMeshSetMesh(*parallelMesh, newMesh);
1359: return(0);
1360: }
1364: /*@C
1365: DMMeshDistribute - Distributes the mesh and any associated sections.
1367: Not Collective
1369: Input Parameter:
1370: + serialMesh - The original DMMesh object
1371: - partitioner - The partitioning package, or NULL for the default
1373: Output Parameter:
1374: . parallelMesh - The distributed DMMesh object
1376: Level: intermediate
1378: .keywords: mesh, elements
1380: .seealso: DMMeshCreate(), DMMeshDistribute()
1381: @*/
1382: PetscErrorCode DMMeshDistributeByFace(DM serialMesh, const char partitioner[], DM *parallelMesh)
1383: {
1384: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1385: PetscErrorCode ierr;
1388: DMMeshGetMesh(serialMesh, oldMesh);
1389: DMMeshCreate(oldMesh->comm(), parallelMesh);
1390: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "I am being lazy, bug me.");
1391: #if 0
1392: ALE::DistributionNew<PETSC_MESH_TYPE>::distributeMeshAndSectionsV(oldMesh, newMesh, height = 1);
1393: #endif
1394: return(0);
1395: }
1399: /*@C
1400: DMMeshGenerate - Generates a mesh.
1402: Not Collective
1404: Input Parameters:
1405: + boundary - The DMMesh boundary object
1406: - interpolate - Flag to create intermediate mesh elements
1408: Output Parameter:
1409: . mesh - The DMMesh object
1411: Level: intermediate
1413: .keywords: mesh, elements
1414: .seealso: DMMeshCreate(), DMMeshRefine()
1415: @*/
1416: PetscErrorCode DMMeshGenerate(DM boundary, PetscBool interpolate, DM *mesh)
1417: {
1418: ALE::Obj<PETSC_MESH_TYPE> mB;
1419: PetscErrorCode ierr;
1422: DMMeshGetMesh(boundary, mB);
1423: DMMeshCreate(mB->comm(), mesh);
1424: ALE::Obj<PETSC_MESH_TYPE> m = ALE::Generator<PETSC_MESH_TYPE>::generateMeshV(mB, interpolate);
1425: DMMeshSetMesh(*mesh, m);
1426: return(0);
1427: }
1431: /*@C
1432: DMMeshRefine - Refines the mesh.
1434: Not Collective
1436: Input Parameters:
1437: + mesh - The original DMMesh object
1438: . refinementLimit - The maximum size of any cell
1439: - interpolate - Flag to create intermediate mesh elements
1441: Output Parameter:
1442: . refinedMesh - The refined DMMesh object
1444: Level: intermediate
1446: .keywords: mesh, elements
1447: .seealso: DMMeshCreate(), DMMeshGenerate()
1448: @*/
1449: PetscErrorCode DMMeshRefine(DM mesh, double refinementLimit, PetscBool interpolate, DM *refinedMesh)
1450: {
1451: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1455: if (refinementLimit == 0.0) return(0);
1456: DMMeshGetMesh(mesh, oldMesh);
1457: DMMeshCreate(oldMesh->comm(), refinedMesh);
1458: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, interpolate);
1459: DMMeshSetMesh(*refinedMesh, newMesh);
1460: return(0);
1461: }
1465: PetscErrorCode DMRefine_Mesh(DM dm, MPI_Comm comm, DM *dmRefined)
1466: {
1467: ALE::Obj<PETSC_MESH_TYPE> oldMesh;
1468: double refinementLimit;
1469: PetscErrorCode ierr;
1472: DMMeshGetMesh(dm, oldMesh);
1473: DMMeshCreate(comm, dmRefined);
1474: refinementLimit = oldMesh->getMaxVolume()/2.0;
1475: ALE::Obj<PETSC_MESH_TYPE> newMesh = ALE::Generator<PETSC_MESH_TYPE>::refineMeshV(oldMesh, refinementLimit, true);
1476: DMMeshSetMesh(*dmRefined, newMesh);
1477: return(0);
1478: }
1482: PetscErrorCode DMCoarsenHierarchy_Mesh(DM mesh, int numLevels, DM *coarseHierarchy)
1483: {
1484: PetscReal cfactor = 1.5;
1488: PetscOptionsReal("-dmmg_coarsen_factor", "The coarsening factor", PETSC_NULL, cfactor, &cfactor, PETSC_NULL);
1489: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Peter needs to incorporate his code.");
1490: return(0);
1491: }
1495: PetscErrorCode DMGetInterpolation_Mesh(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) {
1496: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Peter needs to incorporate his code.");
1497: }
1501: PetscErrorCode DMMeshMarkBoundaryCells(DM dm, const char labelName[], PetscInt marker, PetscInt newMarker) {
1502: ALE::Obj<PETSC_MESH_TYPE> mesh;
1506: DMMeshGetMesh(dm, mesh);
1507: mesh->markBoundaryCells(labelName, marker, newMarker);
1508: return(0);
1509: }
1513: PetscErrorCode DMMeshGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) {
1514: ALE::Obj<PETSC_MESH_TYPE> mesh;
1518: DMMeshGetMesh(dm, mesh);
1519: {
1520: if (stratumValue < 0) {
1521: if (start) *start = mesh->getSieve()->getChart().min();
1522: if (end) *end = mesh->getSieve()->getChart().max();
1523: } else {
1524: const Obj<PETSC_MESH_TYPE::label_sequence>& stratum = mesh->depthStratum(stratumValue);
1525: if (start) *start = *stratum->begin();
1526: if (end) *end = *stratum->rbegin()+1;
1527: }
1528: }
1529: return(0);
1530: }
1534: PetscErrorCode DMMeshGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) {
1535: ALE::Obj<PETSC_MESH_TYPE> mesh;
1539: DMMeshGetMesh(dm, mesh);
1540: {
1541: const Obj<PETSC_MESH_TYPE::label_sequence>& stratum = mesh->heightStratum(stratumValue);
1542: if (start) *start = *stratum->begin();
1543: if (end) *end = *stratum->rbegin()+1;
1544: }
1545: return(0);
1546: }
1550: PetscErrorCode DMMeshCreateSection(DM dm, PetscInt dim, PetscInt numDof[], const char bcName[], PetscInt bcValue, PetscSection *section) {
1551: ALE::Obj<PETSC_MESH_TYPE> mesh;
1552: PetscInt pStart = 0, pEnd = 0, maxConstraints = 0;
1556: PetscSectionCreate(((PetscObject) dm)->comm, section);
1557: DMMeshGetDepthStratum(dm, -1, &pStart, &pEnd);
1558: PetscSectionSetChart(*section, pStart, pEnd);
1559: for(PetscInt d = 0; d <= dim; ++d) {
1560: DMMeshGetDepthStratum(dm, d, &pStart, &pEnd);
1561: for(PetscInt p = pStart; p < pEnd; ++p) {
1562: PetscSectionSetDof(*section, p, numDof[d]);
1563: }
1564: }
1565: DMMeshGetMesh(dm, mesh);
1566: if (bcName) {
1567: const Obj<PETSC_MESH_TYPE::label_sequence>& boundary = mesh->getLabelStratum(bcName, bcValue);
1569: for(PETSC_MESH_TYPE::label_sequence::iterator e_iter = boundary->begin(); e_iter != boundary->end(); ++e_iter) {
1570: const int n = numDof[mesh->depth(*e_iter)];
1572: maxConstraints = PetscMax(maxConstraints, n);
1573: PetscSectionSetConstraintDof(*section, *e_iter, n);
1574: }
1575: }
1576: PetscSectionSetUp(*section);
1577: if (maxConstraints) {
1578: PetscInt *indices;
1580: PetscMalloc(maxConstraints * sizeof(PetscInt), &indices);
1581: PetscSectionGetChart(*section, &pStart, &pEnd);
1582: for(PetscInt p = pStart; p < pEnd; ++p) {
1583: PetscInt cDof;
1585: PetscSectionGetConstraintDof(*section, p, &cDof);
1586: if (cDof) {
1587: if (cDof > maxConstraints) {SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_LIB, "Likely memory corruption, poitn %d cDof %d > maxConstraints %d", p, cDof, maxConstraints);}
1588: for(PetscInt d = 0; d < cDof; ++d) {
1589: indices[d] = d;
1590: }
1591: PetscSectionSetConstraintIndices(*section, p, indices);
1592: }
1593: }
1594: PetscFree(indices);
1595: }
1596: return(0);
1597: }
1601: PetscErrorCode DMMeshGetSection(DM dm, const char name[], PetscSection *section) {
1602: ALE::Obj<PETSC_MESH_TYPE> mesh;
1606: DMMeshGetMesh(dm, mesh);
1607: {
1608: const Obj<PETSC_MESH_TYPE::real_section_type>& s = mesh->getRealSection(name);
1609: const PetscInt pStart = s->getChart().min();
1610: const PetscInt pEnd = s->getChart().max();
1612: PetscSectionCreate(((PetscObject) dm)->comm, section);
1613: PetscSectionSetChart(*section, pStart, pEnd);
1614: for(PetscInt p = pStart; p < pEnd; ++p) {
1615: PetscSectionSetDof(*section, p, s->getFiberDimension(p));
1616: PetscSectionSetConstraintDof(*section, p, s->getConstraintDimension(p));
1617: }
1618: PetscSectionSetUp(*section);
1619: for(PetscInt p = pStart; p < pEnd; ++p) {
1620: PetscSectionSetConstraintIndices(*section, p, (PetscInt *) s->getConstraintDof(p));
1621: }
1622: }
1623: return(0);
1624: }
1628: PetscErrorCode DMMeshSetSection(DM dm, const char name[], PetscSection section) {
1629: ALE::Obj<PETSC_MESH_TYPE> mesh;
1633: DMMeshGetMesh(dm, mesh);
1634: {
1635: const Obj<PETSC_MESH_TYPE::real_section_type>& s = mesh->getRealSection(name);
1636: PetscInt pStart, pEnd;
1638: PetscSectionGetChart(section, &pStart, &pEnd);
1639: s->setChart(PETSC_MESH_TYPE::real_section_type::chart_type(pStart, pEnd));
1640: for(PetscInt p = pStart; p < pEnd; ++p) {
1641: PetscInt fDim, cDim;
1643: PetscSectionGetDof(section, p, &fDim);
1644: s->setFiberDimension(p, fDim);
1645: PetscSectionGetConstraintDof(section, p, &cDim);
1646: if (cDim) {s->setConstraintDimension(p, cDim);}
1647: }
1648: s->allocatePoint();
1649: for(PetscInt p = pStart; p < pEnd; ++p) {
1650: PetscInt *indices;
1652: PetscSectionGetConstraintIndices(section, p, &indices);
1653: s->setConstraintDof(p, indices);
1654: }
1655: {
1656: PetscBool isDefault;
1658: PetscStrcmp(name, "default", &isDefault);
1659: if (isDefault) {
1660: PetscInt maxDof = 0;
1662: for(PetscInt p = pStart; p < pEnd; ++p) {
1663: PetscInt fDim;
1665: PetscSectionGetDof(section, p, &fDim);
1666: maxDof = PetscMax(maxDof, fDim);
1667: }
1668: mesh->setMaxDof(maxDof);
1669: }
1670: }
1671: }
1672: return(0);
1673: }
1677: PetscErrorCode DMMeshGetDefaultSection(DM dm, PetscSection *section) {
1681: DMMeshGetSection(dm, "default", section);
1682: return(0);
1683: }
1687: PetscErrorCode DMMeshGetCoordinateSection(DM dm, PetscSection *section) {
1691: DMMeshGetSection(dm, "coordinates", section);
1692: return(0);
1693: }
1697: PetscErrorCode DMMeshGetCoordinateVec(DM dm, Vec *coordinates) {
1698: ALE::Obj<PETSC_MESH_TYPE> mesh;
1702: DMMeshGetMesh(dm, mesh);
1703: {
1704: const Obj<PETSC_MESH_TYPE::real_section_type>& coords = mesh->getRealSection("coordinates");
1705: VecCreateSeqWithArray(PETSC_COMM_SELF, coords->getStorageSize(), coords->restrictSpace(), coordinates);
1706: }
1707: return(0);
1708: }
1712: PetscErrorCode DMMeshComputeCellGeometry(DM dm, PetscInt cell, PetscReal *v0, PetscReal *J, PetscReal *invJ, PetscReal *detJ) {
1713: ALE::Obj<PETSC_MESH_TYPE> mesh;
1717: DMMeshGetMesh(dm, mesh);
1718: {
1719: ALE::Obj<PETSC_MESH_TYPE::real_section_type> coordinates = mesh->getRealSection("coordinates");
1721: mesh->computeElementGeometry(coordinates, cell, v0, J, invJ, *detJ);
1722: }
1723: return(0);
1724: }
1728: PetscErrorCode DMMeshVecGetClosure(DM dm, Vec v, PetscInt point, const PetscScalar *values[]) {
1729: ALE::Obj<PETSC_MESH_TYPE> mesh;
1733: #ifdef PETSC_USE_COMPLEX
1734: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "DMMesh does not support complex closure");
1735: #else
1736: DMMeshGetMesh(dm, mesh);
1737: /* Peeling back IMesh::restrictClosure() */
1738: try {
1739: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s = mesh->getRealSection("default");
1740: const PETSC_MESH_TYPE::real_section_type::value_type *oldStorage = s->restrictSpace();
1741: const PetscInt size = mesh->sizeWithBC(s, point);
1742: ALE::ISieveVisitor::RestrictVisitor<PETSC_MESH_TYPE::real_section_type> rV(*s, size, s->getRawArray(size));
1743: PetscScalar *array;
1745: VecGetArray(v, &array);
1746: s->setStorage(array);
1747: if (mesh->depth() == 1) {
1748: rV.visitPoint(point, 0);
1749: // Cone is guarateed to be ordered correctly
1750: mesh->getSieve()->orientedCone(point, rV);
1751: } else {
1752: ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type,ALE::ISieveVisitor::RestrictVisitor<PETSC_MESH_TYPE::real_section_type> > pV((int) pow((double) mesh->getSieve()->getMaxConeSize(), mesh->depth())+1, rV, true);
1754: ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(*mesh->getSieve(), point, pV);
1755: }
1756: s->setStorage((PETSC_MESH_TYPE::real_section_type::value_type *) oldStorage);
1757: VecRestoreArray(v, &array);
1758: *values = rV.getValues();
1759: } catch(ALE::Exception e) {
1760: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid argument: %s", e.message());
1761: }
1762: #endif
1763: return(0);
1764: }
1768: PetscErrorCode DMMeshVecSetClosure(DM dm, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) {
1769: ALE::Obj<PETSC_MESH_TYPE> mesh;
1773: #ifdef PETSC_USE_COMPLEX
1774: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "DMMesh does not support complex closure");
1775: #else
1776: DMMeshGetMesh(dm, mesh);
1777: /* Peeling back IMesh::update() and IMesh::updateAdd() */
1778: try {
1779: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s = mesh->getRealSection("default");
1780: const PETSC_MESH_TYPE::real_section_type::value_type *oldStorage = s->restrictSpace();
1781: PetscScalar *array;
1783: VecGetArray(v, &array);
1784: s->setStorage(array);
1786: if (mode == INSERT_VALUES) {
1787: ALE::ISieveVisitor::UpdateVisitor<PETSC_MESH_TYPE::real_section_type> uV(*s, values);
1788: if (mesh->depth() == 1) {
1789: uV.visitPoint(point, 0);
1790: // Cone is guarateed to be ordered correctly
1791: mesh->getSieve()->orientedCone(point, uV);
1792: } else {
1793: ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type,ALE::ISieveVisitor::UpdateVisitor<PETSC_MESH_TYPE::real_section_type> > pV((int) pow((double) mesh->getSieve()->getMaxConeSize(), mesh->depth())+1, uV, true);
1795: ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(*mesh->getSieve(), point, pV);
1796: }
1797: } else {
1798: ALE::ISieveVisitor::UpdateAddVisitor<PETSC_MESH_TYPE::real_section_type> uV(*s, values);
1799: if (mesh->depth() == 1) {
1800: uV.visitPoint(point, 0);
1801: // Cone is guarateed to be ordered correctly
1802: mesh->getSieve()->orientedCone(point, uV);
1803: } else {
1804: ALE::ISieveVisitor::PointRetriever<PETSC_MESH_TYPE::sieve_type,ALE::ISieveVisitor::UpdateAddVisitor<PETSC_MESH_TYPE::real_section_type> > pV((int) pow((double) mesh->getSieve()->getMaxConeSize(), mesh->depth())+1, uV, true);
1806: ALE::ISieveTraversal<PETSC_MESH_TYPE::sieve_type>::orientedClosure(*mesh->getSieve(), point, pV);
1807: }
1808: }
1810: s->setStorage((PETSC_MESH_TYPE::real_section_type::value_type *) oldStorage);
1811: VecRestoreArray(v, &array);
1812: } catch(ALE::Exception e) {
1813: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid argument: %s", e.message());
1814: }
1815: #endif
1816: return(0);
1817: }
1821: PetscErrorCode DMMeshMatSetClosure(DM dm, Mat A, PetscInt point, PetscScalar values[], InsertMode mode) {
1822: ALE::Obj<PETSC_MESH_TYPE> mesh;
1826: #ifdef PETSC_USE_COMPLEX
1827: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "DMMesh does not support complex closure");
1828: #else
1829: DMMeshGetMesh(dm, mesh);
1830: /* Copying from updateOperator() */
1831: try {
1832: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s = mesh->getRealSection("default");
1833: const ALE::Obj<PETSC_MESH_TYPE::order_type>& globalOrder = mesh->getFactory()->getGlobalOrder(mesh, s->getName(), s);
1834: typedef ALE::ISieveVisitor::IndicesVisitor<PETSC_MESH_TYPE::real_section_type,PETSC_MESH_TYPE::order_type,PetscInt> visitor_type;
1835: visitor_type iV(*s, *globalOrder, (int) pow((double) mesh->getSieve()->getMaxConeSize(), mesh->depth())*mesh->getMaxDof(), mesh->depth() > 1);
1837: updateOperator(A, *mesh->getSieve(), iV, point, values, mode);
1838: } catch(ALE::Exception e) {
1839: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid argument: %s", e.message());
1840: }
1841: #endif
1842: return(0);
1843: }
1847: /*@C
1848: DMMeshHasSectionReal - Determines whether this mesh has a SectionReal with the given name.
1850: Not Collective
1852: Input Parameters:
1853: + mesh - The DMMesh object
1854: - name - The section name
1856: Output Parameter:
1857: . flag - True if the SectionReal is present in the DMMesh
1859: Level: intermediate
1861: .keywords: mesh, elements
1862: .seealso: DMMeshCreate()
1863: @*/
1864: PetscErrorCode DMMeshHasSectionReal(DM dm, const char name[], PetscBool *flag)
1865: {
1866: ALE::Obj<PETSC_MESH_TYPE> m;
1870: DMMeshGetMesh(dm, m);
1871: *flag = (PetscBool) m->hasRealSection(std::string(name));
1872: return(0);
1873: }
1877: /*@C
1878: DMMeshGetSectionReal - Returns a SectionReal of the given name from the DMMesh.
1880: Collective on DMMesh
1882: Input Parameters:
1883: + mesh - The DMMesh object
1884: - name - The section name
1886: Output Parameter:
1887: . section - The SectionReal
1889: Note: The section is a new object, and must be destroyed by the user
1891: Level: intermediate
1893: .keywords: mesh, elements
1895: .seealso: DMMeshCreate(), SectionRealDestroy()
1896: @*/
1897: PetscErrorCode DMMeshGetSectionReal(DM dm, const char name[], SectionReal *section)
1898: {
1899: ALE::Obj<PETSC_MESH_TYPE> m;
1900: bool has;
1901: PetscErrorCode ierr;
1904: DMMeshGetMesh(dm, m);
1905: SectionRealCreate(m->comm(), section);
1906: PetscObjectSetName((PetscObject) *section, name);
1907: has = m->hasRealSection(std::string(name));
1908: SectionRealSetSection(*section, m->getRealSection(std::string(name)));
1909: SectionRealSetBundle(*section, m);
1910: if (!has) {
1911: m->getRealSection(std::string(name))->setChart(m->getSieve()->getChart());
1912: }
1913: return(0);
1914: }
1918: /*@C
1919: DMMeshSetSectionReal - Puts a SectionReal of the given name into the DMMesh.
1921: Collective on DMMesh
1923: Input Parameters:
1924: + mesh - The DMMesh object
1925: - section - The SectionReal
1927: Note: This takes the section name from the PETSc object
1929: Level: intermediate
1931: .keywords: mesh, elements
1932: .seealso: DMMeshCreate()
1933: @*/
1934: PetscErrorCode DMMeshSetSectionReal(DM dm, SectionReal section)
1935: {
1936: ALE::Obj<PETSC_MESH_TYPE> m;
1937: ALE::Obj<PETSC_MESH_TYPE::real_section_type> s;
1938: const char *name;
1942: DMMeshGetMesh(dm, m);
1943: PetscObjectGetName((PetscObject) section, &name);
1944: SectionRealGetSection(section, s);
1945: m->setRealSection(std::string(name), s);
1946: return(0);
1947: }
1951: /*@C
1952: DMMeshHasSectionInt - Determines whether this mesh has a SectionInt with the given name.
1954: Not Collective
1956: Input Parameters:
1957: + mesh - The DMMesh object
1958: - name - The section name
1960: Output Parameter:
1961: . flag - True if the SectionInt is present in the DMMesh
1963: Level: intermediate
1965: .keywords: mesh, elements
1966: .seealso: DMMeshCreate()
1967: @*/
1968: PetscErrorCode DMMeshHasSectionInt(DM dm, const char name[], PetscBool *flag)
1969: {
1970: ALE::Obj<PETSC_MESH_TYPE> m;
1974: DMMeshGetMesh(dm, m);
1975: *flag = (PetscBool) m->hasIntSection(std::string(name));
1976: return(0);
1977: }
1981: /*@C
1982: DMMeshGetSectionInt - Returns a SectionInt of the given name from the DMMesh.
1984: Collective on DMMesh
1986: Input Parameters:
1987: + mesh - The DMMesh object
1988: - name - The section name
1990: Output Parameter:
1991: . section - The SectionInt
1993: Note: The section is a new object, and must be destroyed by the user
1995: Level: intermediate
1997: .keywords: mesh, elements
1998: .seealso: DMMeshCreate()
1999: @*/
2000: PetscErrorCode DMMeshGetSectionInt(DM dm, const char name[], SectionInt *section)
2001: {
2002: ALE::Obj<PETSC_MESH_TYPE> m;
2003: bool has;
2004: PetscErrorCode ierr;
2007: DMMeshGetMesh(dm, m);
2008: SectionIntCreate(m->comm(), section);
2009: PetscObjectSetName((PetscObject) *section, name);
2010: has = m->hasIntSection(std::string(name));
2011: SectionIntSetSection(*section, m->getIntSection(std::string(name)));
2012: SectionIntSetBundle(*section, m);
2013: if (!has) {
2014: m->getIntSection(std::string(name))->setChart(m->getSieve()->getChart());
2015: }
2016: return(0);
2017: }
2021: /*@C
2022: DMMeshSetSectionInt - Puts a SectionInt of the given name into the DMMesh.
2024: Collective on DMMesh
2026: Input Parameters:
2027: + mesh - The DMMesh object
2028: - section - The SectionInt
2030: Note: This takes the section name from the PETSc object
2032: Level: intermediate
2034: .keywords: mesh, elements
2035: .seealso: DMMeshCreate()
2036: @*/
2037: PetscErrorCode DMMeshSetSectionInt(DM dm, SectionInt section)
2038: {
2039: ALE::Obj<PETSC_MESH_TYPE> m;
2040: ALE::Obj<PETSC_MESH_TYPE::int_section_type> s;
2041: const char *name;
2045: DMMeshGetMesh(dm, m);
2046: PetscObjectGetName((PetscObject) section, &name);
2047: SectionIntGetSection(section, s);
2048: m->setIntSection(std::string(name), s);
2049: return(0);
2050: }
2054: /*@C
2055: SectionGetArray - Returns the array underlying the Section.
2057: Not Collective
2059: Input Parameters:
2060: + mesh - The DMMesh object
2061: - name - The section name
2063: Output Parameters:
2064: + numElements - The number of mesh element with values
2065: . fiberDim - The number of values per element
2066: - array - The array
2068: Level: intermediate
2070: .keywords: mesh, elements
2071: .seealso: DMMeshCreate()
2072: @*/
2073: PetscErrorCode SectionGetArray(DM dm, const char name[], PetscInt *numElements, PetscInt *fiberDim, PetscScalar *array[])
2074: {
2075: ALE::Obj<PETSC_MESH_TYPE> m;
2076: PetscErrorCode ierr;
2079: DMMeshGetMesh(dm, m);
2080: const Obj<PETSC_MESH_TYPE::real_section_type>& section = m->getRealSection(std::string(name));
2081: if (section->size() == 0) {
2082: *numElements = 0;
2083: *fiberDim = 0;
2084: *array = NULL;
2085: return(0);
2086: }
2087: const PETSC_MESH_TYPE::real_section_type::chart_type& chart = section->getChart();
2088: /* const int depth = m->depth(*chart.begin()); */
2089: /* *numElements = m->depthStratum(depth)->size(); */
2090: /* *fiberDim = section->getFiberDimension(*chart.begin()); */
2091: /* *array = (PetscScalar *) m->restrict(section); */
2092: int fiberDimMin = section->getFiberDimension(*chart.begin());
2093: int numElem = 0;
2095: for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2096: const int fiberDim = section->getFiberDimension(*c_iter);
2098: if (fiberDim < fiberDimMin) fiberDimMin = fiberDim;
2099: }
2100: for(PETSC_MESH_TYPE::real_section_type::chart_type::const_iterator c_iter = chart.begin(); c_iter != chart.end(); ++c_iter) {
2101: const int fiberDim = section->getFiberDimension(*c_iter);
2103: numElem += fiberDim/fiberDimMin;
2104: }
2105: *numElements = numElem;
2106: *fiberDim = fiberDimMin;
2107: *array = (PetscScalar *) section->restrictSpace();
2108: return(0);
2109: }
2113: inline void ExpandInterval(const ALE::Point& interval, int indices[], int& indx)
2114: {
2115: const int end = interval.prefix + interval.index;
2116: for(int i = interval.index; i < end; i++) {
2117: indices[indx++] = i;
2118: }
2119: }
2123: inline void ExpandInterval_New(ALE::Point interval, PetscInt indices[], PetscInt *indx)
2124: {
2125: for(int i = 0; i < interval.prefix; i++) {
2126: indices[(*indx)++] = interval.index + i;
2127: }
2128: for(int i = 0; i < -interval.prefix; i++) {
2129: indices[(*indx)++] = -1;
2130: }
2131: }
2134: /******************************** FEM Support **********************************/
2138: PetscErrorCode DMMeshPrintCellVector(PetscInt c, const char name[], PetscInt len, const PetscScalar x[]) {
2142: PetscPrintf(PETSC_COMM_SELF, "Cell %d Element %s\n", c, name);
2143: for(PetscInt f = 0; f < len; ++f) {
2144: PetscPrintf(PETSC_COMM_SELF, " | %g |\n", x[f]);
2145: }
2146: return(0);
2147: }
2151: PetscErrorCode DMMeshPrintCellMatrix(PetscInt c, const char name[], PetscInt rows, PetscInt cols, const PetscScalar A[]) {
2155: PetscPrintf(PETSC_COMM_SELF, "Cell %d Element %s\n", c, name);
2156: for(int f = 0; f < rows; ++f) {
2157: PetscPrintf(PETSC_COMM_SELF, " |");
2158: for(int g = 0; g < cols; ++g) {
2159: PetscPrintf(PETSC_COMM_SELF, " %g", A[f*cols+g]);
2160: }
2161: PetscPrintf(PETSC_COMM_SELF, " |\n");
2162: }
2163: return(0);
2164: }