PeriDEM 0.2.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 19 of file mshReader.cpp.

20 : 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 625 of file mshReader.cpp.

625{}

◆ 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 316 of file mshReader.cpp.

318 {
319
321 std::cerr << "Error: Filename = " << d_filename <<
322 " in MshReader is either nonexistent or empty.\n";
323 exit(EXIT_FAILURE);
324 }
325
326 // open file
327 if (d_file) d_file.close();
328
329 d_file.open(d_filename);
330
331 if (!d_file) {
332 std::cerr << "Error: Can not open file = " << d_filename + ".msh"
333 << ".\n";
334 exit(1);
335 }
336
337 std::string line;
338 int format = 0;
339 int size = 0;
340 double version = 1.0;
341
342 // clear data
343 enc->clear();
344 nec->clear();
345
346 // specify type of element to read
347 if (dim != 2 and dim != 3) {
348 std::cerr << "Error: MshReader currently only supports reading of "
349 "triangle/quadrangle elements in dimension 2 and tetragonal "
350 "elements in 3.\n";
351 exit(1);
352 }
353
354 unsigned int num_nodes_con = 0;
355 bool read_elements = false;
356
357 while (true) {
358 std::getline(d_file, line);
359 if (d_file) {
360 // // read $MeshFormat block
361 if (line.find("$MeshFormat") == static_cast<std::string::size_type>(0)) {
362 d_file >> version >> format >> size;
363 if ((version != 2.0) && (version != 2.1) && (version != 2.2)) {
364 std::cerr << "Error: Unknown .msh file version " << version << "\n";
365 exit(1);
366 }
367
368 // we only support reading of ascii format, so issue error if this
369 // condition is not met
370 if (format) {
371 std::cerr << "Error: Format of .msh is possibly binary which is not"
372 " supported currently.\n ";
373 exit(1);
374 }
375 }
376 // Read the element block
377 if (line.find("$ELM") == static_cast<std::string::size_type>(0) ||
378 line.find("$Elements") ==
379 static_cast<std::string::size_type>(0)) {
380 read_elements = true;
381
382 // For reading the number of elements and the node ids from the stream
383 unsigned int num_elem = 0;
384 unsigned int node_id = 0;
385
386 // read how many elements are there
387 // this includes point element, line element also
388 d_file >> num_elem;
389
390 // As of version 2.2, the format for each element line is:
391 // elm-number elm-type number-of-tags < tag > ... node-number-list
392
393 // read the elements
394 size_t elem_counter = 0;
395 bool found_tri = false;
396 bool found_quad = false;
397 bool found_tet = false;
398 for (unsigned int iel = 0; iel < num_elem; ++iel) {
399 unsigned int id;
400 unsigned int type;
401 unsigned int ntags;
402 int tag;
403 d_file >> id >> type >> ntags;
404 for (unsigned int j = 0; j < ntags; j++) d_file >> tag;
405
406 // we will read only those elements which we support
407 bool read_this_element = false;
408
409 // read element type we desire and for other element type
410 // perform dummy read
411 if (type == util::msh_type_triangle and dim == 2) {
412 read_this_element = true;
413 found_tri = true;
414 element_type = util::vtk_type_triangle;
415 num_nodes_con =
417 } else if (type == util::msh_type_quadrangle and dim == 2) {
418 read_this_element = true;
419 found_quad = true;
420 element_type = util::vtk_type_quad;
421 num_nodes_con =
423 } else if (type == util::msh_type_tetrahedron and dim == 3) {
424 read_this_element = true;
425 found_tet = true;
426 element_type = util::vtk_type_tetra;
427 num_nodes_con =
429 }
430
431 // std::vector<size_t> e_nodes;
432 if (read_this_element) {
433 // read vertex of this element
434 for (unsigned int i = 0; i < num_nodes_con; i++) {
435 d_file >> node_id;
436 // add to the element-node connectivity
437 // substract 1 to correct the numbering convention
438 enc->push_back(node_id - 1);
439
440 // fill the node-element connectivity table
441 (*nec)[node_id - 1].push_back(elem_counter);
442 }
443
444 // increment the element counter
445 elem_counter++;
446 } else {
447 // these are the type of elements we need to ignore.
449 // dummy read
450 for (unsigned int i = 0; i < n; i++) d_file >> node_id;
451 }
452 } // element loop
453
454 // check if mesh contains both triangle and quadrangle elements
455 if (found_quad and found_tri) {
456 std::cerr << "Error: Check mesh file. It appears to have both "
457 "quadrangle elements and triangle elements. "
458 "Currently we only support one kind of elements.\n";
459 exit(1);
460 }
461
462 // write the number of elements
463 num_elems = elem_counter;
464
465 // read the $ENDELM delimiter
466 std::getline(d_file, line);
467 } // end of reading elements
468 } // if d_file
469
470 // If !d_file, check to see if EOF was set. If so, break out
471 // of while loop.
472 if (d_file.eof()) break;
473
474 if (read_elements) break;
475 } // while true
476
477 // close file
478 d_file.close();
479}
std::ifstream d_file
vtk/vtu file
Definition mshReader.h:97
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_triangle
Integer flag for triangle element.
static const int msh_type_tetrahedron
Integer flag for tetrahedron element.
bool isFileEmpty(std::string filename)
Check if file is empty or null.
Definition io.h:469

