OGS
FileIO::FEFLOWMeshInterface Class Reference

Detailed Description

Read FEFLOW model files (*.fem) into OGS data structure. Currently this class supports only import of mesh data and some geometry given in Supermesh section.

Definition at line 32 of file FEFLOWMeshInterface.h.

#include <FEFLOWMeshInterface.h>

Classes

struct  FEM_CLASS
struct  FEM_DIM

Public Member Functions

MeshLib::MeshreadFEFLOWFile (const std::string &filename)

Private Member Functions

MeshLib::ElementreadElement (std::string const &line, std::vector< MeshLib::Node * > const &nodes)
 Read element type and node indices according to the element type.
MeshLib::ElementreadElement (const FEM_DIM &fem_dim, const MeshLib::MeshElemType elem_type, const std::string &line, const std::vector< MeshLib::Node * > &nodes)
 read node indices and create a mesh element
void readNodeCoordinates (std::ifstream &in, std::vector< MeshLib::Node * > &nodes)
 read node coordinates given in the XYZCOOR section
void readNodeCoordinates (std::ifstream &in, const FEM_CLASS &fem_class, const FEM_DIM &fem_dim, std::vector< MeshLib::Node * > const &nodes)
 read node coordinates
void readElevation (std::ifstream &in, const FEM_CLASS &fem_class, const FEM_DIM &fem_dim, std::vector< MeshLib::Node * > &vec_nodes)
 read elevation data
std::vector< std::size_t > getIndexList (const std::string &str_ranges)
void readELEMENTALSETS (std::ifstream &in, std::vector< std::vector< std::size_t > > &vec_elementsets)
 parse ELEMENTALSETS
void readMAT_I_FLOW (std::ifstream &in, const FEM_DIM &fem_dim, std::vector< std::string > &vec_element_property_names, std::vector< std::vector< double > > &vec_element_property_values)
 read MAT_I_FLOW data (material properties of flow problem)
std::vector< double > readMaterialPropertyValues (std::ifstream &in, std::size_t n_elements)
 read element values of a material property in MAT_I_FLOW data
void setMaterialIDs (FEM_CLASS const &fem_class, FEM_DIM const &fem_dim, std::vector< GeoLib::Polyline * > const &lines, std::vector< std::vector< std::size_t > > const &vec_elementsets, std::vector< MeshLib::Element * > const &vec_elements, MeshLib::PropertyVector< int > &material_ids)

Member Function Documentation

◆ getIndexList()

std::vector< std::size_t > FileIO::FEFLOWMeshInterface::getIndexList ( const std::string & str_ranges)
private

Definition at line 392 of file FEFLOWMeshInterface.cpp.

394{
395 std::vector<std::size_t> vec_node_IDs;
396
397 // insert space before and after minus for splitting
398 std::string str_ranges2(BaseLib::replaceString("-", " # ", str_ranges));
399 BaseLib::trim(str_ranges2);
400 auto splitted_str = BaseLib::splitString(str_ranges2, ' ');
401 bool is_range = false;
402 for (auto str : splitted_str)
403 {
404 if (str.empty())
405 {
406 continue;
407 }
408 if (str[0] == '#')
409 {
410 is_range = true;
411 }
412 else if (is_range)
413 {
414 const std::size_t start = vec_node_IDs.back();
415 const auto end = BaseLib::str2number<std::size_t>(str);
416 for (std::size_t i = start + 1; i < end + 1; i++)
417 {
418 vec_node_IDs.push_back(i);
419 }
420 is_range = false;
421 }
422 else
423 {
424 BaseLib::trim(str);
425 vec_node_IDs.push_back(BaseLib::str2number<std::size_t>(str));
426 }
427 }
428
429 return vec_node_IDs;
430}
std::string replaceString(const std::string &searchString, const std::string &replaceString, std::string stringToReplace)
void trim(std::string &str, char ch)
std::vector< std::string > splitString(std::string const &str)
T str2number(const std::string &str)
Definition StringTools.h:54

References BaseLib::replaceString(), BaseLib::splitString(), BaseLib::str2number(), and BaseLib::trim().

Referenced by readELEMENTALSETS(), readElevation(), and readMaterialPropertyValues().

◆ readElement() [1/2]

MeshLib::Element * FileIO::FEFLOWMeshInterface::readElement ( const FEM_DIM & fem_dim,
const MeshLib::MeshElemType elem_type,
const std::string & line,
const std::vector< MeshLib::Node * > & nodes )
private

read node indices and create a mesh element

Definition at line 591 of file FEFLOWMeshInterface.cpp.

