PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
rw::reader::MshReader Class Reference

A class to read Gmsh (msh) mesh files. More...

#include <mshReader.h>

Collaboration diagram for rw::reader::MshReader:

Public Member Functions

 MshReader (const std::string &filename)
 Constructor.
 
void readMesh (size_t dim, std::vector< util::Point > *nodes, size_t &element_type, size_t &num_elems, std::vector< size_t > *enc, std::vector< std::vector< size_t > > *nec, std::vector< double > *volumes, bool is_fd=false)
 Reads mesh data into node file and element file.
 
void readNodes (std::vector< util::Point > *nodes)
 Reads nodal position.
 
void readCells (size_t dim, size_t &element_type, size_t &num_elems, std::vector< size_t > *enc, std::vector< std::vector< size_t > > *nec)
 Reads cell data, i.e. element-node connectivity and node-element connectivity.
 
bool readPointData (const std::string &name, std::vector< util::Point > *data)
 reads point data from .vtu file
 
bool readPointData (const std::string &name, std::vector< double > *data)
 reads point data from .vtu file
 
void close ()
 Close the file.
 

Private Attributes

std::string d_filename
 filename
 
std::ifstream d_file
 vtk/vtu file
 

Detailed Description

A class to read Gmsh (msh) mesh files.

This class can only handle Gmsh version 2.0, 2.1, 2.2.

Definition at line 28 of file mshReader.h.

Constructor & Destructor Documentation

◆ MshReader()

rw::reader::MshReader::MshReader ( const std::string &  filename)
explicit

Constructor.

Parameters
filenameName of the mesh file

Definition at line 35 of file mshReader.cpp.

36 : d_filename(filename){};
std::string d_filename
filename
Definition mshReader.h:94

Member Function Documentation

◆ close()

void rw::reader::MshReader::close ( )

Close the file.

Definition at line 677 of file mshReader.cpp.

677{}

◆ readCells()

void rw::reader::MshReader::readCells ( size_t  dim,
size_t &  element_type,
size_t &  num_elems,
std::vector< size_t > *  enc,
std::vector< std::vector< size_t > > *  nec 
)

Reads cell data, i.e. element-node connectivity and node-element connectivity.

Parameters
dimDimension
element_typeType of element
num_elemsNumber of elements
encElement-node connectivity
necNode-element connectivity

Definition at line 353 of file mshReader.cpp.