References util::io::isFileEmpty(), util::msh_map_element_to_num_nodes, util::msh_type_quadrangle, util::msh_type_tetrahedron, util::msh_type_triangle, 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 22 of file mshReader.cpp.

27 {
28
30 std::cerr << "Error: Filename = " << d_filename <<
31 " in MshReader is either nonexistent or empty.\n";
32 exit(EXIT_FAILURE);
33 }
34
35 // open file
36 if (d_file) d_file.close();
37
38 d_file.open(d_filename);
39
40 if (!d_file) {
41 std::cerr << "Error: Can not open file = " << d_filename + ".msh"
42 << ".\n";
43 exit(1);
44 }
45
46 std::string line;
47 int format = 0;
48 int size = 0;
49 double version = 1.0;
50
51 // clear data
52 nodes->clear();
53 enc->clear();
54 nec->clear();
55 volumes->clear();
56
57 // specify type of element to read
58 if (dim != 2 and dim != 3) {
59 std::cerr << "Error: MshReader currently only supports reading of "
60 "triangle/quadrangle elements in dimension 2 and tetragonal "
61 "elements in 3.\n";
62 exit(1);
63 }
64
65 unsigned int num_nodes_con = 0;
66 bool read_nodes = false;
67 bool read_elements = false;
68
69 while (true) {
70 std::getline(d_file, line);
71 if (d_file) {
72 // // read $MeshFormat block
73 if (line.find("$MeshFormat") == static_cast<std::string::size_type>(0)) {
74 d_file >> version >> format >> size;
75 if ((version != 2.0) && (version != 2.1) && (version != 2.2)) {
76 std::cerr << "Error: Unknown .msh file version " << version << "\n";
77 exit(1);
78 }
79
80 // we only support reading of ascii format, so issue error if this
81 // condition is not met
82 if (format) {
83 std::cerr << "Error: Format of .msh is possibly binary which is not"
84 " supported currently.\n ";
85 exit(1);
86 }
87 }
88 // read $Nodes block
89 if (line.find("$NOD") == static_cast<std::string::size_type>(0) ||
90 line.find("$NOE") == static_cast<std::string::size_type>(0) ||
91 line.find("$Nodes") == static_cast<std::string::size_type>(0)) {
92 read_nodes = true;
93 unsigned int num_nodes = 0;
94 d_file >> num_nodes;
95
96 // allocate space
97 nodes->resize(num_nodes);
98 nec->resize(num_nodes);
99
100 // read in the nodal coordinates and form points.
101 double x, y, z;
102 unsigned int id;
103
104 // add the nodal coordinates to the d_file
105 for (unsigned int i = 0; i < num_nodes; ++i) {
106 d_file >> id >> x >> y >> z;
107 (*nodes)[id - 1] = util::Point(x, y, z);
108 }
109 // read the $ENDNOD delimiter
110 std::getline(d_file, line);
111 } // end of reading nodes
112 // Read the element block
113 else if (line.find("$ELM") == static_cast<std::string::size_type>(0) ||
114 line.find("$Elements") ==
115 static_cast<std::string::size_type>(0)) {
116 read_elements = true;
117
118 // For reading the number of elements and the node ids from the stream
119 unsigned int num_elem = 0;
120 unsigned int node_id = 0;
121
122 // read how many elements are there
123 // this includes point element, line element also
124 d_file >> num_elem;
125
126 // As of version 2.2, the format for each element line is:
127 // elm-number elm-type number-of-tags < tag > ... node-number-list
128
129 // read the elements
130 size_t elem_counter = 0;
131 bool found_tri = false;
132 bool found_quad = false;
133 bool found_tet = false;
134 for (unsigned int iel = 0; iel < num_elem; ++iel) {
135 unsigned int id;
136 unsigned int type;
137 unsigned int ntags;
138 int tag;
139 d_file >> id >> type >> ntags;
140 for (unsigned int j = 0; j < ntags; j++) d_file >> tag;
141
142 // we will read only those elements which we support
143 bool read_this_element = false;
144
145 // read element type we desire and for other element type
146 // perform dummy read
147 if (type == util::msh_type_triangle and dim == 2) {
148 read_this_element = true;
149 found_tri = true;
150 element_type = util::vtk_type_triangle;
151 num_nodes_con =
153 } else if (type == util::msh_type_quadrangle and dim == 2) {
154 read_this_element = true;
155 found_quad = true;
156 element_type = util::vtk_type_quad;
157 num_nodes_con =
159 } else if (type == util::msh_type_tetrahedron and dim == 3) {
160 read_this_element = true;
161 found_tet = true;
162 element_type = util::vtk_type_tetra;
163 num_nodes_con =
165 }
166
167 // std::vector<size_t> e_nodes;
168 if (read_this_element) {
169 // read vertex of this element
170 for (unsigned int i = 0; i < num_nodes_con; i++) {
171 d_file >> node_id;
172 // add to the element-node connectivity
173 // substract 1 to correct the numbering convention
174 enc->push_back(node_id - 1);
175
176 // e_nodes.push_back(node_id - 1);
177
178 // fill the node-element connectivity table
179 (*nec)[node_id - 1].push_back(elem_counter);
180 }
181
182 // debug
183 // std::cout << "(" << id << ", " << type << ", " << elem_counter
184 // << ") = ";
185 // for (auto enode: e_nodes)
186 // std::cout << enode << ";";
187 // std::cout << "\n";
188
189 // increment the element counter
190 elem_counter++;
191 } else {
192 // these are the type of elements we need to ignore.
194 // dummy read
195 for (unsigned int i = 0; i < n; i++) d_file >> node_id;
196 }
197 } // element loop
198
199 // check if mesh contains both triangle and quadrangle elements
200 if (found_quad and found_tri) {
201 std::cerr << "Error: Check mesh file. It appears to have both "
202 "quadrangle elements and triangle elements. "
203 "Currently we only support one kind of elements.\n";
204 exit(1);
205 }
206
207 // write the number of elements
208 num_elems = elem_counter;
209
210 // read the $ENDELM delimiter
211 std::getline(d_file, line);
212 } // end of reading elements
213 } // if d_file
214
215 // If !d_file, check to see if EOF was set. If so, break out
216 // of while loop.
217 if (d_file.eof()) break;
218
219 if (read_nodes and read_elements) break;
220
221 // If !d_file and !d_file.eof(), stream is in a bad state!
222 // std::cerr<<"Error: Stream is bad! Perhaps the file does not exist?\n";
223 // exit(1);
224 } // while true
225
226 // close file
227 d_file.close();
228}
A structure to represent 3d vectors.
Definition point.h:30

