11 #include <boost/algorithm/string/trim.hpp>
29 std::ifstream in(filename.c_str());
32 ERR(
"FEFLOWMeshInterface::readFEFLOWFile(): Could not open file {:s}.",
39 std::vector<GeoLib::Point*>* points =
nullptr;
40 std::vector<GeoLib::Polyline*>* lines =
nullptr;
42 bool isXZplane =
false;
44 std::vector<MeshLib::Node*> vec_nodes;
45 std::vector<MeshLib::Element*> vec_elements;
47 std::vector<std::vector<std::size_t>> vec_elementsets;
49 std::string line_string;
50 std::stringstream line_stream;
53 std::getline(in, line_string);
54 boost::trim_right(line_string);
57 if (line_string.find(
"CLASS") != std::string::npos)
59 std::getline(in, line_string);
60 boost::trim_right(line_string);
61 line_stream.str(line_string);
72 else if (line_string ==
"DIMENS")
75 std::getline(in, line_string);
76 line_stream.str(line_string);
82 vec_nodes.resize(fem_dim.
n_nodes);
83 std::size_t count = 0;
84 double dummy_coords[3] = {};
85 std::generate(vec_nodes.begin(), vec_nodes.end(),
87 { return new MeshLib::Node(dummy_coords, count++); });
92 else if (line_string ==
"NODE")
94 assert(!vec_nodes.empty());
128 ERR(
"FEFLOWInterface::readFEFLOWFile(): Unsupported element "
129 "type with the number of node = {:d} and dim = {:d}",
131 std::for_each(vec_nodes.begin(), vec_nodes.end(),
138 for (std::size_t i = 0; i < fem_dim.
n_elements; i++)
140 std::getline(in, line_string);
141 vec_elements.push_back(
142 readElement(fem_dim, eleType, line_string, vec_nodes));
145 else if (line_string ==
"VARNODE")
147 assert(!vec_nodes.empty());
152 if (!std::getline(in, line_string))
154 ERR(
"FEFLOWInterface::readFEFLOWFile(): read element "
156 std::for_each(vec_nodes.begin(), vec_nodes.end(),
163 for (std::size_t i = 0; i < fem_dim.
n_elements; i++)
165 std::getline(in, line_string);
166 vec_elements.push_back(
readElement(line_string, vec_nodes));
171 else if (line_string ==
"COOR")
175 else if (line_string ==
"XYZCOOR")
180 else if (line_string ==
"ELEV_I")
190 else if (line_string ==
"GRAVITY")
192 getline(in, line_string);
193 line_stream.str(line_string);
195 line_stream >> vec[0] >> vec[1] >> vec[2];
196 if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
205 else if (line_string ==
"ELEMENTALSETS")
211 else if (line_string ==
"SUPERMESH")
221 std::string project_name(
224 std::make_unique<MeshLib::Mesh>(project_name, vec_nodes, vec_elements));
225 INFO(
"Set values for material property.");
226 auto opt_material_ids(mesh->getProperties().createNewPropertyVector<
int>(
228 if (!opt_material_ids)
230 WARN(
"Could not create PropertyVector for MaterialIDs in Mesh.");
234 opt_material_ids->resize(mesh->getNumberOfElements());
235 setMaterialIDs(fem_class, fem_dim, lines, vec_elementsets, vec_elements,
241 for (
auto* nod : vec_nodes)
243 (*nod)[2] = (*nod)[1];
248 for (
auto* pt : *points)
256 return mesh.release();
260 std::ifstream& in, std::vector<MeshLib::Node*>& vec_nodes)
262 std::string line_string;
265 for (
unsigned k = 0; k < vec_nodes.size(); ++k)
268 if (!std::getline(in, line_string))
270 ERR(
"Could not read the node '{:d}'.", k);
271 for (
auto* n : vec_nodes)
277 std::stringstream line_stream;
278 line_stream.str(line_string);
280 for (std::size_t i(0); i < 3; ++i)
282 if (!(line_stream >> (*vec_nodes[k])[i]))
284 ERR(
"Could not parse coordinate {:d} of node '{:d}'.", i, k);
285 for (
auto* n : vec_nodes)
291 if (!(line_stream >> dummy_char) && i < 2)
293 ERR(
"Could not parse node '{:d}'.", k);
294 for (
auto* n : vec_nodes)
306 std::vector<MeshLib::Node*>
const& vec_nodes)
308 const std::size_t no_nodes_per_layer =
312 assert(no_nodes_per_layer > 0);
313 const std::size_t n_lines = (no_nodes_per_layer - 1) / 12 + 1;
314 const std::size_t n_layers =
316 std::string line_string;
317 std::stringstream line_stream;
321 for (
unsigned k = 0; k < 2; k++)
324 for (std::size_t i = 0; i < n_lines; i++)
326 getline(in, line_string);
327 line_stream.str(line_string);
328 for (
unsigned j = 0; j < 12; j++)
330 if (i * 12 + j >= no_nodes_per_layer)
334 line_stream >> x >> dummy_char;
335 for (std::size_t l = 0; l < n_layers; l++)
337 const std::size_t n = i * 12 + l * no_nodes_per_layer + j;
355 const std::string& str_ranges)
357 std::vector<std::size_t> vec_node_IDs;
363 bool is_range =
false;
364 for (
auto str : splitted_str)
376 const std::size_t start = vec_node_IDs.back();
377 const auto end = BaseLib::str2number<std::size_t>(str);
378 for (std::size_t i = start + 1; i < end + 1; i++)
380 vec_node_IDs.push_back(i);
387 vec_node_IDs.push_back(BaseLib::str2number<std::size_t>(str));
397 std::vector<MeshLib::Node*>& vec_nodes)
399 const std::size_t no_nodes_per_layer =
402 std::string str_nodeList;
403 std::string line_string;
404 std::stringstream line_stream;
408 std::streamoff pos_prev_line = 0;
411 pos_prev_line = in.tellg();
412 std::getline(in, line_string);
413 boost::trim_right(line_string);
417 if (!in || std::isalpha(line_string[0]))
421 else if (line_string.empty())
425 else if (line_string[0] ==
'\t')
429 else if (columns.size() == 1)
439 if (mode != 3 && !str_nodeList.empty())
443 for (
auto n0 : vec_nodeIDs)
445 const std::size_t n = n0 - 1 + l * no_nodes_per_layer;
446 (*vec_nodes[n])[2] = z;
448 str_nodeList.clear();
459 assert(l + 1 == BaseLib::str2number<std::size_t>(columns.front()));
464 line_stream.str(line_string);
466 std::getline(line_stream, str_nodeList);
474 str_nodeList +=
" " + line_string;
479 if (std::isalpha(line_string[0]))
481 in.seekg(pos_prev_line);
486 std::string
const& line, std::vector<MeshLib::Node*>
const& nodes)
488 std::stringstream ss(line);
494 std::size_t n_nodes_of_element;
499 n_nodes_of_element = 4;
503 n_nodes_of_element = 6;
507 n_nodes_of_element = 8;
510 WARN(
"Could not parse element type.");
515 for (std::size_t i = 0; i < n_nodes_of_element; ++i)
524 for (std::size_t k(0); k < n_nodes_of_element; ++k)
526 ele_nodes[k] = nodes[idx[k] - 1];
531 const unsigned n_half_nodes = n_nodes_of_element / 2;
532 for (
unsigned k(0); k < n_half_nodes; ++k)
534 ele_nodes[k] = nodes[idx[k + n_half_nodes] - 1];
535 ele_nodes[k + n_half_nodes] = nodes[idx[k] - 1];
555 const std::string& line,
const std::vector<MeshLib::Node*>& nodes)
557 std::stringstream ss(line);
571 ele_nodes[k] = nodes[idx[k] - 1];
577 for (
unsigned k(0); k < n_half_nodes; ++k)
579 ele_nodes[k] = nodes[idx[k + n_half_nodes] - 1];
580 ele_nodes[k + n_half_nodes] = nodes[idx[k] - 1];
606 std::ifstream& in, std::vector<std::vector<std::size_t>>& vec_elementsets)
608 auto compressSpaces = [](std::string
const& str)
610 std::stringstream ss(str);
616 new_str +=
" " + word;
621 std::string line_string;
622 std::string str_idList;
623 std::streampos pos_prev_line = 0;
626 pos_prev_line = in.tellg();
627 getline(in, line_string);
634 else if (line_string.empty())
638 else if (std::isalpha(line_string[0]))
642 else if (line_string[0] ==
' ')
646 else if (line_string[0] ==
'\t')
652 ERR(
"Failed during parsing of an ELEMENTALSETS section in a FEFLOW "
657 if (mode != 2 && !str_idList.empty())
670 std::string set_name;
673 if (line_string[0] ==
'"')
675 auto pos = line_string.find_last_of(
'"');
676 set_name = line_string.substr(1, pos - 1);
677 ids = line_string.substr(pos + 1);
681 auto pos = line_string.find_first_of(
' ');
682 set_name = line_string.substr(0, pos);
683 ids = line_string.substr(pos + 1);
685 INFO(
"Found an element group - {:s}", set_name.data());
686 str_idList += compressSpaces(ids);
692 str_idList += compressSpaces(line_string);
696 if (std::isalpha(line_string[0]))
698 in.seekg(pos_prev_line);
705 std::vector<GeoLib::Polyline*>*
const& lines,
706 std::vector<std::vector<std::size_t>>
const& vec_elementsets,
707 std::vector<MeshLib::Element*>
const& vec_elements,
708 std::vector<int>& material_ids)
710 assert(material_ids.size() == vec_elements.size());
711 if (!vec_elementsets.empty())
713 for (std::size_t matid = 0; matid < vec_elementsets.size(); ++matid)
715 auto& eids = vec_elementsets[matid];
716 for (
auto eid : eids)
718 material_ids[eid - 1] =
723 else if (lines && !lines->empty())
725 for (std::size_t i = 0; i < vec_elements.size(); ++i)
729 std::size_t matId = 0;
730 for (std::size_t j = 0; j < lines->size(); j++)
745 material_ids[i] = matId;
750 const std::size_t no_nodes_per_layer =
752 for (std::size_t i = 0; i < vec_elements.size(); i++)
755 std::size_t e_min_nodeID = std::numeric_limits<std::size_t>::max();
758 e_min_nodeID = std::min(e_min_nodeID,
getNodeIndex(*e, j));
760 std::size_t layer_id = e_min_nodeID / no_nodes_per_layer;
761 material_ids[i] = layer_id;
Definition of the Point class.
void INFO(char const *fmt, Args const &... args)
void ERR(char const *fmt, Args const &... args)
void WARN(char const *fmt, Args const &... args)
Definition of the Mesh class.
Definition of the Node class.
Definition of the Polygon class.
static void readSuperMesh(std::ifstream &in, unsigned dimension, std::vector< GeoLib::Point * > *&points, std::vector< GeoLib::Polyline * > *&lines)
std::vector< std::size_t > getIndexList(const std::string &str_ranges)
void readNodeCoordinates(std::ifstream &in, std::vector< MeshLib::Node * > &nodes)
read node coordinates given in the XYZCOOR section
void readELEMENTALSETS(std::ifstream &in, std::vector< std::vector< std::size_t >> &vec_elementsets)
parse ELEMENTALSETS
MeshLib::Mesh * readFEFLOWFile(const std::string &filename)
void readElevation(std::ifstream &in, const FEM_CLASS &fem_class, const FEM_DIM &fem_dim, std::vector< MeshLib::Node * > &vec_nodes)
read elevation data
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 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, std::vector< int > &material_ids)
bool isPntInPolygon(const MathLib::Point3d &pnt) const
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
virtual unsigned getNumberOfBaseNodes() const =0
std::string replaceString(const std::string &searchString, const std::string &replaceString, std::string stringToReplace)
void trim(std::string &str, char ch)
std::string extractBaseNameWithoutExtension(std::string const &pathname)
std::vector< std::string > splitString(std::string const &str)
TemplateElement< MeshLib::TetRule4 > Tet
TemplateElement< MeshLib::LineRule2 > Line
std::size_t getNodeIndex(Element const &element, unsigned const idx)
TemplateElement< MeshLib::TriRule3 > Tri
TemplateElement< MeshLib::PrismRule6 > Prism
MeshLib::Node getCenterOfGravity(Element const &element)
Calculates the center of gravity for the mesh element.
MeshElemType
Types of mesh elements supported by OpenGeoSys. Values are from VTKCellType enum.
TemplateElement< MeshLib::HexRule8 > Hex
TemplateElement< MeshLib::QuadRule4 > Quad
unsigned n_nodes_of_element