355 {
356
358 throw std::runtime_error(
360 << "Error: Filename = " << d_filename <<
361 " in MshReader is either nonexistent or empty.\n");
362 }
363
364 // open file
365 if (d_file) d_file.close();
366
367 d_file.open(d_filename);
368
369 if (!d_file) {
370 throw std::runtime_error(
372 << "Error: Can not open file = " << d_filename + ".msh"
373 << ".\n");
374 }
375
376 // specify type of element to read
377 if (dim != 2 and dim != 3) {
378 throw std::runtime_error(
380 << "Error: MshReader currently only supports reading of "
381 "triangle/quadrangle elements in dimension 2 and tetragonal "
382 "elements in 3.\n");
383 }
384
385 enc->clear();
386 nec->clear();
387
388 bool have_nodes = false;
389 bool read_elements = false;
390
391 std::string line;
392 while (std::getline(d_file, line)) {
393 trim_inplace(line);
394 if (line.empty())
395 continue;
396
397 if (!have_nodes && (line == "$Nodes" || line == "$NOD" || line == "$NOE")) {
398 if (!std::getline(d_file, line)) {
399 throw std::runtime_error(
401 << "Error: Unexpected end of file in MshReader (readCells node count).\n");
402 }
403 trim_inplace(line);
404 unsigned int num_nodes = 0;
405 {
406 std::istringstream ns(line);
407 ns >> num_nodes;
408 }
409 for (unsigned int i = 0; i < num_nodes; ++i) {
410 if (!std::getline(d_file, line)) {
411 throw std::runtime_error(
413 << "Error: Unexpected end of file in MshReader (readCells skip nodes).\n");
414 }
415 }
416 nec->assign(num_nodes, {});
417 have_nodes = true;
418 continue;
419 }
420
421 if (have_nodes && (line == "$Elements" || line == "$ELM")) {
422 read_elements = true;
423 if (!std::getline(d_file, line)) {
424 throw std::runtime_error(
426 << "Error: Unexpected end of file in MshReader (readCells element count).\n");
427 }
428 trim_inplace(line);
429 unsigned int num_elem = 0;
430 {
431 std::istringstream es(line);
432 es >> num_elem;
433 }
434
435 size_t elem_counter = 0;
436 bool found_tri = false;
437 bool found_quad = false;
438
439 for (unsigned int iel = 0; iel < num_elem; ++iel) {
440 if (!std::getline(d_file, line)) {
441 throw std::runtime_error(
443 << "Error: Unexpected end of file in MshReader (readCells elements).\n");
444 }
445 trim_inplace(line);
446 std::istringstream ls(line);
447 unsigned int id;
448 unsigned int type;
449 unsigned int ntags;
450 ls >> id >> type >> ntags;
451 int tag = 0;
452 for (unsigned int j = 0; j < ntags; j++)
453 ls >> tag;
454
455 bool read_this_element = false;
456 unsigned int num_nodes_con = 0;
457
458 if (type == util::msh_type_triangle and dim == 2) {
459 read_this_element = true;
460 found_tri = true;
461 element_type = util::vtk_type_triangle;
462 num_nodes_con =
464 } else if (type == util::msh_type_quadrangle and dim == 2) {
465 read_this_element = true;
466 found_quad = true;
467 element_type = util::vtk_type_quad;
468 num_nodes_con =
470 } else if (type == util::msh_type_tetrahedron and dim == 3) {
471 read_this_element = true;
472 element_type = util::vtk_type_tetra;
473 num_nodes_con =
475 } else if (type == util::msh_type_hexahedron and dim == 3) {
476 read_this_element = true;
477 element_type = util::vtk_type_hexahedron;
478 num_nodes_con =
480 }
481
482 if (read_this_element) {
483 for (unsigned int i = 0; i < num_nodes_con; i++) {
484 unsigned int node_id;
485 ls >> node_id;
486 enc->push_back(node_id - 1);
487 (*nec)[node_id - 1].push_back(elem_counter);
488 }
489 elem_counter++;
490 } else {
491 unsigned int n_skip = 0;
492 if (type < 16)
493 n_skip = static_cast<unsigned int>(util::msh_map_element_to_num_nodes[type]);
494 if (n_skip > 0) {
495 unsigned int dummy;
496 for (unsigned int i = 0; i < n_skip; i++)
497 ls >> dummy;
498 } else {
499 unsigned int dummy;
500 while (ls >> dummy) {
501 }
502 }
503 }
504 }
505
506 if (found_quad and found_tri) {
507 throw std::runtime_error(
509 << "Error: Check mesh file. It appears to have both "
510 "quadrangle elements and triangle elements. "
511 "Currently we only support one kind of elements.\n");
512 }
513
514 num_elems = elem_counter;
515 break;
516 }
517 }
518
519 if (!have_nodes || !read_elements) {
520 throw std::runtime_error(
522 << "Error: MshReader::readCells: incomplete .msh file: " << d_filename << "\n");
523 }
524
525 // close file
526 d_file.close();
527}
std::ifstream d_file
vtk/vtu file
Definition mshReader.h:97
Collects a message with stream syntax for use in an exception.
Definition io.h:52
static const int msh_type_quadrangle
Integer flag for quadrangle element.
static const int vtk_type_triangle
Integer flag for triangle element.
static const int vtk_type_quad
Integer flag for quad element.
static const int vtk_type_tetra
Integer flag for tetrahedron element.
static int msh_map_element_to_num_nodes[16]
Map from element type to number of nodes (for msh)
static const int msh_type_hexahedron
Integer flag for hexahedron element.
static const int vtk_type_hexahedron
Integer flag for hexahedron element.
static const int msh_type_triangle
Integer flag for triangle element.
static const int msh_type_tetrahedron
Integer flag for tetrahedron element.
void trim_inplace(std::string &s)
Definition mshReader.cpp:23
bool isFileEmpty(std::string filename)
Check if file is empty or null.
Definition io.h:393