References util::io::isFileEmpty(), util::msh_map_element_to_num_nodes, util::msh_type_quadrangle, util::msh_type_tetrahedron, util::msh_type_triangle, 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 230 of file mshReader.cpp.

230 {
231
233 std::cerr << "Error: Filename = " << d_filename <<
234 " in MshReader is either nonexistent or empty.\n";
235 exit(EXIT_FAILURE);
236 }
237
238 // open file
239 if (d_file) d_file.close();
240
241 d_file.open(d_filename);
242
243 if (!d_file) {
244 std::cerr << "Error: Can not open file = " << d_filename + ".msh.\n";
245 exit(1);
246 }
247
248 std::string line;
249 int format = 0;
250 int size = 0;
251 double version = 1.0;
252
253 // clear data
254 nodes->clear();
255 bool read_nodes = false;
256
257 while (true) {
258 std::getline(d_file, line);
259 if (d_file) {
260 // // read $MeshFormat block
261 if (line.find("$MeshFormat") == static_cast<std::string::size_type>(0)) {
262 d_file >> version >> format >> size;
263 if ((version != 2.0) && (version != 2.1) && (version != 2.2)) {
264 std::cerr << "Error: Unknown .msh file version " << version << "\n";
265 exit(1);
266 }
267
268 // we only support reading of ascii format, so issue error if this
269 // condition is not met
270 if (format) {
271 std::cerr << "Error: Format of .msh is possibly binary which is not"
272 " supported currently.\n ";
273 exit(1);
274 }
275 }
276 // read $Nodes block
277 if (line.find("$NOD") == static_cast<std::string::size_type>(0) ||
278 line.find("$NOE") == static_cast<std::string::size_type>(0) ||
279 line.find("$Nodes") == static_cast<std::string::size_type>(0)) {
280 read_nodes = true;
281 unsigned int num_nodes = 0;
282 d_file >> num_nodes;
283
284 // allocate space
285 nodes->resize(num_nodes);
286
287 // read in the nodal coordinates and form points.
288 double x, y, z;
289 unsigned int id;
290
291 // add the nodal coordinates to the d_file
292 for (unsigned int i = 0; i < num_nodes; ++i) {
293 d_file >> id >> x >> y >> z;
294 (*nodes)[id - 1] = util::Point(x, y, z);
295 }
296 // read the $ENDNOD delimiter
297 std::getline(d_file, line);
298 } // end of reading nodes
299 } // if d_file
300
301 // If !d_file, check to see if EOF was set. If so, break out
302 // of while loop.
303 if (d_file.eof()) break;
304
305 if (read_nodes) break;
306
307 // If !d_file and !d_file.eof(), stream is in a bad state!
308 // std::cerr<<"Error: Stream is bad! Perhaps the file does not exist?\n";
309 // exit(1);
310 } // while true
311
312 // close file
313 d_file.close();
314}

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 553 of file mshReader.cpp.

