dune-grid 2.8.0
Loading...
Searching...
No Matches
gmshwriter.hh
Go to the documentation of this file.
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>
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
Mapper for multiple codim and multiple geometry types.
size_type dim() const
#define DUNE_THROW(E, m)
const IndexSet & indexSet() const
obtain the index set
Definition common/gridview.hh:175
int size(int codim) const
obtain number of entities in a given codimension
Definition common/gridview.hh:181
@ dimensionworld
The dimension of the world the grid lives in.
Definition common/gridview.hh:134
@ dimension
The dimension of the grid.
Definition common/gridview.hh:130
MCMGLayout mcmgElementLayout()
layout for elements (codim-0 entities)
Definition mcmgmapper.hh:95
Include standard header files.
constexpr bool isPyramid() const
constexpr bool isTetrahedron() const
constexpr bool isPrism() const
constexpr bool isVertex() const
constexpr bool isTriangle() const
constexpr bool isLine() const
constexpr bool isQuadrilateral() const
constexpr bool isHexahedron() const
Wrapper class for entities.
Definition common/entity.hh:64
Geometry geometry() const
obtain geometric realization of the entity
Definition common/entity.hh:143
GeometryType type() const
Return the name of the reference element. The type can be used to access the Dune::ReferenceElement.
Definition common/entity.hh:148
Grid view abstract base class.
Definition common/gridview.hh:63
Implementation class for a multiple codim and multiple geometry type mapper.
Definition mcmgmapper.hh:127
Index index(const EntityType &e) const
Map entity to starting index in array for dof block.
Definition mcmgmapper.hh:169
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
Different resources needed by all grid implementations.
T c_str(T... args)
T close(T... args)
T empty(T... args)
T endl(T... args)
T is_open(T... args)
T setprecision(T... args)