References util::io::isFileEmpty(), util::msh_map_element_to_num_nodes, util::msh_type_hexahedron, util::msh_type_quadrangle, util::msh_type_tetrahedron, util::msh_type_triangle, util::vtk_type_hexahedron, util::vtk_type_quad, util::vtk_type_tetra, and util::vtk_type_triangle.

Here is the call graph for this function:

◆ readMesh()

void rw::reader::MshReader::readMesh ( size_t  dim,
std::vector< util::Point > *  nodes,
size_t &  element_type,
size_t &  num_elems,
std::vector< size_t > *  enc,
std::vector< std::vector< size_t > > *  nec,
std::vector< double > *  volumes,
bool  is_fd = false 
)

Reads mesh data into node file and element file.

Parameters
dimDimension
nodesVector of nodes data
element_typeType of element
num_elemsNumber of elements
encVector holding element-node connectivity
necVector holding node-element connectivity
volumesVector holding volume of the nodes
is_fdFlag indicating if this mesh is for finite_difference simulation

Definition at line 38 of file mshReader.cpp.

43 {
44
45 (void)is_fd;
46
48 throw std::runtime_error(
50 << "Error: Filename = " << d_filename <<
51 " in MshReader is either nonexistent or empty.\n");
52 }
53
54 // open file
55 if (d_file) d_file.close();
56
57 d_file.open(d_filename);
58
59 if (!d_file) {
60 throw std::runtime_error(
62 << "Error: Can not open file = " << d_filename + ".msh"
63 << ".\n");
64 }
65
66 int format = 0;
67 int size = 0;
68 double version = 1.0;
69
70 // clear data
71 nodes->clear();
72 enc->clear();
73 nec->clear();
74 volumes->clear();
75
76 // specify type of element to read
77 if (dim != 2 and dim != 3) {
78 throw std::runtime_error(
80 << "Error: MshReader currently only supports reading of "
81 "triangle/quadrangle elements in dimension 2 and tetragonal "
82 "elements in 3.\n");
83 }
84
85 bool read_nodes = false;
86 bool read_elements = false;
87
88 std::string line;
89 while (std::getline(d_file, line)) {
90 trim_inplace(line);
91 if (line.empty())
92 continue;
93
94 if (line == "$MeshFormat") {
95 if (!std::getline(d_file, line)) {
96 throw std::runtime_error(
98 << "Error: Unexpected end of file in MshReader (after $MeshFormat).\n");
99 }
100 trim_inplace(line);
101 {
102 std::istringstream iss(line);
103 iss >> version >> format >> size;
104 }
105 if ((version != 2.0) && (version != 2.1) && (version != 2.2)) {
106 throw std::runtime_error(
108 << "Error: Unknown .msh file version " << version << "\n");
109 }
110 if (format) {
111 throw std::runtime_error(
113 << "Error: Format of .msh is possibly binary which is not"
114 " supported currently.\n ");
115 }
116 } else if (line == "$Nodes" || line == "$NOD" || line == "$NOE") {
117 read_nodes = true;
118 if (!std::getline(d_file, line)) {
119 throw std::runtime_error(
121 << "Error: Unexpected end of file in MshReader (node count).\n");
122 }
123 trim_inplace(line);
124 unsigned int num_nodes = 0;
125 {
126 std::istringstream ns(line);
127 ns >> num_nodes;
128 }
129 nodes->resize(num_nodes);
130 nec->resize(num_nodes);
131
132 for (unsigned int i = 0; i < num_nodes; ++i) {
133 if (!std::getline(d_file, line)) {
134 throw std::runtime_error(
136 << "Error: Unexpected end of file in MshReader (reading nodes).\n");
137 }
138 trim_inplace(line);
139 std::istringstream ls(line);
140 unsigned int id;
141 double x, y, z;
142 ls >> id >> x >> y >> z;
143 if (id < 1 || id > num_nodes) {
144 throw std::runtime_error(
146 << "Error: MshReader: node id out of range in file " << d_filename << "\n");
147 }
148 // 2D: planar meshes use xy; some .msh exports leave z as denormal/garbage — ignore file z.
149 if (dim == 2)
150 (*nodes)[id - 1] = util::Point(x, y, 0.);
151 else
152 (*nodes)[id - 1] = util::Point(x, y, z);
153 }
154 } else if (line == "$Elements" || line == "$ELM") {
155 read_elements = true;
156 if (!std::getline(d_file, line)) {
157 throw std::runtime_error(
159 << "Error: Unexpected end of file in MshReader (element count).\n");
160 }
161 trim_inplace(line);
162 unsigned int num_elem = 0;
163 {
164 std::istringstream es(line);
165 es >> num_elem;
166 }
167
168 size_t elem_counter = 0;
169 bool found_tri = false;
170 bool found_quad = false;
171
172 for (unsigned int iel = 0; iel < num_elem; ++iel) {
173 if (!std::getline(d_file, line)) {
174 throw std::runtime_error(
176 << "Error: Unexpected end of file in MshReader (reading elements).\n");
177 }
178 trim_inplace(line);
179 std::istringstream ls(line);
180 unsigned int id;
181 unsigned int type;
182 unsigned int ntags;
183 ls >> id >> type >> ntags;
184 int tag = 0;
185 for (unsigned int j = 0; j < ntags; j++)
186 ls >> tag;
187
188 bool read_this_element = false;
189 unsigned int num_nodes_con = 0;
190
191 if (type == util::msh_type_triangle and dim == 2) {
192 read_this_element = true;
193 found_tri = true;
194 element_type = util::vtk_type_triangle;
195 num_nodes_con =
197 } else if (type == util::msh_type_quadrangle and dim == 2) {
198 read_this_element = true;
199 found_quad = true;
200 element_type = util::vtk_type_quad;
201 num_nodes_con =
203 } else if (type == util::msh_type_tetrahedron and dim == 3) {
204 read_this_element = true;
205 element_type = util::vtk_type_tetra;
206 num_nodes_con =
208 } else if (type == util::msh_type_hexahedron and dim == 3) {
209 read_this_element = true;
210 element_type = util::vtk_type_hexahedron;
211 num_nodes_con =
213 }
214
215 if (read_this_element) {
216 for (unsigned int i = 0; i < num_nodes_con; i++) {
217 unsigned int node_id;
218 ls >> node_id;
219 enc->push_back(node_id - 1);
220 (*nec)[node_id - 1].push_back(elem_counter);
221 }
222 elem_counter++;
223 } else {
224 unsigned int n_skip = 0;
225 if (type < 16)
226 n_skip = static_cast<unsigned int>(util::msh_map_element_to_num_nodes[type]);
227 if (n_skip > 0) {
228 unsigned int dummy;
229 for (unsigned int i = 0; i < n_skip; i++)
230 ls >> dummy;
231 } else {
232 unsigned int dummy;
233 while (ls >> dummy) {
234 }
235 }
236 }
237 }
238
239 if (found_quad and found_tri) {
240 throw std::runtime_error(
242 << "Error: Check mesh file. It appears to have both "
243 "quadrangle elements and triangle elements. "
244 "Currently we only support one kind of elements.\n");
245 }
246
247 num_elems = elem_counter;
248 break;
249 }
250 }
251
252 if (!read_nodes || !read_elements) {
253 throw std::runtime_error(
255 << "Error: MshReader: incomplete .msh file (need $Nodes and $Elements): "
256 << d_filename << "\n");
257 }
258
259 // close file
260 d_file.close();
261}
A structure to represent 3d vectors.
Definition point.h:30

