OGS
FileIO::FEFLOWGeoInterface Class Reference

Detailed Description

Interface to geometric data in FEFLOW files

Definition at line 24 of file FEFLOWGeoInterface.h.

#include <FEFLOWGeoInterface.h>

Static Public Member Functions

static void readFEFLOWFile (const std::string &filename, GeoLib::GEOObjects &geo_objects)
static void readSuperMesh (std::ifstream &in, unsigned dimension, std::vector< GeoLib::Point * > &points, std::vector< GeoLib::Polyline * > &lines)

Static Private Member Functions

static void readPoints (xmlNodePtr nodesEle, const xmlChar *tag, int dim, std::vector< GeoLib::Point * > &points)

Member Function Documentation

◆ readFEFLOWFile()

void FileIO::FEFLOWGeoInterface::readFEFLOWFile ( const std::string & filename,
GeoLib::GEOObjects & geo_objects )
static

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

This function reads geometry data given in Supermesh.

Parameters
filenameFEFLOW file name
geo_objectsGeometric objects where imported geometry data are added

Definition at line 56 of file FEFLOWGeoInterface.cpp.

58{
59 std::ifstream in(filename.c_str());
60 if (!in)
61 {
62 ERR("FEFLOWGeoInterface::readFEFLOWFile(): Could not open file {:s}.",
63 filename);
64 return;
65 }
66
67 unsigned dimension = 0;
68 std::vector<GeoLib::Point*> points;
69 std::vector<GeoLib::Polyline*> lines;
70
71 bool isXZplane = false;
72
73 std::string line_string;
74 std::stringstream line_stream;
75 while (!in.eof())
76 {
77 std::getline(in, line_string);
78 if (line_string.find("CLASS") != std::string::npos)
79 {
80 std::getline(in, line_string);
81 line_stream.str(line_string);
82 unsigned dummy = 0;
83 for (int i = 0; i < 3; i++)
84 {
85 line_stream >> dummy;
86 }
87 line_stream >> dimension;
88 line_stream.clear();
89 }
90 else if (line_string == "GRAVITY")
91 {
92 std::getline(in, line_string);
93 line_stream.str(line_string);
94 double vec[3] = {};
95 line_stream >> vec[0] >> vec[1] >> vec[2];
96 if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
97 {
98 isXZplane = true;
99 }
100 line_stream.clear();
101 }
102 else if (line_string == "SUPERMESH")
103 {
104 readSuperMesh(in, dimension, points, lines);
105 }
106 }
107 in.close();
108
109 if (isXZplane && !points.empty())
110 {
111 for (auto* pt : points)
112 {
113 (*pt)[2] = (*pt)[1];
114 (*pt)[1] = .0;
115 }
116 }
117 std::string project_name(
119 if (!points.empty())
120 {
121 geo_objects.addPointVec(std::move(points), project_name,
123 }
124 if (!lines.empty())
125 {
126 geo_objects.addPolylineVec(std::move(lines), project_name,
128 }
129}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
static void readSuperMesh(std::ifstream &in, unsigned dimension, std::vector< GeoLib::Point * > &points, std::vector< GeoLib::Polyline * > &lines)
void addPolylineVec(std::vector< Polyline * > &&lines, std::string const &name, PolylineVec::NameIdMap &&ply_names)
void addPointVec(std::vector< Point * > &&points, std::string &name, PointVec::NameIdMap &&pnt_id_name_map, double const eps=std::sqrt(std::numeric_limits< double >::epsilon()))
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:30
std::string extractBaseNameWithoutExtension(std::string const &pathname)
constexpr int dimension()
Displacement dimension of a vectorized tensor.

References GeoLib::GEOObjects::addPointVec(), GeoLib::GEOObjects::addPolylineVec(), ERR(), BaseLib::extractBaseNameWithoutExtension(), and readSuperMesh().

Referenced by MainWindow::loadFile().

◆ readPoints()

void FileIO::FEFLOWGeoInterface::readPoints ( xmlNodePtr nodesEle,
const xmlChar * tag,
int dim,
std::vector< GeoLib::Point * > & points )
staticprivate

Definition at line 131 of file FEFLOWGeoInterface.cpp.

135{
136 xmlNodePtr xmlEle = firstChild(nodesEle, tag);
137 if (xmlEle == nullptr)
138 {
139 return;
140 }
141
142 std::istringstream ss(xmlCharsToString(xmlNodeGetContent(xmlEle)));
143 std::string line_str;
144 while (std::getline(ss, line_str))
145 {
146 boost::algorithm::trim_right(line_str);
147 if (line_str.empty())
148 {
149 continue;
150 }
151 std::istringstream line_ss(line_str);
152 std::size_t pt_id = 0;
153 std::array<double, 3> pt_xyz{};
154 line_ss >> pt_id;
155 for (int i = 0; i < dim; ++i)
156 {
157 line_ss >> pt_xyz[i];
158 }
159 points[pt_id - 1] = new GeoLib::Point(pt_xyz, pt_id);
160 }
161}
xmlNodePtr firstChild(xmlNodePtr parent, const xmlChar *name)

Referenced by readSuperMesh().

◆ readSuperMesh()

void FileIO::FEFLOWGeoInterface::readSuperMesh ( std::ifstream & in,
unsigned dimension,
std::vector< GeoLib::Point * > & points,
std::vector< GeoLib::Polyline * > & lines )
static

read points and polylines in Supermesh section

A super mesh is a collection of polygons, lines and points in the 2D plane and will be used for mesh generation and to define the modeling region

Definition at line 163 of file FEFLOWGeoInterface.cpp.

167{
168 // Read XML block
169 std::ostringstream oss;
170 std::string line_string;
171 while (true)
172 {
173 std::getline(in, line_string);
174 BaseLib::trim(line_string);
175 oss << line_string << "\n";
176 if (line_string.find("</supermesh>") != std::string::npos)
177 {
178 break;
179 }
180 }
181 const std::string xml_str = oss.str();
182
183 xmlInitParser();
184 xmlDocPtr doc =
185 xmlReadMemory(xml_str.c_str(), static_cast<int>(xml_str.size()),
186 "supermesh.xml", nullptr, XML_PARSE_NOBLANKS);
187 if (doc == nullptr)
188 {
189 ERR("FEFLOWGeoInterface::readSuperMesh(): Illegal XML format error");
190 xmlCleanupParser();
191 return;
192 }
193
194 xmlNodePtr docElem = xmlDocGetRootElement(doc);
195 if (docElem == nullptr)
196 {
197 ERR("FEFLOWGeoInterface::readSuperMesh(): Error in getting XML root "
198 "element");
199 xmlFreeDoc(doc);
200 xmlCleanupParser();
201 return;
202 }
203
204 static constexpr xmlChar nodes_name[] = "nodes";
205 xmlNodePtr nodesEle = firstChild(docElem, nodes_name);
206 if (nodesEle == nullptr)
207 {
208 ERR("FEFLOWGeoInterface::readSuperMesh(): Error in getting 'nodes' "
209 "element");
210 xmlFreeDoc(doc);
211 xmlCleanupParser();
212 return;
213 }
214
215 static constexpr xmlChar count_name[] = "count";
216 const std::string cnt = xmlCharsToString(xmlGetProp(nodesEle, count_name));
217 const std::size_t n_points = cnt.empty() ? 0u : std::stoul(cnt);
218
219 // Convert to raw pointer vector for readPoints compatibility
220 std::vector<GeoLib::Point*> raw_points(n_points, nullptr);
221
222 static constexpr xmlChar fixed_name[] = "fixed";
223 readPoints(nodesEle, fixed_name, static_cast<int>(dimension), raw_points);
224 static constexpr xmlChar linear_name[] = "linear";
225 readPoints(nodesEle, linear_name, static_cast<int>(dimension), raw_points);
226 static constexpr xmlChar parabolic_name[] = "parabolic";
227 readPoints(nodesEle, parabolic_name, static_cast<int>(dimension),
228 raw_points);
229
230 // Transfer ownership to unique_ptrs
231 std::vector<std::unique_ptr<GeoLib::Point>> temp_points(n_points);
232 for (std::size_t i = 0; i < raw_points.size(); ++i)
233 {
234 temp_points[i].reset(raw_points[i]);
235 }
236
237 static constexpr xmlChar polygons_name[] = "polygons";
238 xmlNodePtr polygonsEle = firstChild(docElem, polygons_name);
239 if (polygonsEle == nullptr)
240 {
241 // unique_ptrs will automatically clean up
242 xmlFreeDoc(doc);
243 xmlCleanupParser();
244 return;
245 }
246
247 for (xmlNodePtr child = polygonsEle->children; child; child = child->next)
248 {
249 static constexpr xmlChar polygon_name[] = "polygon";
250 if (child->type != XML_ELEMENT_NODE ||
251 xmlStrcmp(child->name, polygon_name) != 0)
252 {
253 continue;
254 }
255
256 xmlNodePtr nodes = firstChild(child, nodes_name);
257 if (nodes == nullptr)
258 {
259 continue;
260 }
261
262 const std::string cnt_nodes =
263 xmlCharsToString(xmlGetProp(nodes, count_name));
264 const std::size_t n_pts =
265 cnt_nodes.empty() ? 0u
266 : static_cast<std::size_t>(std::stoul(cnt_nodes));
267 std::istringstream ss(xmlCharsToString(xmlNodeGetContent(nodes)));
268
269 auto line = std::make_unique<GeoLib::Polyline>(raw_points);
270
271 for (std::size_t i = 0; i < n_pts; ++i)
272 {
273 int pt_id = 0;
274 ss >> pt_id;
275 line->addPoint(pt_id - 1);
276 }
277 // close the polygon
278 line->addPoint(line->getPointID(0));
279
280 lines.push_back(line.release());
281 }
282
283 xmlFreeDoc(doc);
284 xmlCleanupParser();
285
286 // Only transfer ownership to output vectors if everything succeeded
287 for (auto& pt : temp_points)
288 {
289 points.push_back(pt.release());
290 }
291}
static void readPoints(xmlNodePtr nodesEle, const xmlChar *tag, int dim, std::vector< GeoLib::Point * > &points)
void trim(std::string &str, char ch)

References ERR(), readPoints(), and BaseLib::trim().

Referenced by readFEFLOWFile(), and FileIO::FEFLOWMeshInterface::readFEFLOWFile().


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