554 {
555 // open file
556 if (!d_file) d_file = std::ifstream(d_filename);
557
558 if (!d_file)
559 if (!d_file) {
560 std::cerr << "Error: Can not open file = " << d_filename + ".msh"
561 << ".\n";
562 exit(1);
563 }
564
565 bool found_data = false;
566 std::string line;
567 while (true) {
568 std::getline(d_file, line);
569 if (d_file) {
570 // read $Nodes block
571 if (line.find("$NodeData") == static_cast<std::string::size_type>(0)) {
572 // get name of data
573 int num_tags = 0;
574 d_file >> num_tags;
575 std::string tag[num_tags];
576 for (size_t i = 0; i < num_tags; i++) d_file >> tag[i];
577
578 // read dummy data
579 d_file >> num_tags;
580 double real_tag = 0.;
581 d_file >> real_tag;
582
583 int tag_number = 0;
584 int field_type = 0;
585 int num_data = 0;
586 d_file >> tag_number >> field_type >> num_data;
587
588 // check we found the data
589 if (tag[0] == name) {
590 // check if data is of desired field type
591 if (field_type != 1) {
592 std::cerr << "Error: Data " << tag[0] << " is of type "
593 << field_type << " but we expect it to be of type " << 1
594 << ".\n";
595 exit(1);
596 }
597
598 found_data = true;
599 data->resize(num_data);
600 }
601
602 // we read through the data irrespective of we found it or not
603 for (size_t i = 0; i < num_data; i++) {
604 double d[field_type];
605 for (size_t j = 0; j < field_type; j++) d_file >> d[j];
606
607 if (found_data) (*data)[i] = d[0];
608 }
609 // read the end of data block
610 std::getline(d_file, line);
611 } // end of reading nodes
612 } // if d_file
613
614 if (found_data) break;
615
616 // If !d_file, check to see if EOF was set. If so, break out
617 // of while loop.
618 if (d_file.eof()) break;
619 } // while true
620
621 d_file.close();
622 return found_data;
623}
float d
initial distance between particle and wall

◆ 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 481 of file mshReader.cpp.

482 {
483 // open file
484 if (!d_file) d_file = std::ifstream(d_filename);
485
486 if (!d_file)
487 if (!d_file) {
488 std::cerr << "Error: Can not open file = " << d_filename + ".msh"
489 << ".\n";
490 exit(1);
491 }
492
493 bool found_data = false;
494 std::string line;
495 while (true) {
496 std::getline(d_file, line);
497 if (d_file) {
498 // read $Nodes block
499 if (line.find("$NodeData") == static_cast<std::string::size_type>(0)) {
500 // get name of data
501 int num_tags = 0;
502 d_file >> num_tags;
503 std::string tag[num_tags];
504 for (size_t i = 0; i < num_tags; i++) d_file >> tag[i];
505
506 // read dummy data
507 d_file >> num_tags;
508 double real_tag = 0.;
509 d_file >> real_tag;
510
511 int tag_number = 0;
512 int field_type = 0;
513 int num_data = 0;
514 d_file >> tag_number >> field_type >> num_data;
515
516 // check we found the data
517 if (tag[0] == name) {
518 // check if data is of desired field type
519 if (field_type != 3) {
520 std::cerr << "Error: Data " << tag[0] << " is of type "
521 << field_type << " but we expect it to be of type " << 3
522 << ".\n";
523 exit(1);
524 }
525
526 found_data = true;
527 data->resize(num_data);
528 }
529
530 // we read through the data irrespective of we found it or not
531 for (size_t i = 0; i < num_data; i++) {
532 double d[field_type];
533 for (size_t j = 0; j < field_type; j++) d_file >> d[j];
534
535 if (found_data) (*data)[i] = util::Point(d[0], d[1], d[2]);
536 }
537 // read the end of data block
538 std::getline(d_file, line);
539 } // end of reading nodes
540 } // if d_file
541
542 if (found_data) break;
543
544 // If !d_file, check to see if EOF was set. If so, break out
545 // of while loop.
546 if (d_file.eof()) break;
547 } // while true
548
549 d_file.close();
550 return found_data;
551}

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: