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 386 of file FEFLOWMeshInterface.cpp.

388{
389 std::vector<std::size_t> vec_node_IDs;
390
391 // insert space before and after minus for splitting
392 std::string str_ranges2(BaseLib::replaceString("-", " # ", str_ranges));
393 BaseLib::trim(str_ranges2);
394 auto splitted_str = BaseLib::splitString(str_ranges2, ' ');
395 bool is_range = false;
396 for (auto str : splitted_str)
397 {
398 if (str.empty())
399 {
400 continue;
401 }
402 if (str[0] == '#')
403 {
404 is_range = true;
405 }
406 else if (is_range)
407 {
408 const std::size_t start = vec_node_IDs.back();
409 const auto end = BaseLib::str2number<std::size_t>(str);
410 for (std::size_t i = start + 1; i < end + 1; i++)
411 {
412 vec_node_IDs.push_back(i);
413 }
414 is_range = false;
415 }
416 else
417 {
418 BaseLib::trim(str);
419 vec_node_IDs.push_back(BaseLib::str2number<std::size_t>(str));
420 }
421 }
422
423 return vec_node_IDs;
424}
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:53

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 585 of file FEFLOWMeshInterface.cpp.

588{
589 std::stringstream ss(line);
590
591 unsigned idx[8];
592 for (std::size_t i = 0; i < fem_dim.n_nodes_of_element; ++i)
593 {
594 ss >> idx[i];
595 }
596 auto** ele_nodes = new MeshLib::Node*[fem_dim.n_nodes_of_element];
597
598 switch (elem_type)
599 {
600 default:
601 for (unsigned k(0); k < fem_dim.n_nodes_of_element; ++k)
602 {
603 ele_nodes[k] = nodes[idx[k] - 1];
604 }
605 break;
608 const unsigned n_half_nodes = fem_dim.n_nodes_of_element / 2;
609 for (unsigned k(0); k < n_half_nodes; ++k)
610 {
611 ele_nodes[k] = nodes[idx[k + n_half_nodes] - 1];
612 ele_nodes[k + n_half_nodes] = nodes[idx[k] - 1];
613 }
614 break;
615 }
616
617 switch (elem_type)
618 {
620 return new MeshLib::Line(ele_nodes);
622 return new MeshLib::Tri(ele_nodes);
624 return new MeshLib::Quad(ele_nodes);
626 return new MeshLib::Tet(ele_nodes);
628 return new MeshLib::Hex(ele_nodes);
630 return new MeshLib::Prism(ele_nodes);
631 default:
632 assert(false);
633 return nullptr;
634 }
635}
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 517 of file FEFLOWMeshInterface.cpp.