References util::io::isFileEmpty(), util::msh_map_element_to_num_nodes, util::msh_type_hexahedron, util::msh_type_quadrangle, util::msh_type_tetrahedron, util::msh_type_triangle, util::vtk_type_hexahedron, util::vtk_type_quad, util::vtk_type_tetra, and util::vtk_type_triangle.

Here is the call graph for this function:

◆ readNodes()

void rw::reader::MshReader::readNodes ( std::vector< util::Point > *  nodes)

Reads nodal position.

Parameters
nodesVector of nodal coordinates

Definition at line 263 of file mshReader.cpp.

263 {
264
266 throw std::runtime_error(
268 << "Error: Filename = " << d_filename <<
269 " in MshReader is either nonexistent or empty.\n");
270 }
271
272 // open file
273 if (d_file) d_file.close();
274
275 d_file.open(d_filename);
276
277 if (!d_file) {
278 throw std::runtime_error(
280 << "Error: Can not open file = " << d_filename + ".msh.\n");
281 }
282
283 std::string line;
284 int format = 0;
285 int size = 0;
286 double version = 1.0;
287
288 // clear data
289 nodes->clear();
290 bool read_nodes = false;
291
292 while (true) {
293 std::getline(d_file, line);
294 if (d_file) {
295 // // read $MeshFormat block
296 if (line.find("$MeshFormat") == static_cast<std::string::size_type>(0)) {
297 d_file >> version >> format >> size;
298 if ((version != 2.0) && (version != 2.1) && (version != 2.2)) {
299 throw std::runtime_error(
301 << "Error: Unknown .msh file version " << version << "\n");
302 }
303
304 // we only support reading of ascii format, so issue error if this
305 // condition is not met
306 if (format) {
307 throw std::runtime_error(
309 << "Error: Format of .msh is possibly binary which is not"
310 " supported currently.\n ");
311 }
312 }
313 // read $Nodes block
314 if (line.find("$NOD") == static_cast<std::string::size_type>(0) ||
315 line.find("$NOE") == static_cast<std::string::size_type>(0) ||
316 line.find("$Nodes") == static_cast<std::string::size_type>(0)) {
317 read_nodes = true;
318 unsigned int num_nodes = 0;
319 d_file >> num_nodes;
320
321 // allocate space
322 nodes->resize(num_nodes);
323
324 // read in the nodal coordinates and form points.
325 double x, y, z;
326 unsigned int id;
327
328 // add the nodal coordinates to the d_file
329 for (unsigned int i = 0; i < num_nodes; ++i) {
330 d_file >> id >> x >> y >> z;
331 (*nodes)[id - 1] = util::Point(x, y, z);
332 }
333 // read the $ENDNOD delimiter
334 std::getline(d_file, line);
335 } // end of reading nodes
336 } // if d_file
337
338 // If !d_file, check to see if EOF was set. If so, break out
339 // of while loop.
340 if (d_file.eof()) break;
341
342 if (read_nodes) break;
343
344 // If !d_file and !d_file.eof(), stream is in a bad state!
345 // std::cerr<<"Error: Stream is bad! Perhaps the file does not exist?\n";
346 // exit(1);
347 } // while true
348
349 // close file
350 d_file.close();
351}