594{
595 std::stringstream ss(line);
596
597 unsigned idx[8];
598 for (std::size_t i = 0; i < fem_dim.n_nodes_of_element; ++i)
599 {
600 ss >> idx[i];
601 }
602 auto** ele_nodes = new MeshLib::Node*[fem_dim.n_nodes_of_element];
603
604 switch (elem_type)
605 {
606 default:
607 for (unsigned k(0); k < fem_dim.n_nodes_of_element; ++k)
608 {
609 ele_nodes[k] = nodes[idx[k] - 1];
610 }
611 break;
614 const unsigned n_half_nodes = fem_dim.n_nodes_of_element / 2;
615 for (unsigned k(0); k < n_half_nodes; ++k)
616 {
617 ele_nodes[k] = nodes[idx[k + n_half_nodes] - 1];
618 ele_nodes[k + n_half_nodes] = nodes[idx[k] - 1];
619 }
620 break;
621 }
622
623 switch (elem_type)
624 {
626 return new MeshLib::Line(ele_nodes);
628 return new MeshLib::Tri(ele_nodes);
630 return new MeshLib::Quad(ele_nodes);
632 return new MeshLib::Tet(ele_nodes);
634 return new MeshLib::Hex(ele_nodes);
636 return new MeshLib::Prism(ele_nodes);
637 default:
638 assert(false);
639 return nullptr;
640 }
641}
TemplateElement< MeshLib::TetRule4 > Tet
Definition Tet.h:14
TemplateElement< MeshLib::LineRule2 > Line
Definition Line.h:14
TemplateElement< MeshLib::QuadRule4 > Quad
Definition Quad.h:17
TemplateElement< MeshLib::TriRule3 > Tri
Definition Tri.h:15
TemplateElement< MeshLib::PrismRule6 > Prism
Definition Prism.h:14
TemplateElement< MeshLib::HexRule8 > Hex
Definition Hex.h:14

References MeshLib::HEXAHEDRON, MeshLib::LINE, FileIO::FEFLOWMeshInterface::FEM_DIM::n_nodes_of_element, MeshLib::PRISM, MeshLib::QUAD, MeshLib::TETRAHEDRON, and MeshLib::TRIANGLE.

◆ readElement() [2/2]

MeshLib::Element * FileIO::FEFLOWMeshInterface::readElement ( std::string const & line,
std::vector< MeshLib::Node * > const & nodes )
private

Read element type and node indices according to the element type.

Definition at line 523 of file FEFLOWMeshInterface.cpp.

525{
526 std::stringstream ss(line);
527
528 int ele_type;
529 ss >> ele_type;
530
531 MeshLib::MeshElemType elem_type;
532 std::size_t n_nodes_of_element;
533 switch (ele_type)
534 {
535 case 6:
537 n_nodes_of_element = 4;
538 break;
539 case 7:
541 n_nodes_of_element = 6;
542 break;
543 case 8:
545 n_nodes_of_element = 8;
546 break;
547 default:
548 WARN("Could not parse element type.");
549 return nullptr;
550 }
551
552 unsigned idx[8];
553 for (std::size_t i = 0; i < n_nodes_of_element; ++i)
554 {
555 ss >> idx[i];
556 }
557 auto** ele_nodes = new MeshLib::Node*[n_nodes_of_element];
558
559 switch (elem_type)
560 {
561 default:
562 for (std::size_t k(0); k < n_nodes_of_element; ++k)
563 {
564 ele_nodes[k] = nodes[idx[k] - 1];
565 }
566 break;
569 const unsigned n_half_nodes = n_nodes_of_element / 2;
570 for (unsigned k(0); k < n_half_nodes; ++k)
571 {
572 ele_nodes[k] = nodes[idx[k + n_half_nodes] - 1];
573 ele_nodes[k + n_half_nodes] = nodes[idx[k] - 1];
574 }
575 break;
576 }
577
578 switch (elem_type)
579 {
581 return new MeshLib::Tet(ele_nodes);
583 return new MeshLib::Hex(ele_nodes);
585 return new MeshLib::Prism(ele_nodes);
586 default:
587 return nullptr;
588 }
589}
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
MeshElemType
Types of mesh elements supported by OpenGeoSys. Values are from VTKCellType enum.
Definition MeshEnums.h:38

References MeshLib::HEXAHEDRON, MeshLib::PRISM, MeshLib::TETRAHEDRON, and WARN().

Referenced by readFEFLOWFile().

◆ readELEMENTALSETS()

void FileIO::FEFLOWMeshInterface::readELEMENTALSETS ( std::ifstream & in,
std::vector< std::vector< std::size_t > > & vec_elementsets )
private

parse ELEMENTALSETS

Definition at line 643 of file FEFLOWMeshInterface.cpp.

