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