References util::io::isFileEmpty().

Here is the call graph for this function:

◆ readPointData() [1/2]

bool rw::reader::MshReader::readPointData ( const std::string &  name,
std::vector< double > *  data 
)

reads point data from .vtu file

Parameters
nameName of data
dataPointer to the vector of data
Returns
status True if data is found otherwise false

Definition at line 603 of file mshReader.cpp.

604 {
605 // open file
606 if (!d_file) d_file = std::ifstream(d_filename);
607
608 if (!d_file)
609 if (!d_file) {
610 throw std::runtime_error(
612 << "Error: Can not open file = " << d_filename + ".msh"
613 << ".\n");
614 }
615
616 bool found_data = false;
617 std::string line;
618 while (true) {
619 std::getline(d_file, line);
620 if (d_file) {
621 // read $Nodes block
622 if (line.find("$NodeData") == static_cast<std::string::size_type>(0)) {
623 // get name of data
624 int num_tags = 0;
625 d_file >> num_tags;
626 std::string tag[num_tags];
627 for (size_t i = 0; i < num_tags; i++) d_file >> tag[i];
628
629 // read dummy data
630 d_file >> num_tags;
631 double real_tag = 0.;
632 d_file >> real_tag;
633
634 int tag_number = 0;
635 int field_type = 0;
636 int num_data = 0;
637 d_file >> tag_number >> field_type >> num_data;
638
639 // check we found the data
640 if (tag[0] == name) {
641 // check if data is of desired field type
642 if (field_type != 1) {
643 throw std::runtime_error(
645 << "Error: Data " << tag[0] << " is of type "
646 << field_type << " but we expect it to be of type " << 1
647 << ".\n");
648 }
649
650 found_data = true;
651 data->resize(num_data);
652 }
653
654 // we read through the data irrespective of we found it or not
655 for (size_t i = 0; i < num_data; i++) {
656 double d[field_type];
657 for (size_t j = 0; j < field_type; j++) d_file >> d[j];
658
659 if (found_data) (*data)[i] = d[0];
660 }
661 // read the end of data block
662 std::getline(d_file, line);
663 } // end of reading nodes
664 } // if d_file
665
666 if (found_data) break;
667
668 // If !d_file, check to see if EOF was set. If so, break out
669 // of while loop.
670 if (d_file.eof()) break;
671 } // while true
672
673 d_file.close();
674 return found_data;
675}
Definition contact.h:20

