24 while (!s.empty() && (s.back() ==
'\r' || s.back() ==
' ' || s.back() ==
'\t'))
27 while (i < s.size() && (s[i] ==
' ' || s[i] ==
'\t'))
36 : d_filename(filename){};
39 std::vector<util::Point> *nodes,
40 size_t &element_type,
size_t &num_elems,
41 std::vector<size_t> *enc,
42 std::vector<std::vector<size_t>> *nec,
43 std::vector<double> *volumes,
bool is_fd) {
48 throw std::runtime_error(
50 <<
"Error: Filename = " << d_filename <<
51 " in MshReader is either nonexistent or empty.\n");
55 if (d_file) d_file.close();
57 d_file.open(d_filename);
60 throw std::runtime_error(
62 <<
"Error: Can not open file = " << d_filename +
".msh"
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 "
85 bool read_nodes =
false;
86 bool read_elements =
false;
89 while (std::getline(d_file, line)) {
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");
102 std::istringstream iss(line);
103 iss >> version >> format >> size;
105 if ((version != 2.0) && (version != 2.1) && (version != 2.2)) {
106 throw std::runtime_error(
108 <<
"Error: Unknown .msh file version " << version <<
"\n");
111 throw std::runtime_error(
113 <<
"Error: Format of .msh is possibly binary which is not"
114 " supported currently.\n ");
116 }
else if (line ==
"$Nodes" || line ==
"$NOD" || line ==
"$NOE") {
118 if (!std::getline(d_file, line)) {
119 throw std::runtime_error(
121 <<
"Error: Unexpected end of file in MshReader (node count).\n");
124 unsigned int num_nodes = 0;
126 std::istringstream ns(line);
129 nodes->resize(num_nodes);
130 nec->resize(num_nodes);
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");
139 std::istringstream ls(line);
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");
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");
162 unsigned int num_elem = 0;
164 std::istringstream es(line);
168 size_t elem_counter = 0;
169 bool found_tri =
false;
170 bool found_quad =
false;
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");
179 std::istringstream ls(line);
183 ls >>
id >> type >> ntags;
185 for (
unsigned int j = 0; j < ntags; j++)
188 bool read_this_element =
false;
189 unsigned int num_nodes_con = 0;
192 read_this_element =
true;
198 read_this_element =
true;
204 read_this_element =
true;
209 read_this_element =
true;
215 if (read_this_element) {
216 for (
unsigned int i = 0; i < num_nodes_con; i++) {
217 unsigned int node_id;
219 enc->push_back(node_id - 1);
220 (*nec)[node_id - 1].push_back(elem_counter);
224 unsigned int n_skip = 0;
229 for (
unsigned int i = 0; i < n_skip; i++)
233 while (ls >> dummy) {
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");
247 num_elems = elem_counter;
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");
266 throw std::runtime_error(
268 <<
"Error: Filename = " << d_filename <<
269 " in MshReader is either nonexistent or empty.\n");
273 if (d_file) d_file.close();
275 d_file.open(d_filename);
278 throw std::runtime_error(
280 <<
"Error: Can not open file = " << d_filename +
".msh.\n");
286 double version = 1.0;
290 bool read_nodes =
false;
293 std::getline(d_file, line);
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");
307 throw std::runtime_error(
309 <<
"Error: Format of .msh is possibly binary which is not"
310 " supported currently.\n ");
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)) {
318 unsigned int num_nodes = 0;
322 nodes->resize(num_nodes);
329 for (
unsigned int i = 0; i < num_nodes; ++i) {
330 d_file >>
id >> x >> y >> z;
334 std::getline(d_file, line);
340 if (d_file.eof())
break;
342 if (read_nodes)
break;
354 size_t &num_elems, std::vector<size_t> *enc,
355 std::vector<std::vector<size_t>> *nec) {
358 throw std::runtime_error(
360 <<
"Error: Filename = " << d_filename <<
361 " in MshReader is either nonexistent or empty.\n");
365 if (d_file) d_file.close();
367 d_file.open(d_filename);
370 throw std::runtime_error(
372 <<
"Error: Can not open file = " << d_filename +
".msh"
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 "
388 bool have_nodes =
false;
389 bool read_elements =
false;
392 while (std::getline(d_file, line)) {
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");
404 unsigned int num_nodes = 0;
406 std::istringstream ns(line);
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");
416 nec->assign(num_nodes, {});
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");
429 unsigned int num_elem = 0;
431 std::istringstream es(line);
435 size_t elem_counter = 0;
436 bool found_tri =
false;
437 bool found_quad =
false;
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");
446 std::istringstream ls(line);
450 ls >>
id >> type >> ntags;
452 for (
unsigned int j = 0; j < ntags; j++)
455 bool read_this_element =
false;
456 unsigned int num_nodes_con = 0;
459 read_this_element =
true;
465 read_this_element =
true;
471 read_this_element =
true;
476 read_this_element =
true;
482 if (read_this_element) {
483 for (
unsigned int i = 0; i < num_nodes_con; i++) {
484 unsigned int node_id;
486 enc->push_back(node_id - 1);
487 (*nec)[node_id - 1].push_back(elem_counter);
491 unsigned int n_skip = 0;
496 for (
unsigned int i = 0; i < n_skip; i++)
500 while (ls >> dummy) {
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");
514 num_elems = elem_counter;
519 if (!have_nodes || !read_elements) {
520 throw std::runtime_error(
522 <<
"Error: MshReader::readCells: incomplete .msh file: " << d_filename <<
"\n");
530 std::vector<util::Point> *
data) {
532 if (!d_file) d_file = std::ifstream(d_filename);
536 throw std::runtime_error(
538 <<
"Error: Can not open file = " << d_filename +
".msh"
542 bool found_data =
false;
545 std::getline(d_file, line);
548 if (line.find(
"$NodeData") ==
static_cast<std::string::size_type
>(0)) {
552 std::string tag[num_tags];
553 for (
size_t i = 0; i < num_tags; i++) d_file >> tag[i];
557 double real_tag = 0.;
563 d_file >> tag_number >> field_type >> num_data;
566 if (tag[0] == name) {
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
577 data->resize(num_data);
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];
588 std::getline(d_file, line);
592 if (found_data)
break;
596 if (d_file.eof())
break;
604 std::vector<double> *
data) {
606 if (!d_file) d_file = std::ifstream(d_filename);
610 throw std::runtime_error(
612 <<
"Error: Can not open file = " << d_filename +
".msh"
616 bool found_data =
false;
619 std::getline(d_file, line);
622 if (line.find(
"$NodeData") ==
static_cast<std::string::size_type
>(0)) {
626 std::string tag[num_tags];
627 for (
size_t i = 0; i < num_tags; i++) d_file >> tag[i];
631 double real_tag = 0.;
637 d_file >> tag_number >> field_type >> num_data;
640 if (tag[0] == name) {
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
651 data->resize(num_data);
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];
659 if (found_data) (*
data)[i] = d[0];
662 std::getline(d_file, line);
666 if (found_data)
break;
670 if (d_file.eof())
break;
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 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
void close()
Close the file.
MshReader(const std::string &filename)
Constructor.
void readNodes(std::vector< util::Point > *nodes)
Reads nodal position.
Collects a message with stream syntax for use in an exception.
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)
bool isFileEmpty(std::string filename)
Check if file is empty or null.
A structure to represent 3d vectors.