645{
646 auto compressSpaces = [](std::string const& str)
647 {
648 std::stringstream ss(str);
649 std::string new_str;
650 std::string word;
651 while (ss)
652 {
653 ss >> word;
654 new_str += " " + word;
655 }
656 return new_str;
657 };
658
659 std::string line_string;
660 std::string str_idList;
661 std::streampos pos_prev_line = 0;
662 while (true)
663 {
664 pos_prev_line = in.tellg();
665 std::getline(in, line_string);
666
667 unsigned mode = 0;
668 if (!in)
669 {
670 mode = 0; // reached the end of the file
671 }
672 else if (line_string.empty())
673 {
674 continue; // skip and see what comes next
675 }
676 else if (std::isalpha(line_string[0]))
677 {
678 mode = 0; // reached the next section
679 }
680 else if (line_string[0] == ' ')
681 {
682 mode = 1; // start of the element set definition
683 }
684 else if (line_string[0] == '\t')
685 {
686 mode = 2; // continue the definition
687 }
688 else
689 {
690 ERR("Failed during parsing of an ELEMENTALSETS section in a FEFLOW "
691 "file");
692 break;
693 }
694
695 if (mode != 2 && !str_idList.empty())
696 {
697 vec_elementsets.push_back(getIndexList(str_idList));
698 str_idList.clear();
699 }
700
701 if (mode == 0)
702 {
703 break;
704 }
705 if (mode == 1)
706 {
707 // starting a new set
708 std::string set_name;
709 std::string ids;
710 BaseLib::trim(line_string, ' ');
711 if (line_string[0] == '"')
712 { // multiple words
713 auto pos = line_string.find_last_of('"');
714 set_name = line_string.substr(1, pos - 1); // without quotation
715 ids = line_string.substr(pos + 1);
716 }
717 else
718 { // single word
719 auto pos = line_string.find_first_of(' ');
720 set_name = line_string.substr(0, pos);
721 ids = line_string.substr(pos + 1);
722 }
723 INFO("Found an element group - {:s}", set_name.data());
724 str_idList += compressSpaces(ids);
725 }
726 else
727 {
728 // continue reading a element ids
729 BaseLib::trim(line_string, '\t');
730 str_idList += compressSpaces(line_string);
731 }
732 }
733 // move stream position to previous line
734 if (std::isalpha(line_string[0]))
735 {
736 in.seekg(pos_prev_line);
737 }
738}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
std::vector< std::size_t > getIndexList(const std::string &str_ranges)
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
Definition Mesh.h:218

References ERR(), getIndexList(), INFO(), and BaseLib::trim().

Referenced by readFEFLOWFile().

◆ readElevation()

void FileIO::FEFLOWMeshInterface::readElevation ( std::ifstream & in,
const FEM_CLASS & fem_class,
const FEM_DIM & fem_dim,
std::vector< MeshLib::Node * > & vec_nodes )
private

read elevation data

Definition at line 432 of file FEFLOWMeshInterface.cpp.

436{
437 const std::size_t no_nodes_per_layer =
438 fem_dim.n_nodes / (fem_class.n_layers3d + 1);
439 double z = .0;
440 std::string str_nodeList;
441 std::string line_string;
442 std::stringstream line_stream;
443 std::size_t l = 0;
444 unsigned mode = 0; // 0: exit, 1: slice no, 2: elevation value, 3:
445 // continued line of mode 2
446 std::streamoff pos_prev_line = 0;
447 while (true)
448 {
449 pos_prev_line = in.tellg();
450 std::getline(in, line_string);
451 boost::trim_right(line_string);
452
453 // check mode
454 auto columns = BaseLib::splitString(line_string, ' ');
455 if (!in || std::isalpha(line_string[0]))
456 {
457 mode = 0;
458 }
459 else if (line_string.empty())
460 {
461 continue;
462 }
463 else if (line_string[0] == '\t')
464 {
465 mode = 3;
466 }
467 else if (columns.size() == 1)
468 {
469 mode = 1;
470 }
471 else
472 { // columns.size()>1
473 mode = 2;
474 }
475
476 // process stocked data
477 if (mode != 3 && !str_nodeList.empty())
478 {
479 // process previous lines
480 auto vec_nodeIDs = getIndexList(str_nodeList);
481 for (auto n0 : vec_nodeIDs)
482 {
483 const std::size_t n = n0 - 1 + l * no_nodes_per_layer;
484 (*vec_nodes[n])[2] = z;
485 }
486 str_nodeList.clear();
487 }
488
489 if (mode == 0)
490 {
491 break;
492 }
493 if (mode == 1)
494 {
495 // slice number
496 l++;
497 assert(l + 1 == BaseLib::str2number<std::size_t>(columns.front()));
498 }
499 else if (mode == 2)
500 {
501 // parse current line
502 line_stream.str(line_string);
503 line_stream >> z;
504 std::getline(line_stream, str_nodeList);
505 boost::trim(str_nodeList);
506 line_stream.clear();
507 }
508 else if (mode == 3)
509 {
510 // continue reading node range
511 BaseLib::trim(line_string, '\t');
512 str_nodeList += " " + line_string;
513 }
514 }
515
516 // move stream position to previous line
517 if (std::isalpha(line_string[0]))
518 {
519 in.seekg(pos_prev_line);
520 }
521}

