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(), [&]()
85 { return new MeshLib::Node(dummy_coords, count++); });
90 else if (line_string ==
"NODE")
92 assert(!vec_nodes.empty());
126 ERR(
"FEFLOWInterface::readFEFLOWFile(): Unsupported element "
127 "type with the number of node = {:d} and dim = {:d}",
129 std::for_each(vec_nodes.begin(), vec_nodes.end(),
136 for (std::size_t i = 0; i < fem_dim.
n_elements; i++)
138 std::getline(in, line_string);
139 vec_elements.push_back(
140 readElement(fem_dim, eleType, line_string, vec_nodes));
143 else if (line_string ==
"VARNODE")
145 assert(!vec_nodes.empty());
150 if (!std::getline(in, line_string))
152 ERR(
"FEFLOWInterface::readFEFLOWFile(): read element "
154 std::for_each(vec_nodes.begin(), vec_nodes.end(),
161 for (std::size_t i = 0; i < fem_dim.
n_elements; i++)
163 std::getline(in, line_string);
164 vec_elements.push_back(
readElement(line_string, vec_nodes));
169 else if (line_string ==
"COOR")
173 else if (line_string ==
"XYZCOOR")
178 else if (line_string ==
"ELEV_I")
188 else if (line_string ==
"GRAVITY")
190 std::getline(in, line_string);
191 line_stream.str(line_string);
193 line_stream >> vec[0] >> vec[1] >> vec[2];
194 if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
203 else if (line_string ==
"ELEMENTALSETS")
209 else if (line_string ==
"SUPERMESH")
216 else if (line_string ==
"MAT_I_FLOW")
219 vec_element_property_values);
226 std::string project_name(
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>(
233 if (!opt_material_ids)
235 WARN(
"Could not create PropertyVector for MaterialIDs in Mesh.");
239 opt_material_ids->resize(mesh->getNumberOfElements());
240 setMaterialIDs(fem_class, fem_dim, lines, vec_elementsets, vec_elements,
243 if (!vec_element_property_names.empty())
245 for (
unsigned prop_id = 0; prop_id < vec_element_property_names.size();
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>(
256 if (!opt_element_property_values)
258 WARN(
"Could not create PropertyVector for {:s} in Mesh.",
263 opt_element_property_values->resize(
264 mesh->getNumberOfElements());
265 opt_element_property_values->assign(vec_property_values);
272 for (
auto* nod : vec_nodes)
274 (*nod)[2] = (*nod)[1];
279 for (
auto* pt : points)
286 for (
auto* pt : points)
290 for (
auto* line : lines)
294 return mesh.release();
344 std::vector<MeshLib::Node*>
const& vec_nodes)
346 const std::size_t no_nodes_per_layer =
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 =
354 std::string line_string;
355 std::stringstream line_stream;
359 for (
unsigned k = 0; k < 2; k++)
362 for (std::size_t i = 0; i < n_lines; i++)
364 std::getline(in, line_string);
365 line_stream.str(line_string);
366 for (
unsigned j = 0; j < 12; j++)
368 if (i * 12 + j >= no_nodes_per_layer)
372 line_stream >> x >> dummy_char;
373 for (std::size_t l = 0; l < n_layers; l++)
375 const std::size_t n = i * 12 + l * no_nodes_per_layer + j;
435 std::vector<MeshLib::Node*>& vec_nodes)
437 const std::size_t no_nodes_per_layer =
440 std::string str_nodeList;
441 std::string line_string;
442 std::stringstream line_stream;
446 std::streamoff pos_prev_line = 0;
449 pos_prev_line = in.tellg();
450 std::getline(in, line_string);
451 boost::trim_right(line_string);
455 if (!in || std::isalpha(line_string[0]))
459 else if (line_string.empty())
463 else if (line_string[0] ==
'\t')
467 else if (columns.size() == 1)
477 if (mode != 3 && !str_nodeList.empty())
481 for (
auto n0 : vec_nodeIDs)
483 const std::size_t n = n0 - 1 + l * no_nodes_per_layer;
484 (*vec_nodes[n])[2] = z;
486 str_nodeList.clear();
502 line_stream.str(line_string);
504 std::getline(line_stream, str_nodeList);
505 boost::trim(str_nodeList);
512 str_nodeList +=
" " + line_string;
517 if (std::isalpha(line_string[0]))
519 in.seekg(pos_prev_line);
644 std::ifstream& in, std::vector<std::vector<std::size_t>>& vec_elementsets)
646 auto compressSpaces = [](std::string
const& str)
648 std::stringstream ss(str);
654 new_str +=
" " + word;
659 std::string line_string;
660 std::string str_idList;
661 std::streampos pos_prev_line = 0;
664 pos_prev_line = in.tellg();
665 std::getline(in, line_string);
672 else if (line_string.empty())
676 else if (std::isalpha(line_string[0]))
680 else if (line_string[0] ==
' ')
684 else if (line_string[0] ==
'\t')
690 ERR(
"Failed during parsing of an ELEMENTALSETS section in a FEFLOW "
695 if (mode != 2 && !str_idList.empty())
708 std::string set_name;
711 if (line_string[0] ==
'"')
713 auto pos = line_string.find_last_of(
'"');
714 set_name = line_string.substr(1, pos - 1);
715 ids = line_string.substr(pos + 1);
719 auto pos = line_string.find_first_of(
' ');
720 set_name = line_string.substr(0, pos);
721 ids = line_string.substr(pos + 1);
723 INFO(
"Found an element group - {:s}", set_name.data());
724 str_idList += compressSpaces(ids);
730 str_idList += compressSpaces(line_string);
734 if (std::isalpha(line_string[0]))
736 in.seekg(pos_prev_line);
741 std::ifstream& in, std::size_t n_elements)
743 std::vector<double> vec_element_values(n_elements);
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;
753 pos_prev_line = in.tellg();
754 std::getline(in, line_string);
755 boost::trim_right(line_string);
756 if (line_string.empty())
764 if ((!in || (line_string[0] !=
' ' && line_string[0] !=
'\t')) &&
769 else if (line_string[0] !=
'\t')
773 else if (line_string[0] ==
'\t')
780 if (mode != 2 && !str_elementList.empty())
784 for (
auto elementID : vec_elementIDs)
786 vec_element_values[elementID - 1] = property_value;
788 str_elementList.clear();
794 in.seekg(pos_prev_line);
799 line_stream.str(line_string);
800 line_stream >> property_value;
801 std::getline(line_stream, str_elementList);
802 boost::trim(str_elementList);
808 boost::trim_if(line_string, boost::is_any_of(
"\t"));
809 str_elementList +=
" " + line_string;
812 return vec_element_values;
818 std::vector<std::string>& vec_element_property_names,
819 std::vector<std::vector<double>>& vec_element_property_values)
821 std::string line_string;
822 std::stringstream line_stream;
824 auto is_header_of_material_property = [](
const std::string& line_string)
826 if (line_string.empty())
830 return static_cast<bool>(isdigit(line_string.at(0)));
833 auto is_end_of_MAT_I_FLOW = [](
const std::string& line_string)
834 {
return (isalpha(line_string.at(0))); };
836 auto get_material_property_name = [](
const std::string& line_string)
838 using Tok = boost::tokenizer<boost::escaped_list_separator<char>>;
840 boost::escaped_list_separator<char>(
'\\',
' ',
'"'));
841 std::vector<std::string> vec_str;
842 for (
auto const& t : tok)
846 vec_str.push_back(t);
850 if (vec_str.size() < 3)
852 return std::string(
"");
857 std::streamoff pos_prev_line = 0;
860 pos_prev_line = in.tellg();
861 std::getline(in, line_string);
862 boost::trim_right(line_string);
863 if (line_string.empty())
867 if (is_end_of_MAT_I_FLOW(line_string))
870 in.seekg(pos_prev_line);
874 if (is_header_of_material_property(line_string))
876 const std::string property_name =
877 get_material_property_name(line_string);
878 if (!property_name.empty())
880 INFO(
"read element property {:s}", property_name);
881 vec_element_property_names.push_back(property_name);
882 vec_element_property_values.push_back(
892 std::vector<GeoLib::Polyline*>
const& lines,
893 std::vector<std::vector<std::size_t>>
const& vec_elementsets,
894 std::vector<MeshLib::Element*>
const& vec_elements,
897 assert(material_ids.
size() == vec_elements.size());
898 if (!vec_elementsets.empty())
900 for (std::size_t matid = 0; matid < vec_elementsets.size(); ++matid)
902 auto& eids = vec_elementsets[matid];
903 for (
auto eid : eids)
905 material_ids[eid - 1] =
910 else if (!lines.empty())
912 for (std::size_t i = 0; i < vec_elements.size(); ++i)
915 std::size_t matId = 0;
916 for (std::size_t j = 0; j < lines.size(); j++)
931 material_ids[i] = matId;
936 const std::size_t no_nodes_per_layer =
938 for (std::size_t i = 0; i < vec_elements.size(); i++)
941 std::size_t e_min_nodeID = std::numeric_limits<std::size_t>::max();
944 e_min_nodeID = std::min(e_min_nodeID, getNodeIndex(*e, j));
946 std::size_t layer_id = e_min_nodeID / no_nodes_per_layer;
947 material_ids[i] = layer_id;