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