DUNE PDELab (2.8)

gmshwriter.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_GRID_IO_FILE_GMSHWRITER_HH
4#define DUNE_GRID_IO_FILE_GMSHWRITER_HH
5
6#include <fstream>
7#include <iostream>
8#include <iomanip>
9#include <string>
10#include <vector>
11
13#include <dune/geometry/type.hh>
14#include <dune/geometry/referenceelements.hh>
17
18namespace Dune {
19
33 template <class GridView>
35 {
36 private:
37 const GridView gv;
38 int precision;
39
40 static const unsigned int dim = GridView::dimension;
41 static const unsigned int dimWorld = GridView::dimensionworld;
42 static_assert( (dimWorld <= 3), "GmshWriter requires dimWorld <= 3." );
43
45 template<typename Entity>
46 std::size_t nodeIndexFromEntity(const Entity& entity, int i) const {
47 return gv.indexSet().subIndex(entity, i, dim)+1;
48 }
49
53 static std::size_t translateDuneToGmshType(const GeometryType& type) {
54 std::size_t element_type;
55
56 if (type.isLine())
57 element_type = 1;
58 else if (type.isTriangle())
59 element_type = 2;
60 else if (type.isQuadrilateral())
61 element_type = 3;
62 else if (type.isTetrahedron())
63 element_type = 4;
64 else if (type.isHexahedron())
65 element_type = 5;
66 else if (type.isPrism())
67 element_type = 6;
68 else if (type.isPyramid())
69 element_type = 7;
70 else if (type.isVertex())
71 element_type = 15;
72 else
73 DUNE_THROW(Dune::IOError, "GeometryType " << type << " is not supported by gmsh.");
74
75 return element_type;
76 }
77
92 void outputElements(std::ofstream& file, const std::vector<int>& physicalEntities, const std::vector<int>& physicalBoundaries) const {
94 std::size_t counter(1);
95 for (const auto& entity : elements(gv)) {
96 // Check whether the type is compatible. If not, close file and rethrow exception.
97 try {
98 std::size_t element_type = translateDuneToGmshType(entity.type());
99
100 file << counter << " " << element_type;
101 // If present, set the first tag to the physical entity
102 if (!physicalEntities.empty())
103 file << " " << 1 << " " << physicalEntities[elementMapper.index(entity)];
104 else
105 file << " " << 0; // "0" for "I do not use any tags."
106
107 // Output list of nodes.
108 // 3, 5 and 7 got different vertex numbering compared to Dune
109 if (3 == element_type)
110 file << " "
111 << nodeIndexFromEntity(entity, 0) << " " << nodeIndexFromEntity(entity, 1) << " "
112 << nodeIndexFromEntity(entity, 3) << " " << nodeIndexFromEntity(entity, 2);
113 else if (5 == element_type)
114 file << " "
115 << nodeIndexFromEntity(entity, 0) << " " << nodeIndexFromEntity(entity, 1) << " "
116 << nodeIndexFromEntity(entity, 3) << " " << nodeIndexFromEntity(entity, 2) << " "
117 << nodeIndexFromEntity(entity, 4) << " " << nodeIndexFromEntity(entity, 5) << " "
118 << nodeIndexFromEntity(entity, 7) << " " << nodeIndexFromEntity(entity, 6);
119 else if (7 == element_type)
120 file << " "
121 << nodeIndexFromEntity(entity, 0) << " " << nodeIndexFromEntity(entity, 1) << " "
122 << nodeIndexFromEntity(entity, 3) << " " << nodeIndexFromEntity(entity, 2) << " "
123 << nodeIndexFromEntity(entity, 4);
124 else {
125 for (int k = 0; k < entity.geometry().corners(); ++k)
126 file << " " << nodeIndexFromEntity(entity, k);
127 }
128 ++counter;
129
130 file << std::endl;
131
132 // Write boundaries
133 if (!physicalBoundaries.empty()) {
134 auto refElement = referenceElement<typename GridView::ctype,dim>(entity.type());
135 for(const auto& intersection : intersections(gv, entity)) {
136 if(intersection.boundary()) {
137 const auto faceLocalIndex(intersection.indexInInside());
138 file << counter << " " << translateDuneToGmshType(intersection.type())
139 << " " << 1 << " " << physicalBoundaries[intersection.boundarySegmentIndex()];
140 for (int k = 0; k < intersection.geometry().corners(); ++k)
141 {
142 const auto vtxLocalIndex(refElement.subEntity(faceLocalIndex, 1, k, dim));
143 file << " " << nodeIndexFromEntity(entity, vtxLocalIndex);
144 }
145 ++counter;
146 file << std::endl;
147 }
148 }
149 }
150
151 } catch(Exception& e) {
152 file.close();
153 throw;
154 }
155 }
156 }
157
158
165 void outputNodes(std::ofstream& file) const {
166 for (const auto& vertex : vertices(gv)) {
167 const auto globalCoord = vertex.geometry().center();
168 const auto nodeIndex = gv.indexSet().index(vertex)+1; // Start counting indices by "1".
169
170 if (1 == dimWorld)
171 file << nodeIndex << " " << globalCoord[0] << " " << 0 << " " << 0 << std::endl;
172 else if (2 == dimWorld)
173 file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << 0 << std::endl;
174 else // (3 == dimWorld)
175 file << nodeIndex << " " << globalCoord[0] << " " << globalCoord[1] << " " << globalCoord[2] << std::endl;
176 }
177 }
178
179 public:
185 GmshWriter(const GridView& gridView, int numDigits=6) : gv(gridView), precision(numDigits) {}
186
191 void setPrecision(int numDigits) {
192 precision = numDigits;
193 }
194
216 void write(const std::string& fileName,
217 const std::vector<int>& physicalEntities=std::vector<int>(),
218 const std::vector<int>& physicalBoundaries=std::vector<int>()) const {
219 // Open file
220 std::ofstream file(fileName.c_str());
221 if (!file.is_open())
222 DUNE_THROW(Dune::IOError, "Could not open " << fileName << " with write access.");
223
224 // Set precision
225 file << std::setprecision( precision );
226
227 // Output Header
228 file << "$MeshFormat" << std::endl
229 << "2.0 0 " << sizeof(double) << std::endl // "2.0" for "version 2.0", "0" for ASCII
230 << "$EndMeshFormat" << std::endl;
231
232 // Output Nodes
233 file << "$Nodes" << std::endl
234 << gv.size(dim) << std::endl;
235
236 outputNodes(file);
237
238 file << "$EndNodes" << std::endl;
239
240 // Output Elements;
241 int boundariesSize(0);
242 if(!physicalBoundaries.empty())
243 for(const auto& entity : elements(gv))
244 for(const auto& intersection : intersections(gv, entity))
245 if(intersection.boundary())
246 ++boundariesSize;
247
248 file << "$Elements" << std::endl
249 << gv.size(0) + boundariesSize<< std::endl;
250
251 outputElements(file, physicalEntities, physicalBoundaries);
252
253 file << "$EndElements" << std::endl;
254 }
255
256 };
257
258} // namespace Dune
259
260#endif // DUNE_GRID_IO_FILE_GMSHWRITER_HH
Wrapper class for entities.
Definition: entity.hh:64
Geometry geometry() const
obtain geometric realization of the entity
Definition: entity.hh:143
GeometryType type() const
Return the name of the reference element. The type can be used to access the Dune::ReferenceElement.
Definition: entity.hh:148
Base class for Dune-Exceptions.
Definition: exceptions.hh:94
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:123
constexpr bool isPyramid() const
Return true if entity is a pyramid.
Definition: type.hh:313
constexpr bool isTetrahedron() const
Return true if entity is a tetrahedron.
Definition: type.hh:308
constexpr bool isPrism() const
Return true if entity is a prism.
Definition: type.hh:318
constexpr bool isVertex() const
Return true if entity is a vertex.
Definition: type.hh:288
constexpr bool isTriangle() const
Return true if entity is a triangle.
Definition: type.hh:298
constexpr bool isLine() const
Return true if entity is a line segment.
Definition: type.hh:293
constexpr bool isQuadrilateral() const
Return true if entity is a quadrilateral.
Definition: type.hh:303
constexpr bool isHexahedron() const
Return true if entity is a hexahedron.
Definition: type.hh:323
Write Gmsh mesh file.
Definition: gmshwriter.hh:35
GmshWriter(const GridView &gridView, int numDigits=6)
Constructor expecting GridView of Grid to be written.
Definition: gmshwriter.hh:185
void setPrecision(int numDigits)
Set the number of digits to be used when writing the vertices. By default is 6.
Definition: gmshwriter.hh:191
void write(const std::string &fileName, const std::vector< int > &physicalEntities=std::vector< int >(), const std::vector< int > &physicalBoundaries=std::vector< int >()) const
Write given grid in Gmsh 2.0 compatible ASCII file.
Definition: gmshwriter.hh:216
Grid view abstract base class.
Definition: gridview.hh:63
Default exception class for I/O errors.
Definition: exceptions.hh:229
Index index(const EntityType &e) const
Map entity to starting index in array for dof block.
Definition: mcmgmapper.hh:169
Different resources needed by all grid implementations.
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
const IndexSet & indexSet() const
obtain the index set
Definition: gridview.hh:175
int size(int codim) const
obtain number of entities in a given codimension
Definition: gridview.hh:181
@ dimension
The dimension of the grid.
Definition: gridview.hh:130
@ dimensionworld
The dimension of the world the grid lives in.
Definition: gridview.hh:134
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:504
MCMGLayout mcmgElementLayout()
layout for elements (codim-0 entities)
Definition: mcmgmapper.hh:95
Mapper for multiple codim and multiple geometry types.
Dune namespace.
Definition: alignedallocator.hh:11
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)