References getIndexList(), FileIO::FEFLOWMeshInterface::FEM_CLASS::n_layers3d, FileIO::FEFLOWMeshInterface::FEM_DIM::n_nodes, BaseLib::splitString(), BaseLib::str2number(), and BaseLib::trim().

Referenced by readFEFLOWFile().

◆ readFEFLOWFile()

MeshLib::Mesh * FileIO::FEFLOWMeshInterface::readFEFLOWFile ( const std::string & filename)

read a FEFLOW Model file (*.fem) in ASCII format (Version 5.4)

This function reads mesh data in addition to geometry data given in Supermesh.

Parameters
filenameFEFLOW file name
Returns
a pointer to a created OGS mesh

Definition at line 24 of file FEFLOWMeshInterface.cpp.

25{
26 std::ifstream in(filename.c_str());
27 if (!in)
28 {
29 ERR("FEFLOWMeshInterface::readFEFLOWFile(): Could not open file {:s}.",
30 filename);
31 return nullptr;
32 }
33
34 FEM_CLASS fem_class;
35 FEM_DIM fem_dim;
36 std::vector<GeoLib::Point*> points;
37 std::vector<GeoLib::Polyline*> lines;
38
39 bool isXZplane = false;
40
41 std::vector<MeshLib::Node*> vec_nodes;
42 std::vector<MeshLib::Element*> vec_elements;
43
44 std::vector<std::vector<std::size_t>> vec_elementsets;
45 std::vector<std::string> vec_element_property_names;
46 std::vector<std::vector<double>> vec_element_property_values;
47
48 std::string line_string;
49 std::stringstream line_stream;
50 while (!in.eof())
51 {
52 std::getline(in, line_string);
53 boost::trim_right(line_string);
54 //....................................................................
55 // CLASS: the version number follows afterward, e.g. CLASS (v.5.313)
56 if (line_string.find("CLASS") != std::string::npos)
57 {
58 std::getline(in, line_string);
59 boost::trim_right(line_string);
60 line_stream.str(line_string);
61 // problem class, time mode, problem orientation, dimension, nr.
62 // layers for 3D, saturation switch, precision of results, precision
63 // of coordinates
64 line_stream >> fem_class.problem_class >> fem_class.time_mode >>
65 fem_class.orientation >> fem_class.dimension >>
66 fem_class.n_layers3d;
67 line_stream.clear();
68 }
69 //....................................................................
70 // DIMENS
71 else if (line_string == "DIMENS")
72 {
73 // DIMENS
74 std::getline(in, line_string);
75 line_stream.str(line_string);
76 line_stream >> fem_dim.n_nodes >> fem_dim.n_elements >>
77 fem_dim.n_nodes_of_element >> std::ws;
78 // create node pointers with dummy coordinates to create element
79 // objects.
80 // True coordinates are set later in COOR and ELEV_I.
81 vec_nodes.resize(fem_dim.n_nodes);
82 std::size_t count = 0;
83 double dummy_coords[3] = {};
84 std::generate(vec_nodes.begin(), vec_nodes.end(), [&]()
85 { return new MeshLib::Node(dummy_coords, count++); });
86 line_stream.clear();
87 }
88 //....................................................................
89 // NODE (node index for elements)
90 else if (line_string == "NODE")
91 {
92 assert(!vec_nodes.empty());
93
95 if (fem_dim.n_nodes_of_element == 2)
96 {
98 }
99 else if (fem_dim.n_nodes_of_element == 3)
100 {
102 }
103 else if (fem_dim.n_nodes_of_element == 4 &&
104 fem_class.dimension == 2)
105 {
107 }
108 else if (fem_dim.n_nodes_of_element == 4 &&
109 fem_class.dimension == 3)
110 {
112 }
113 else if (fem_dim.n_nodes_of_element == 6 &&
114 fem_class.dimension == 3)
115 {
117 }
118 else if (fem_dim.n_nodes_of_element == 8 &&
119 fem_class.dimension == 3)
120 {
122 }
123
124 if (eleType == MeshLib::MeshElemType::INVALID)
125 {
126 ERR("FEFLOWInterface::readFEFLOWFile(): Unsupported element "
127 "type with the number of node = {:d} and dim = {:d}",
128 fem_dim.n_nodes_of_element, fem_class.dimension);
129 std::for_each(vec_nodes.begin(), vec_nodes.end(),
130 [](MeshLib::Node* nod) { delete nod; });
131 vec_nodes.clear();
132 return nullptr;
133 }
134
135 vec_elements.reserve(fem_dim.n_elements);
136 for (std::size_t i = 0; i < fem_dim.n_elements; i++)
137 {
138 std::getline(in, line_string);
139 vec_elements.push_back(
140 readElement(fem_dim, eleType, line_string, vec_nodes));
141 }
142 }
143 else if (line_string == "VARNODE")
144 {
145 assert(!vec_nodes.empty());
146
147 vec_elements.reserve(fem_dim.n_elements);
148 if (fem_dim.n_nodes_of_element == 0)
149 { // mixed element case
150 if (!std::getline(in, line_string))
151 {
152 ERR("FEFLOWInterface::readFEFLOWFile(): read element "
153 "error");
154 std::for_each(vec_nodes.begin(), vec_nodes.end(),
155 [](MeshLib::Node* nod) { delete nod; });
156 vec_nodes.clear();
157 return nullptr;
158 }
159 }
160
161 for (std::size_t i = 0; i < fem_dim.n_elements; i++)
162 {
163 std::getline(in, line_string);
164 vec_elements.push_back(readElement(line_string, vec_nodes));
165 }
166 }
167 //....................................................................
168 // COOR
169 else if (line_string == "COOR")
170 {
171 readNodeCoordinates(in, fem_class, fem_dim, vec_nodes);
172 }
173 else if (line_string == "XYZCOOR")
174 {
175 readNodeCoordinates(in, vec_nodes);
176 }
177 // ELEV_I
178 else if (line_string == "ELEV_I")
179 {
180 if (fem_class.dimension == 2)
181 {
182 continue;
183 }
184 readElevation(in, fem_class, fem_dim, vec_nodes);
185 }
186 //....................................................................
187 // GRAVITY
188 else if (line_string == "GRAVITY")
189 {
190 std::getline(in, line_string);
191 line_stream.str(line_string);
192 double vec[3] = {};
193 line_stream >> vec[0] >> vec[1] >> vec[2];
194 if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
195 {
196 // x-z plane
197 isXZplane = true;
198 }
199 line_stream.clear();
200 }
201 //....................................................................
202 // ELEMENTALSETS
203 else if (line_string == "ELEMENTALSETS")
204 {
205 readELEMENTALSETS(in, vec_elementsets);
206 }
207 //....................................................................
208 // SUPERMESH
209 else if (line_string == "SUPERMESH")
210 {
211 FileIO::FEFLOWGeoInterface::readSuperMesh(in, fem_class.dimension,
212 points, lines);
213 }
214 //....................................................................
215 // MAT_I_FLOW
216 else if (line_string == "MAT_I_FLOW")
217 {
218 readMAT_I_FLOW(in, fem_dim, vec_element_property_names,
219 vec_element_property_values);
220 }
221 //....................................................................
222 }
223 in.close();
224
225 INFO("Create mesh");
226 std::string project_name(
228 auto mesh(
229 std::make_unique<MeshLib::Mesh>(project_name, vec_nodes, vec_elements));
230 INFO("Set values for material property.");
231 auto opt_material_ids(mesh->getProperties().createNewPropertyVector<int>(
232 "MaterialIDs", MeshLib::MeshItemType::Cell, 1));
233 if (!opt_material_ids)
234 {
235 WARN("Could not create PropertyVector for MaterialIDs in Mesh.");
236 }
237 else
238 {
239 opt_material_ids->resize(mesh->getNumberOfElements());
240 setMaterialIDs(fem_class, fem_dim, lines, vec_elementsets, vec_elements,
241 *opt_material_ids);
242 }
243 if (!vec_element_property_names.empty())
244 {
245 for (unsigned prop_id = 0; prop_id < vec_element_property_names.size();
246 prop_id++)
247 {
248 const std::string& property_name =
249 vec_element_property_names[prop_id];
250 const std::vector<double>& vec_property_values =
251 vec_element_property_values[prop_id];
252 assert(vec_property_values.size() == mesh->getNumberOfElements());
253 auto opt_element_property_values(
254 mesh->getProperties().createNewPropertyVector<double>(
255 property_name, MeshLib::MeshItemType::Cell, 1));
256 if (!opt_element_property_values)
257 {
258 WARN("Could not create PropertyVector for {:s} in Mesh.",
259 property_name);
260 }
261 else
262 {
263 opt_element_property_values->resize(
264 mesh->getNumberOfElements());
265 opt_element_property_values->assign(vec_property_values);
266 }
267 }
268 }
269
270 if (isXZplane)
271 {
272 for (auto* nod : vec_nodes)
273 {
274 (*nod)[2] = (*nod)[1];
275 (*nod)[1] = 0.0;
276 }
277 if (!points.empty())
278 {
279 for (auto* pt : points)
280 {
281 (*pt)[2] = (*pt)[1];
282 (*pt)[1] = .0;
283 }
284 }
285 }
286 for (auto* pt : points)
287 {
288 delete pt;
289 }
290 for (auto* line : lines)
291 {
292 delete line;
293 }
294 return mesh.release();
295}
static void readSuperMesh(std::ifstream &in, unsigned dimension, std::vector< GeoLib::Point * > &points, std::vector< GeoLib::Polyline * > &lines)
void readMAT_I_FLOW(std::ifstream &in, const FEM_DIM &fem_dim, std::vector< std::string > &vec_element_property_names, std::vector< std::vector< double > > &vec_element_property_values)
read MAT_I_FLOW data (material properties of flow problem)
void readNodeCoordinates(std::ifstream &in, std::vector< MeshLib::Node * > &nodes)
read node coordinates given in the XYZCOOR section
void readElevation(std::ifstream &in, const FEM_CLASS &fem_class, const FEM_DIM &fem_dim, std::vector< MeshLib::Node * > &vec_nodes)
read elevation data
void setMaterialIDs(FEM_CLASS const &fem_class, FEM_DIM const &fem_dim, std::vector< GeoLib::Polyline * > const &lines, std::vector< std::vector< std::size_t > > const &vec_elementsets, std::vector< MeshLib::Element * > const &vec_elements, MeshLib::PropertyVector< int > &material_ids)
MeshLib::Element * readElement(std::string const &line, std::vector< MeshLib::Node * > const &nodes)
Read element type and node indices according to the element type.
void readELEMENTALSETS(std::ifstream &in, std::vector< std::vector< std::size_t > > &vec_elementsets)
parse ELEMENTALSETS
std::string extractBaseNameWithoutExtension(std::string const &pathname)

References MeshLib::Cell, FileIO::FEFLOWMeshInterface::FEM_CLASS::dimension, ERR(), BaseLib::extractBaseNameWithoutExtension(), MeshLib::HEXAHEDRON, INFO(), MeshLib::INVALID, MeshLib::LINE, FileIO::FEFLOWMeshInterface::FEM_DIM::n_elements, FileIO::FEFLOWMeshInterface::FEM_CLASS::n_layers3d, FileIO::FEFLOWMeshInterface::FEM_DIM::n_nodes, FileIO::FEFLOWMeshInterface::FEM_DIM::n_nodes_of_element, FileIO::FEFLOWMeshInterface::FEM_CLASS::orientation, MeshLib::PRISM, FileIO::FEFLOWMeshInterface::FEM_CLASS::problem_class, MeshLib::QUAD, readElement(), readELEMENTALSETS(), readElevation(), readMAT_I_FLOW(), readNodeCoordinates(), FileIO::FEFLOWGeoInterface::readSuperMesh(), setMaterialIDs(), MeshLib::TETRAHEDRON, FileIO::FEFLOWMeshInterface::FEM_CLASS::time_mode, MeshLib::TRIANGLE, and WARN().

Referenced by MainWindow::loadFile(), and main().

◆ readMAT_I_FLOW()

void FileIO::FEFLOWMeshInterface::readMAT_I_FLOW ( std::ifstream & in,
const FEM_DIM & fem_dim,
std::vector< std::string > & vec_element_property_names,
std::vector< std::vector< double > > & vec_element_property_values )
private

read MAT_I_FLOW data (material properties of flow problem)

Definition at line 815 of file FEFLOWMeshInterface.cpp.

820{
821 std::string line_string;
822 std::stringstream line_stream;
823
824 auto is_header_of_material_property = [](const std::string& line_string)
825 {
826 if (line_string.empty())
827 {
828 return false;
829 }
830 return static_cast<bool>(isdigit(line_string.at(0)));
831 };
832
833 auto is_end_of_MAT_I_FLOW = [](const std::string& line_string)
834 { return (isalpha(line_string.at(0))); };
835
836 auto get_material_property_name = [](const std::string& line_string)
837 {
838 using Tok = boost::tokenizer<boost::escaped_list_separator<char>>;
839 Tok tok(line_string,
840 boost::escaped_list_separator<char>('\\', ' ', '"'));
841 std::vector<std::string> vec_str;
842 for (auto const& t : tok)
843 {
844 if (!t.empty())
845 {
846 vec_str.push_back(t);
847 }
848 }
849
850 if (vec_str.size() < 3)
851 {
852 return std::string("");
853 }
854 return vec_str[2];
855 };
856
857 std::streamoff pos_prev_line = 0;
858 while (!in.eof())
859 {
860 pos_prev_line = in.tellg();
861 std::getline(in, line_string);
862 boost::trim_right(line_string);
863 if (line_string.empty())
864 {
865 continue;
866 }
867 if (is_end_of_MAT_I_FLOW(line_string))
868 {
869 // move stream position to previous line
870 in.seekg(pos_prev_line);
871 break;
872 }
873
874 if (is_header_of_material_property(line_string))
875 {
876 const std::string property_name =
877 get_material_property_name(line_string);
878 if (!property_name.empty())
879 {
880 INFO("read element property {:s}", property_name);
881 vec_element_property_names.push_back(property_name);
882 vec_element_property_values.push_back(
883 readMaterialPropertyValues(in, fem_dim.n_elements));
884 }
885 }
886 }
887}
std::vector< double > readMaterialPropertyValues(std::ifstream &in, std::size_t n_elements)
read element values of a material property in MAT_I_FLOW data

References INFO(), FileIO::FEFLOWMeshInterface::FEM_DIM::n_elements, and readMaterialPropertyValues().

Referenced by readFEFLOWFile().

◆ readMaterialPropertyValues()

std::vector< double > FileIO::FEFLOWMeshInterface::readMaterialPropertyValues ( std::ifstream & in,
std::size_t n_elements )
private

read element values of a material property in MAT_I_FLOW data

Definition at line 740 of file FEFLOWMeshInterface.cpp.

742{
743 std::vector<double> vec_element_values(n_elements);
744
745 double property_value = 0;
746 std::string str_elementList;
747 std::string line_string;
748 std::stringstream line_stream;
749 unsigned prev_mode = 0;
750 std::streamoff pos_prev_line = 0;
751 while (true)
752 {
753 pos_prev_line = in.tellg();
754 std::getline(in, line_string);
755 boost::trim_right(line_string);
756 if (line_string.empty())
757 {
758 continue;
759 }
760
761 // check mode
762 unsigned mode = 0; // 0: exit, 1: value + corresponding element
763 // numbers, 2: continued line of mode 1
764 if ((!in || (line_string[0] != ' ' && line_string[0] != '\t')) &&
765 prev_mode != 0)
766 {
767 mode = 0;
768 }
769 else if (line_string[0] != '\t')
770 {
771 mode = 1;
772 }
773 else if (line_string[0] == '\t')
774 {
775 mode = 2;
776 }
777 prev_mode = mode;
778
779 // process stocked data
780 if (mode != 2 && !str_elementList.empty())
781 {
782 // process previous lines
783 auto vec_elementIDs = getIndexList(str_elementList);
784 for (auto elementID : vec_elementIDs)
785 {
786 vec_element_values[elementID - 1] = property_value;
787 }
788 str_elementList.clear();
789 }
790
791 if (mode == 0)
792 {
793 // move stream position to previous line
794 in.seekg(pos_prev_line);
795 break;
796 }
797 if (mode == 1)
798 {
799 line_stream.str(line_string);
800 line_stream >> property_value;
801 std::getline(line_stream, str_elementList);
802 boost::trim(str_elementList);
803 line_stream.clear();
804 }
805 else if (mode == 2)
806 {
807 // continue reading node range
808 boost::trim_if(line_string, boost::is_any_of("\t"));
809 str_elementList += " " + line_string;
810 }
811 }
812 return vec_element_values;
813}

References getIndexList().

Referenced by readMAT_I_FLOW().

◆ readNodeCoordinates() [1/2]

void FileIO::FEFLOWMeshInterface::readNodeCoordinates ( std::ifstream & in,
const FEM_CLASS & fem_class,
const FEM_DIM & fem_dim,
std::vector< MeshLib::Node * > const & nodes )
private

read node coordinates

Definition at line 342 of file FEFLOWMeshInterface.cpp.

345{
346 const std::size_t no_nodes_per_layer =
347 (fem_class.dimension == 2)
348 ? fem_dim.n_nodes
349 : fem_dim.n_nodes / (fem_class.n_layers3d + 1);
350 assert(no_nodes_per_layer > 0);
351 const std::size_t n_lines = (no_nodes_per_layer - 1) / 12 + 1;
352 const std::size_t n_layers =
353 (fem_class.dimension == 3) ? fem_class.n_layers3d + 1 : 1;
354 std::string line_string;
355 std::stringstream line_stream;
356 double x;
357 char dummy_char; // for comma(,)
358 // x, y
359 for (unsigned k = 0; k < 2; k++)
360 {
361 // each line
362 for (std::size_t i = 0; i < n_lines; i++)
363 {
364 std::getline(in, line_string);
365 line_stream.str(line_string);
366 for (unsigned j = 0; j < 12; j++)
367 {
368 if (i * 12 + j >= no_nodes_per_layer)
369 {
370 break;
371 }
372 line_stream >> x >> dummy_char;
373 for (std::size_t l = 0; l < n_layers; l++)
374 {
375 const std::size_t n = i * 12 + l * no_nodes_per_layer + j;
376 MeshLib::Node* m_nod = vec_nodes[n];
377 if (k == 0)
378 {
379 (*m_nod)[0] = x;
380 }
381 else
382 {
383 (*m_nod)[1] = x;
384 }
385 }
386 }
387 line_stream.clear();
388 }
389 }
390}

References FileIO::FEFLOWMeshInterface::FEM_CLASS::dimension, FileIO::FEFLOWMeshInterface::FEM_CLASS::n_layers3d, and FileIO::FEFLOWMeshInterface::FEM_DIM::n_nodes.

◆ readNodeCoordinates() [2/2]

void FileIO::FEFLOWMeshInterface::readNodeCoordinates ( std::ifstream & in,
std::vector< MeshLib::Node * > & nodes )
private

read node coordinates given in the XYZCOOR section

Definition at line 297 of file FEFLOWMeshInterface.cpp.

299{
300 std::string line_string;
301 char dummy_char; // for comma(,)
302
303 for (unsigned k = 0; k < vec_nodes.size(); ++k)
304 {
305 // read the line containing the coordinates as string
306 if (!std::getline(in, line_string))
307 {
308 ERR("Could not read the node '{:d}'.", k);
309 for (auto* n : vec_nodes)
310 {
311 delete n;
312 }
313 return;
314 }
315 std::stringstream line_stream;
316 line_stream.str(line_string);
317 // parse the particular coordinates from the string read above
318 for (std::size_t i(0); i < 3; ++i)
319 {
320 if (!(line_stream >> (*vec_nodes[k])[i]))
321 {
322 ERR("Could not parse coordinate {:d} of node '{:d}'.", i, k);
323 for (auto* n : vec_nodes)
324 {
325 delete n;
326 }
327 return;
328 }
329 if (!(line_stream >> dummy_char) && i < 2) // read comma
330 {
331 ERR("Could not parse node '{:d}'.", k);
332 for (auto* n : vec_nodes)
333 {
334 delete n;
335 }
336 return;
337 }
338 }
339 }
340}

References ERR().

Referenced by readFEFLOWFile().

◆ setMaterialIDs()

void FileIO::FEFLOWMeshInterface::setMaterialIDs ( FEM_CLASS const & fem_class,
FEM_DIM const & fem_dim,
std::vector< GeoLib::Polyline * > const & lines,
std::vector< std::vector< std::size_t > > const & vec_elementsets,
std::vector< MeshLib::Element * > const & vec_elements,
MeshLib::PropertyVector< int > & material_ids )
private

Definition at line 889 of file FEFLOWMeshInterface.cpp.

896{
897 assert(material_ids.size() == vec_elements.size());
898 if (!vec_elementsets.empty())
899 {
900 for (std::size_t matid = 0; matid < vec_elementsets.size(); ++matid)
901 {
902 auto& eids = vec_elementsets[matid];
903 for (auto eid : eids)
904 {
905 material_ids[eid - 1] =
906 matid; // Element IDs given by FEFLOW starts from one!
907 }
908 }
909 }
910 else if (!lines.empty())
911 {
912 for (std::size_t i = 0; i < vec_elements.size(); ++i)
913 {
914 auto const gpt = MeshLib::getCenterOfGravity(*vec_elements[i]);
915 std::size_t matId = 0;
916 for (std::size_t j = 0; j < lines.size(); j++)
917 {
918 GeoLib::Polyline const& poly = *lines[j];
919 if (!poly.isClosed())
920 {
921 continue;
922 }
923
924 GeoLib::Polygon polygon(poly, true);
925 if (polygon.isPntInPolygon(gpt))
926 {
927 matId = j;
928 break;
929 }
930 }
931 material_ids[i] = matId;
932 }
933 }
934 else if (fem_class.n_layers3d > 0)
935 {
936 const std::size_t no_nodes_per_layer =
937 fem_dim.n_nodes / (fem_class.n_layers3d + 1);
938 for (std::size_t i = 0; i < vec_elements.size(); i++)
939 {
940 MeshLib::Element* e = vec_elements[i];
941 std::size_t e_min_nodeID = std::numeric_limits<std::size_t>::max();
942 for (std::size_t j = 0; j < e->getNumberOfBaseNodes(); j++)
943 {
944 e_min_nodeID = std::min(e_min_nodeID, getNodeIndex(*e, j));
945 }
946 std::size_t layer_id = e_min_nodeID / no_nodes_per_layer;
947 material_ids[i] = layer_id;
948 }
949 }
950}
bool isClosed() const
Definition Polyline.cpp:108
virtual unsigned getNumberOfBaseNodes() const =0
constexpr std::size_t size() const
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition Element.cpp:226
MathLib::Point3d getCenterOfGravity(Element const &element)
Calculates the center of gravity for the mesh element.
Definition Element.cpp:131

References MeshLib::getCenterOfGravity(), MeshLib::Element::getNumberOfBaseNodes(), GeoLib::Polyline::isClosed(), GeoLib::Polygon::isPntInPolygon(), FileIO::FEFLOWMeshInterface::FEM_CLASS::n_layers3d, FileIO::FEFLOWMeshInterface::FEM_DIM::n_nodes, and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by readFEFLOWFile().


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