OGS
MeshIO.cpp
Go to the documentation of this file.
1
19#include "MeshIO.h"
20
21#include <iomanip>
22#include <memory>
23#include <sstream>
24
25#include "BaseLib/Error.h"
26#include "BaseLib/FileTools.h"
27#include "BaseLib/Logging.h"
28#include "BaseLib/StringTools.h"
30#include "MeshLib/Location.h"
31#include "MeshLib/Node.h"
33
34namespace MeshLib
35{
36namespace IO
37{
38namespace Legacy
39{
40MeshIO::MeshIO() = default;
41
42MeshLib::Mesh* MeshIO::loadMeshFromFile(const std::string& file_name)
43{
44 INFO("Reading OGS legacy mesh ... ");
45
46 std::ifstream in(file_name.c_str(), std::ios::in);
47 if (!in.is_open())
48 {
49 WARN("MeshIO::loadMeshFromFile() - Could not open file {:s}.",
50 file_name);
51 return nullptr;
52 }
53
54 std::string line_string;
55 getline(in, line_string);
56
57 std::vector<MeshLib::Node*> nodes;
58 std::vector<MeshLib::Element*> elements;
59 std::vector<std::size_t> materials;
60
61 if (line_string.find("#FEM_MSH") != std::string::npos) // OGS mesh file
62 {
63 while (!in.eof())
64 {
65 getline(in, line_string);
66
67 // check keywords
68 if (line_string.find("#STOP") != std::string::npos)
69 {
70 break;
71 }
72 if (line_string.find("$NODES") != std::string::npos)
73 {
74 double x;
75 double y;
76 double z;
77 double double_dummy;
78 unsigned idx;
79 getline(in, line_string);
80 BaseLib::trim(line_string);
81 unsigned nNodes = atoi(line_string.c_str());
82 std::string s;
83 for (unsigned i = 0; i < nNodes; ++i)
84 {
85 getline(in, line_string);
86 std::stringstream iss(line_string);
87 iss >> idx >> x >> y >> z;
88 auto* node(new MeshLib::Node(x, y, z, idx));
89 nodes.push_back(node);
90 iss >> s;
91 if (s.find("$AREA") != std::string::npos)
92 {
93 iss >> double_dummy;
94 }
95 }
96 }
97 else if (line_string.find("$ELEMENTS") != std::string::npos)
98 {
99 getline(in, line_string);
100 BaseLib::trim(line_string);
101 unsigned nElements = atoi(line_string.c_str());
102 for (unsigned i = 0; i < nElements; ++i)
103 {
104 getline(in, line_string);
105 std::stringstream ss(line_string);
106 materials.push_back(readMaterialID(ss));
107 MeshLib::Element* elem(readElement(ss, nodes));
108 if (elem == nullptr)
109 {
110 ERR("Reading mesh element {:d} from file '{:s}' "
111 "failed.",
112 i, file_name);
113 // clean up the elements vector
114 std::for_each(elements.begin(), elements.end(),
115 std::default_delete<MeshLib::Element>());
116 // clean up the nodes vector
117 std::for_each(nodes.begin(), nodes.end(),
118 std::default_delete<MeshLib::Node>());
119 return nullptr;
120 }
121 elements.push_back(elem);
122 }
123 }
124 }
125
126 if (elements.empty())
127 {
128 ERR("MeshIO::loadMeshFromFile() - File did not contain element "
129 "information.");
130 for (auto& node : nodes)
131 {
132 delete node;
133 }
134 return nullptr;
135 }
136
139 elements));
140
141 auto* const material_ids =
143 "MaterialIDs", MeshLib::MeshItemType::Cell, 1);
144 if (!material_ids)
145 {
146 WARN("Could not create PropertyVector for MaterialIDs in Mesh.");
147 }
148 else
149 {
150 material_ids->insert(material_ids->end(), materials.cbegin(),
151 materials.cend());
152 }
153 INFO("\t... finished.");
154 INFO("Nr. Nodes: {:d}.", nodes.size());
155 INFO("Nr. Elements: {:d}.", elements.size());
156
157 in.close();
158 return mesh;
159 }
160
161 in.close();
162 return nullptr;
163}
164
165std::size_t MeshIO::readMaterialID(std::istream& in)
166{
167 unsigned index;
168 unsigned material_id;
169 if (!(in >> index >> material_id))
170 {
171 return std::numeric_limits<std::size_t>::max();
172 }
173 return material_id;
174}
175
177 std::istream& in, const std::vector<MeshLib::Node*>& nodes) const
178{
179 std::string elem_type_str;
181
182 do
183 {
184 if (!(in >> elem_type_str))
185 {
186 return nullptr;
187 }
188 elem_type = MeshLib::String2MeshElemType(elem_type_str);
189 } while (elem_type == MeshLib::MeshElemType::INVALID);
190
191 auto* idx = new unsigned[8];
192 MeshLib::Element* elem;
193
194 switch (elem_type)
195 {
197 {
198 for (int i = 0; i < 2; ++i)
199 {
200 if (!(in >> idx[i]))
201 {
202 return nullptr;
203 }
204 }
205 // edge_nodes array will be deleted from Line object
206 auto** edge_nodes = new MeshLib::Node*[2];
207 for (unsigned k(0); k < 2; ++k)
208 {
209 edge_nodes[k] = nodes[idx[k]];
210 }
211 elem = new MeshLib::Line(edge_nodes);
212 break;
213 }
215 {
216 for (int i = 0; i < 3; ++i)
217 {
218 if (!(in >> idx[i]))
219 {
220 return nullptr;
221 }
222 }
223 auto** tri_nodes = new MeshLib::Node*[3];
224 for (unsigned k(0); k < 3; ++k)
225 {
226 tri_nodes[k] = nodes[idx[k]];
227 }
228 elem = new MeshLib::Tri(tri_nodes);
229 break;
230 }
232 {
233 for (int i = 0; i < 4; ++i)
234 {
235 if (!(in >> idx[i]))
236 {
237 return nullptr;
238 }
239 }
240 auto** quad_nodes = new MeshLib::Node*[4];
241 for (unsigned k(0); k < 4; ++k)
242 {
243 quad_nodes[k] = nodes[idx[k]];
244 }
245 elem = new MeshLib::Quad(quad_nodes);
246 break;
247 }
249 {
250 for (int i = 0; i < 4; ++i)
251 {
252 if (!(in >> idx[i]))
253 {
254 return nullptr;
255 }
256 }
257 auto** tet_nodes = new MeshLib::Node*[4];
258 for (unsigned k(0); k < 4; ++k)
259 {
260 tet_nodes[k] = nodes[idx[k]];
261 }
262 elem = new MeshLib::Tet(tet_nodes);
263 break;
264 }
266 {
267 for (int i = 0; i < 8; ++i)
268 {
269 if (!(in >> idx[i]))
270 {
271 return nullptr;
272 }
273 }
274 auto** hex_nodes = new MeshLib::Node*[8];
275 for (unsigned k(0); k < 8; ++k)
276 {
277 hex_nodes[k] = nodes[idx[k]];
278 }
279 elem = new MeshLib::Hex(hex_nodes);
280 break;
281 }
283 {
284 for (int i = 0; i < 5; ++i)
285 {
286 if (!(in >> idx[i]))
287 {
288 return nullptr;
289 }
290 }
291 auto** pyramid_nodes = new MeshLib::Node*[5];
292 for (unsigned k(0); k < 5; ++k)
293 {
294 pyramid_nodes[k] = nodes[idx[k]];
295 }
296 elem = new MeshLib::Pyramid(pyramid_nodes);
297 break;
298 }
300 {
301 for (int i = 0; i < 6; ++i)
302 {
303 if (!(in >> idx[i]))
304 {
305 return nullptr;
306 }
307 }
308 auto** prism_nodes = new MeshLib::Node*[6];
309 for (unsigned k(0); k < 6; ++k)
310 {
311 prism_nodes[k] = nodes[idx[k]];
312 }
313 elem = new MeshLib::Prism(prism_nodes);
314 break;
315 }
316 default:
317 elem = nullptr;
318 break;
319 }
320
321 delete[] idx;
322
323 return elem;
324}
325
327{
328 if (!_mesh)
329 {
330 WARN("MeshIO::write(): Cannot write: no mesh object specified.");
331 return false;
332 }
333
334 out << "#FEM_MSH\n"
335 << "$PCS_TYPE\n"
336 << " NO_PCS\n"
337 << "$NODES\n"
338 << " ";
339 const std::size_t n_nodes(_mesh->getNumberOfNodes());
340 out << n_nodes << "\n";
341 for (std::size_t i(0); i < n_nodes; ++i)
342 {
343 out << i << " " << *(_mesh->getNode(i)) << "\n";
344 }
345
346 out << "$ELEMENTS\n"
347 << " ";
348
349 if (!_mesh->getProperties().existsPropertyVector<int>("MaterialIDs"))
350 {
351 writeElements(_mesh->getElements(), nullptr, out);
352 }
353 else
354 {
357 _mesh->getProperties().getPropertyVector<int>("MaterialIDs"), out);
358 }
359 out << "#STOP\n";
360
361 return true;
362}
363
365{
366 _mesh = mesh;
367}
368
370 std::vector<MeshLib::Element*> const& ele_vec,
371 MeshLib::PropertyVector<int> const* const material_ids,
372 std::ostream& out) const
373{
374 const std::size_t ele_vector_size(ele_vec.size());
375
376 out << ele_vector_size << "\n";
377 for (std::size_t i(0); i < ele_vector_size; ++i)
378 {
379 auto const& element = *ele_vec[i];
380 if (element.getNumberOfBaseNodes() != element.getNumberOfNodes())
381 {
382 OGS_FATAL(
383 "Found high order element in the mesh that is not required by "
384 "OGS 5 input. High order elements are generated in OGS 5 on "
385 "demand.");
386 }
387
388 out << i << " ";
389 if (!material_ids)
390 {
391 out << "0 ";
392 }
393 else
394 {
395 out << (*material_ids)[i] << " ";
396 }
397 out << ElemType2StringOutput(element.getGeomType()) << " ";
398 unsigned nElemNodes(element.getNumberOfBaseNodes());
399 for (std::size_t j = 0; j < nElemNodes; ++j)
400 {
401 out << element.getNode(j)->getID() << " ";
402 }
403 out << "\n";
404 }
405}
406
408{
410 {
411 return "line";
412 }
414 {
415 return "quad";
416 }
418 {
419 return "hex";
420 }
422 {
423 return "tri";
424 }
426 {
427 return "tet";
428 }
430 {
431 return "pris";
432 }
434 {
435 return "pyra";
436 }
437 return "none";
438}
439
440} // end namespace Legacy
441} // end namespace IO
442} // namespace MeshLib
#define OGS_FATAL(...)
Definition: Error.h:26
Filename manipulation routines.
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:34
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:44
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:39
Definition of the MeshIO class.
Definition of the Node class.
Definition of string helper functions.
std::ostringstream out
The stream to write to.
Definition: Writer.h:46
bool write() override
Write mesh to stream.
Definition: MeshIO.cpp:326
MeshLib::Element * readElement(std::istream &in, const std::vector< MeshLib::Node * > &nodes) const
Definition: MeshIO.cpp:176
MeshLib::Mesh * loadMeshFromFile(const std::string &file_name)
Read mesh from file.
Definition: MeshIO.cpp:42
const MeshLib::Mesh * _mesh
Definition: MeshIO.h:63
static std::size_t readMaterialID(std::istream &in)
Definition: MeshIO.cpp:165
void setMesh(const MeshLib::Mesh *mesh)
Set mesh for writing.
Definition: MeshIO.cpp:364
void writeElements(std::vector< MeshLib::Element * > const &ele_vec, MeshLib::PropertyVector< int > const *const material_ids, std::ostream &out) const
Definition: MeshIO.cpp:369
static std::string ElemType2StringOutput(const MeshLib::MeshElemType t)
Definition: MeshIO.cpp:407
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition: Mesh.h:98
const Node * getNode(std::size_t idx) const
Get the node with the given index.
Definition: Mesh.h:74
Properties & getProperties()
Definition: Mesh.h:123
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition: Mesh.h:89
PropertyVector< T > * createNewPropertyVector(std::string const &name, MeshItemType mesh_item_type, std::size_t n_components=1)
bool existsPropertyVector(std::string const &name) const
PropertyVector< T > const * getPropertyVector(std::string const &name) const
void trim(std::string &str, char ch)
Definition: StringTools.cpp:58
std::string extractBaseNameWithoutExtension(std::string const &pathname)
Definition: FileTools.cpp:180
static const double s
static const double t
MeshElemType String2MeshElemType(const std::string &s)
Given a string of the shortened name of the element type, this returns the corresponding MeshElemType...
Definition: MeshEnums.cpp:95
TemplateElement< MeshLib::TetRule4 > Tet
Definition: Tet.h:25
TemplateElement< MeshLib::LineRule2 > Line
Definition: Line.h:25
TemplateElement< MeshLib::TriRule3 > Tri
Definition: Tri.h:26
TemplateElement< MeshLib::PrismRule6 > Prism
Definition: Prism.h:25
TemplateElement< MeshLib::PyramidRule5 > Pyramid
Definition: Pyramid.h:25
MeshElemType
Types of mesh elements supported by OpenGeoSys. Values are from VTKCellType enum.
Definition: MeshEnums.h:27
TemplateElement< MeshLib::HexRule8 > Hex
Definition: Hex.h:25
TemplateElement< MeshLib::QuadRule4 > Quad
Definition: Quad.h:28