519{
520 std::stringstream ss(line);
521
522 int ele_type;
523 ss >> ele_type;
524
525 MeshLib::MeshElemType elem_type;
526 std::size_t n_nodes_of_element;
527 switch (ele_type)
528 {
529 case 6:
531 n_nodes_of_element = 4;
532 break;
533 case 7:
535 n_nodes_of_element = 6;
536 break;
537 case 8:
539 n_nodes_of_element = 8;
540 break;
541 default:
542 WARN("Could not parse element type.");
543 return nullptr;
544 }
545
546 unsigned idx[8];
547 for (std::size_t i = 0; i < n_nodes_of_element; ++i)
548 {
549 ss >> idx[i];
550 }
551 auto** ele_nodes = new MeshLib::Node*[n_nodes_of_element];
552
553 switch (elem_type)
554 {
555 default:
556 for (std::size_t k(0); k < n_nodes_of_element; ++k)
557 {
558 ele_nodes[k] = nodes[idx[k] - 1];
559 }
560 break;
563 const unsigned n_half_nodes = n_nodes_of_element / 2;
564 for (unsigned k(0); k < n_half_nodes; ++k)
565 {
566 ele_nodes[k] = nodes[idx[k + n_half_nodes] - 1];
567 ele_nodes[k + n_half_nodes] = nodes[idx[k] - 1];
568 }
569 break;
570 }
571
572 switch (elem_type)
573 {
575 return new MeshLib::Tet(ele_nodes);
577 return new MeshLib::Hex(ele_nodes);
579 return new MeshLib::Prism(ele_nodes);
580 default:
581 return nullptr;
582 }
583}
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:37

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 637 of file FEFLOWMeshInterface.cpp.

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

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 426 of file FEFLOWMeshInterface.cpp.

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

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 [&]()
86 { return new MeshLib::Node(dummy_coords, count++); });
87 line_stream.clear();
88 }
89 //....................................................................
90 // NODE (node index for elements)
91 else if (line_string == "NODE")
92 {
93 assert(!vec_nodes.empty());
94
96 if (fem_dim.n_nodes_of_element == 2)
97 {
99 }
100 else if (fem_dim.n_nodes_of_element == 3)
101 {
103 }
104 else if (fem_dim.n_nodes_of_element == 4 &&
105 fem_class.dimension == 2)
106 {
108 }
109 else if (fem_dim.n_nodes_of_element == 4 &&
110 fem_class.dimension == 3)
111 {
113 }
114 else if (fem_dim.n_nodes_of_element == 6 &&
115 fem_class.dimension == 3)
116 {
118 }
119 else if (fem_dim.n_nodes_of_element == 8 &&
120 fem_class.dimension == 3)
121 {
123 }
124
125 if (eleType == MeshLib::MeshElemType::INVALID)
126 {
127 ERR("FEFLOWInterface::readFEFLOWFile(): Unsupported element "
128 "type with the number of node = {:d} and dim = {:d}",
129 fem_dim.n_nodes_of_element, fem_class.dimension);
130 std::for_each(vec_nodes.begin(), vec_nodes.end(),
131 [](MeshLib::Node* nod) { delete nod; });
132 vec_nodes.clear();
133 return nullptr;
134 }
135
136 vec_elements.reserve(fem_dim.n_elements);
137 for (std::size_t i = 0; i < fem_dim.n_elements; i++)
138 {
139 std::getline(in, line_string);
140 vec_elements.push_back(
141 readElement(fem_dim, eleType, line_string, vec_nodes));
142 }
143 }
144 else if (line_string == "VARNODE")
145 {
146 assert(!vec_nodes.empty());
147
148 vec_elements.reserve(fem_dim.n_elements);
149 if (fem_dim.n_nodes_of_element == 0)
150 { // mixed element case
151 if (!std::getline(in, line_string))
152 {
153 ERR("FEFLOWInterface::readFEFLOWFile(): read element "
154 "error");
155 std::for_each(vec_nodes.begin(), vec_nodes.end(),
156 [](MeshLib::Node* nod) { delete nod; });
157 vec_nodes.clear();
158 return nullptr;
159 }
160 }
161
162 for (std::size_t i = 0; i < fem_dim.n_elements; i++)
163 {
164 std::getline(in, line_string);
165 vec_elements.push_back(readElement(line_string, vec_nodes));
166 }
167 }
168 //....................................................................
169 // COOR
170 else if (line_string == "COOR")
171 {
172 readNodeCoordinates(in, fem_class, fem_dim, vec_nodes);
173 }
174 else if (line_string == "XYZCOOR")
175 {
176 readNodeCoordinates(in, vec_nodes);
177 }
178 // ELEV_I
179 else if (line_string == "ELEV_I")
180 {
181 if (fem_class.dimension == 2)
182 {
183 continue;
184 }
185 readElevation(in, fem_class, fem_dim, vec_nodes);
186 }
187 //....................................................................
188 // GRAVITY
189 else if (line_string == "GRAVITY")
190 {
191 std::getline(in, line_string);
192 line_stream.str(line_string);
193 double vec[3] = {};
194 line_stream >> vec[0] >> vec[1] >> vec[2];
195 if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
196 {
197 // x-z plane
198 isXZplane = true;
199 }
200 line_stream.clear();
201 }
202 //....................................................................
203 // ELEMENTALSETS
204 else if (line_string == "ELEMENTALSETS")
205 {
206 readELEMENTALSETS(in, vec_elementsets);
207 }
208 //....................................................................
209 // SUPERMESH
210 else if (line_string == "SUPERMESH")
211 {
212 FileIO::FEFLOWGeoInterface::readSuperMesh(in, fem_class.dimension,
213 points, lines);
214 }
215 //....................................................................
216 // MAT_I_FLOW
217 else if (line_string == "MAT_I_FLOW")
218 {
219 readMAT_I_FLOW(in, fem_dim, vec_element_property_names,
220 vec_element_property_values);
221 }
222 //....................................................................
223 }
224 in.close();
225
226 INFO("Create mesh");
227 std::string project_name(
229 auto mesh(
230 std::make_unique<MeshLib::Mesh>(project_name, vec_nodes, vec_elements));
231 INFO("Set values for material property.");
232 auto opt_material_ids(mesh->getProperties().createNewPropertyVector<int>(
233 "MaterialIDs", MeshLib::MeshItemType::Cell, 1));
234 if (!opt_material_ids)
235 {
236 WARN("Could not create PropertyVector for MaterialIDs in Mesh.");
237 }
238 else
239 {
240 opt_material_ids->resize(mesh->getNumberOfElements());
241 setMaterialIDs(fem_class, fem_dim, lines, vec_elementsets, vec_elements,
242 *opt_material_ids);
243 }
244 if (!vec_element_property_names.empty())
245 {
246 for (unsigned prop_id = 0; prop_id < vec_element_property_names.size();
247 prop_id++)
248 {
249 const std::string& property_name =
250 vec_element_property_names[prop_id];
251 const std::vector<double>& vec_property_values =
252 vec_element_property_values[prop_id];
253 assert(vec_property_values.size() == mesh->getNumberOfElements());
254 auto opt_element_property_values(
255 mesh->getProperties().createNewPropertyVector<double>(
256 property_name, MeshLib::MeshItemType::Cell, 1));
257 if (!opt_element_property_values)
258 {
259 WARN("Could not create PropertyVector for {:s} in Mesh.",
260 property_name);
261 }
262 else
263 {
264 opt_element_property_values->resize(
265 mesh->getNumberOfElements());
266 opt_element_property_values->assign(vec_property_values);
267 }
268 }
269 }
270
271 if (isXZplane)
272 {
273 for (auto* nod : vec_nodes)
274 {
275 (*nod)[2] = (*nod)[1];
276 (*nod)[1] = 0.0;
277 }
278 if (!points.empty())
279 {
280 for (auto* pt : points)
281 {
282 (*pt)[2] = (*pt)[1];
283 (*pt)[1] = .0;
284 }
285 }
286 }
287
288 return mesh.release();
289}
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 809 of file FEFLOWMeshInterface.cpp.

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

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

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 336 of file FEFLOWMeshInterface.cpp.

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

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 291 of file FEFLOWMeshInterface.cpp.

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

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 883 of file FEFLOWMeshInterface.cpp.