◆ readPointData() [2/2]

bool rw::reader::MshReader::readPointData ( const std::string &  name,
std::vector< util::Point > *  data 
)

reads point data from .vtu file

Parameters
nameName of data
dataPointer to the vector of data
Returns
status True if data is found otherwise false

Definition at line 529 of file mshReader.cpp.

530 {
531 // open file
532 if (!d_file) d_file = std::ifstream(d_filename);
533
534 if (!d_file)
535 if (!d_file) {
536 throw std::runtime_error(
538 << "Error: Can not open file = " << d_filename + ".msh"
539 << ".\n");
540 }
541
542 bool found_data = false;
543 std::string line;
544 while (true) {
545 std::getline(d_file, line);
546 if (d_file) {
547 // read $Nodes block
548 if (line.find("$NodeData") == static_cast<std::string::size_type>(0)) {
549 // get name of data
550 int num_tags = 0;
551 d_file >> num_tags;
552 std::string tag[num_tags];
553 for (size_t i = 0; i < num_tags; i++) d_file >> tag[i];
554
555 // read dummy data
556 d_file >> num_tags;
557 double real_tag = 0.;
558 d_file >> real_tag;
559
560 int tag_number = 0;
561 int field_type = 0;
562 int num_data = 0;
563 d_file >> tag_number >> field_type >> num_data;
564
565 // check we found the data
566 if (tag[0] == name) {
567 // check if data is of desired field type
568 if (field_type != 3) {
569 throw std::runtime_error(
571 << "Error: Data " << tag[0] << " is of type "
572 << field_type << " but we expect it to be of type " << 3
573 << ".\n");
574 }
575
576 found_data = true;
577 data->resize(num_data);
578 }
579
580 // we read through the data irrespective of we found it or not
581 for (size_t i = 0; i < num_data; i++) {
582 double d[field_type];
583 for (size_t j = 0; j < field_type; j++) d_file >> d[j];
584
585 if (found_data) (*data)[i] = util::Point(d[0], d[1], d[2]);
586 }
587 // read the end of data block
588 std::getline(d_file, line);
589 } // end of reading nodes
590 } // if d_file
591
592 if (found_data) break;
593
594 // If !d_file, check to see if EOF was set. If so, break out
595 // of while loop.
596 if (d_file.eof()) break;
597 } // while true
598
599 d_file.close();
600 return found_data;
601}

Field Documentation

◆ d_file

std::ifstream rw::reader::MshReader::d_file
private

vtk/vtu file

Definition at line 97 of file mshReader.h.

◆ d_filename

std::string rw::reader::MshReader::d_filename
private

filename

Definition at line 94 of file mshReader.h.


The documentation for this class was generated from the following files: