26 std::ifstream in(filename.c_str());
29 ERR(
"FEFLOWMeshInterface::readFEFLOWFile(): Could not open file {:s}.",
36 std::vector<GeoLib::Point*> points;
37 std::vector<GeoLib::Polyline*> lines;
39 bool isXZplane =
false;
41 std::vector<MeshLib::Node*> vec_nodes;
42 std::vector<MeshLib::Element*> vec_elements;
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;
48 std::string line_string;
49 std::stringstream line_stream;
52 std::getline(in, line_string);
53 boost::trim_right(line_string);
56 if (line_string.find(
"CLASS") != std::string::npos)
58 std::getline(in, line_string);
59 boost::trim_right(line_string);
60 line_stream.str(line_string);
71 else if (line_string ==
"DIMENS")
74 std::getline(in, line_string);
75 line_stream.str(line_string);
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(),
86 { return new MeshLib::Node(dummy_coords, count++); });
91 else if (line_string ==
"NODE")
93 assert(!vec_nodes.empty());
127 ERR(
"FEFLOWInterface::readFEFLOWFile(): Unsupported element "
128 "type with the number of node = {:d} and dim = {:d}",
130 std::for_each(vec_nodes.begin(), vec_nodes.end(),
137 for (std::size_t i = 0; i < fem_dim.
n_elements; i++)
139 std::getline(in, line_string);
140 vec_elements.push_back(
141 readElement(fem_dim, eleType, line_string, vec_nodes));
144 else if (line_string ==
"VARNODE")
146 assert(!vec_nodes.empty());
151 if (!std::getline(in, line_string))
153 ERR(
"FEFLOWInterface::readFEFLOWFile(): read element "
155 std::for_each(vec_nodes.begin(), vec_nodes.end(),
162 for (std::size_t i = 0; i < fem_dim.
n_elements; i++)
164 std::getline(in, line_string);
165 vec_elements.push_back(
readElement(line_string, vec_nodes));
170 else if (line_string ==
"COOR")
174 else if (line_string ==
"XYZCOOR")
179 else if (line_string ==
"ELEV_I")
189 else if (line_string ==
"GRAVITY")
191 std::getline(in, line_string);
192 line_stream.str(line_string);
194 line_stream >> vec[0] >> vec[1] >> vec[2];
195 if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
204 else if (line_string ==
"ELEMENTALSETS")
210 else if (line_string ==
"SUPERMESH")
217 else if (line_string ==
"MAT_I_FLOW")
220 vec_element_property_values);
227 std::string project_name(
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>(
234 if (!opt_material_ids)
236 WARN(
"Could not create PropertyVector for MaterialIDs in Mesh.");
240 opt_material_ids->resize(mesh->getNumberOfElements());
241 setMaterialIDs(fem_class, fem_dim, lines, vec_elementsets, vec_elements,
244 if (!vec_element_property_names.empty())
246 for (
unsigned prop_id = 0; prop_id < vec_element_property_names.size();
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>(
257 if (!opt_element_property_values)
259 WARN(
"Could not create PropertyVector for {:s} in Mesh.",
264 opt_element_property_values->resize(
265 mesh->getNumberOfElements());
266 opt_element_property_values->assign(vec_property_values);
273 for (
auto* nod : vec_nodes)
275 (*nod)[2] = (*nod)[1];
280 for (
auto* pt : points)
288 return mesh.release();
338 std::vector<MeshLib::Node*>
const& vec_nodes)
340 const std::size_t no_nodes_per_layer =
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 =
348 std::string line_string;
349 std::stringstream line_stream;
353 for (
unsigned k = 0; k < 2; k++)
356 for (std::size_t i = 0; i < n_lines; i++)
358 std::getline(in, line_string);
359 line_stream.str(line_string);
360 for (
unsigned j = 0; j < 12; j++)
362 if (i * 12 + j >= no_nodes_per_layer)
366 line_stream >> x >> dummy_char;
367 for (std::size_t l = 0; l < n_layers; l++)
369 const std::size_t n = i * 12 + l * no_nodes_per_layer + j;
429 std::vector<MeshLib::Node*>& vec_nodes)
431 const std::size_t no_nodes_per_layer =
434 std::string str_nodeList;
435 std::string line_string;
436 std::stringstream line_stream;
440 std::streamoff pos_prev_line = 0;
443 pos_prev_line = in.tellg();
444 std::getline(in, line_string);
445 boost::trim_right(line_string);
449 if (!in || std::isalpha(line_string[0]))
453 else if (line_string.empty())
457 else if (line_string[0] ==
'\t')
461 else if (columns.size() == 1)
471 if (mode != 3 && !str_nodeList.empty())
475 for (
auto n0 : vec_nodeIDs)
477 const std::size_t n = n0 - 1 + l * no_nodes_per_layer;
478 (*vec_nodes[n])[2] = z;
480 str_nodeList.clear();
496 line_stream.str(line_string);
498 std::getline(line_stream, str_nodeList);
499 boost::trim(str_nodeList);
506 str_nodeList +=
" " + line_string;
511 if (std::isalpha(line_string[0]))
513 in.seekg(pos_prev_line);
638 std::ifstream& in, std::vector<std::vector<std::size_t>>& vec_elementsets)
640 auto compressSpaces = [](std::string
const& str)
642 std::stringstream ss(str);
648 new_str +=
" " + word;
653 std::string line_string;
654 std::string str_idList;
655 std::streampos pos_prev_line = 0;
658 pos_prev_line = in.tellg();
659 std::getline(in, line_string);
666 else if (line_string.empty())
670 else if (std::isalpha(line_string[0]))
674 else if (line_string[0] ==
' ')
678 else if (line_string[0] ==
'\t')
684 ERR(
"Failed during parsing of an ELEMENTALSETS section in a FEFLOW "
689 if (mode != 2 && !str_idList.empty())
702 std::string set_name;
705 if (line_string[0] ==
'"')
707 auto pos = line_string.find_last_of(
'"');
708 set_name = line_string.substr(1, pos - 1);
709 ids = line_string.substr(pos + 1);
713 auto pos = line_string.find_first_of(
' ');
714 set_name = line_string.substr(0, pos);
715 ids = line_string.substr(pos + 1);
717 INFO(
"Found an element group - {:s}", set_name.data());
718 str_idList += compressSpaces(ids);
724 str_idList += compressSpaces(line_string);
728 if (std::isalpha(line_string[0]))
730 in.seekg(pos_prev_line);
735 std::ifstream& in, std::size_t n_elements)
737 std::vector<double> vec_element_values(n_elements);
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;
747 pos_prev_line = in.tellg();
748 std::getline(in, line_string);
749 boost::trim_right(line_string);
750 if (line_string.empty())
758 if ((!in || (line_string[0] !=
' ' && line_string[0] !=
'\t')) &&
763 else if (line_string[0] !=
'\t')
767 else if (line_string[0] ==
'\t')
774 if (mode != 2 && !str_elementList.empty())
778 for (
auto elementID : vec_elementIDs)
780 vec_element_values[elementID - 1] = property_value;
782 str_elementList.clear();
788 in.seekg(pos_prev_line);
793 line_stream.str(line_string);
794 line_stream >> property_value;
795 std::getline(line_stream, str_elementList);
796 boost::trim(str_elementList);
802 boost::trim_if(line_string, boost::is_any_of(
"\t"));
803 str_elementList +=
" " + line_string;
806 return vec_element_values;
812 std::vector<std::string>& vec_element_property_names,
813 std::vector<std::vector<double>>& vec_element_property_values)
815 std::string line_string;
816 std::stringstream line_stream;
818 auto is_header_of_material_property = [](
const std::string& line_string)
820 if (line_string.empty())
824 return static_cast<bool>(isdigit(line_string.at(0)));
827 auto is_end_of_MAT_I_FLOW = [](
const std::string& line_string)
828 {
return (isalpha(line_string.at(0))); };
830 auto get_material_property_name = [](
const std::string& line_string)
832 using Tok = boost::tokenizer<boost::escaped_list_separator<char>>;
834 boost::escaped_list_separator<char>(
'\\',
' ',
'"'));
835 std::vector<std::string> vec_str;
836 for (
auto const& t : tok)
840 vec_str.push_back(t);
844 if (vec_str.size() < 3)
846 return std::string(
"");
851 std::streamoff pos_prev_line = 0;
854 pos_prev_line = in.tellg();
855 std::getline(in, line_string);
856 boost::trim_right(line_string);
857 if (line_string.empty())
861 if (is_end_of_MAT_I_FLOW(line_string))
864 in.seekg(pos_prev_line);
868 if (is_header_of_material_property(line_string))
870 const std::string property_name =
871 get_material_property_name(line_string);
872 if (!property_name.empty())
874 INFO(
"read element property {:s}", property_name);
875 vec_element_property_names.push_back(property_name);
876 vec_element_property_values.push_back(
886 std::vector<GeoLib::Polyline*>
const& lines,
887 std::vector<std::vector<std::size_t>>
const& vec_elementsets,
888 std::vector<MeshLib::Element*>
const& vec_elements,
891 assert(material_ids.
size() == vec_elements.size());
892 if (!vec_elementsets.empty())
894 for (std::size_t matid = 0; matid < vec_elementsets.size(); ++matid)
896 auto& eids = vec_elementsets[matid];
897 for (
auto eid : eids)
899 material_ids[eid - 1] =
904 else if (!lines.empty())
906 for (std::size_t i = 0; i < vec_elements.size(); ++i)
909 std::size_t matId = 0;
910 for (std::size_t j = 0; j < lines.size(); j++)
925 material_ids[i] = matId;
930 const std::size_t no_nodes_per_layer =
932 for (std::size_t i = 0; i < vec_elements.size(); i++)
935 std::size_t e_min_nodeID = std::numeric_limits<std::size_t>::max();
938 e_min_nodeID = std::min(e_min_nodeID, getNodeIndex(*e, j));
940 std::size_t layer_id = e_min_nodeID / no_nodes_per_layer;
941 material_ids[i] = layer_id;