890{
891 assert(material_ids.size() == vec_elements.size());
892 if (!vec_elementsets.empty())
893 {
894 for (std::size_t matid = 0; matid < vec_elementsets.size(); ++matid)
895 {
896 auto& eids = vec_elementsets[matid];
897 for (auto eid : eids)
898 {
899 material_ids[eid - 1] =
900 matid; // Element IDs given by FEFLOW starts from one!
901 }
902 }
903 }
904 else if (!lines.empty())
905 {
906 for (std::size_t i = 0; i < vec_elements.size(); ++i)
907 {
908 auto const gpt = MeshLib::getCenterOfGravity(*vec_elements[i]);
909 std::size_t matId = 0;
910 for (std::size_t j = 0; j < lines.size(); j++)
911 {
912 GeoLib::Polyline const& poly = *lines[j];
913 if (!poly.isClosed())
914 {
915 continue;
916 }
917
918 GeoLib::Polygon polygon(poly, true);
919 if (polygon.isPntInPolygon(gpt))
920 {
921 matId = j;
922 break;
923 }
924 }
925 material_ids[i] = matId;
926 }
927 }
928 else if (fem_class.n_layers3d > 0)
929 {
930 const std::size_t no_nodes_per_layer =
931 fem_dim.n_nodes / (fem_class.n_layers3d + 1);
932 for (std::size_t i = 0; i < vec_elements.size(); i++)
933 {
934 MeshLib::Element* e = vec_elements[i];
935 std::size_t e_min_nodeID = std::numeric_limits<std::size_t>::max();
936 for (std::size_t j = 0; j < e->getNumberOfBaseNodes(); j++)
937 {
938 e_min_nodeID = std::min(e_min_nodeID, getNodeIndex(*e, j));
939 }
940 std::size_t layer_id = e_min_nodeID / no_nodes_per_layer;
941 material_ids[i] = layer_id;
942 }
943 }
944}
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: