OGS
FEFLOWGeoInterface.cpp
Go to the documentation of this file.
1
10#include "FEFLOWGeoInterface.h"
11
12#include <QDomElement>
13#include <QString>
14#include <QtXml/QDomDocument>
15#include <boost/algorithm/string/trim.hpp>
16#include <cctype>
17#include <fstream>
18#include <memory>
19
20#include "BaseLib/FileTools.h"
21#include "BaseLib/Logging.h"
22#include "BaseLib/StringTools.h"
23#include "GeoLib/GEOObjects.h"
24#include "GeoLib/Point.h"
25#include "GeoLib/Polygon.h"
26
27namespace FileIO
28{
29void FEFLOWGeoInterface::readFEFLOWFile(const std::string& filename,
30 GeoLib::GEOObjects& geo_objects)
31{
32 std::ifstream in(filename.c_str());
33 if (!in)
34 {
35 ERR("FEFLOWGeoInterface::readFEFLOWFile(): Could not open file {:s}.",
36 filename);
37 return;
38 }
39
40 unsigned dimension = 0;
41 std::vector<GeoLib::Point*> points;
42 std::vector<GeoLib::Polyline*> lines;
43
44 bool isXZplane = false;
45
46 std::string line_string;
47 std::stringstream line_stream;
48 while (!in.eof())
49 {
50 std::getline(in, line_string);
51 //....................................................................
52 // CLASS: the version number follows afterward, e.g. CLASS (v.5.313)
53 if (line_string.find("CLASS") != std::string::npos)
54 {
55 std::getline(in, line_string);
56 line_stream.str(line_string);
57 // problem class, time mode, problem orientation, dimension, ...
58 unsigned dummy = 0;
59 for (int i = 0; i < 3; i++)
60 {
61 line_stream >> dummy;
62 }
63 line_stream >> dimension;
64 line_stream.clear();
65 }
66 //....................................................................
67 // GRAVITY
68 else if (line_string == "GRAVITY")
69 {
70 std::getline(in, line_string);
71 line_stream.str(line_string);
72 double vec[3] = {};
73 line_stream >> vec[0] >> vec[1] >> vec[2];
74 if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
75 {
76 // x-z plane
77 isXZplane = true;
78 }
79 line_stream.clear();
80 }
81 //....................................................................
82 // SUPERMESH
83 else if (line_string == "SUPERMESH")
84 {
85 readSuperMesh(in, dimension, points, lines);
86 }
87 //....................................................................
88 }
89 in.close();
90
91 if (isXZplane && !points.empty())
92 {
93 for (auto* pt : points)
94 {
95 (*pt)[2] = (*pt)[1];
96 (*pt)[1] = .0;
97 }
98 }
99 std::string project_name(
101 if (!points.empty())
102 {
103 geo_objects.addPointVec(std::move(points), project_name,
105 }
106 if (!lines.empty())
107 {
108 geo_objects.addPolylineVec(std::move(lines), project_name,
110 }
111}
112
113void FEFLOWGeoInterface::readPoints(QDomElement& nodesEle,
114 const std::string& tag,
115 int dim,
116 std::vector<GeoLib::Point*>& points)
117{
118 QDomElement xmlEle =
119 nodesEle.firstChildElement(QString::fromStdString(tag));
120 if (xmlEle.isNull())
121 {
122 return;
123 }
124 QString str_pt_list1 = xmlEle.text();
125 std::istringstream ss(str_pt_list1.toStdString());
126 std::string line_str;
127 while (!ss.eof())
128 {
129 std::getline(ss, line_str);
130 boost::trim_right(line_str);
131 if (line_str.empty())
132 {
133 continue;
134 }
135 std::istringstream line_ss(line_str);
136 std::size_t pt_id = 0;
137 std::array<double, 3> pt_xyz;
138 line_ss >> pt_id;
139 for (int i = 0; i < dim; i++)
140 {
141 line_ss >> pt_xyz[i];
142 }
143 points[pt_id - 1] = new GeoLib::Point(pt_xyz, pt_id);
144 }
145}
146
148 unsigned dimension,
149 std::vector<GeoLib::Point*>& points,
150 std::vector<GeoLib::Polyline*>& lines)
151{
152 // get XML strings
153 std::ostringstream oss;
154 std::string line_string;
155 while (true)
156 {
157 std::getline(in, line_string);
158 BaseLib::trim(line_string);
159 oss << line_string << "\n";
160 if (line_string.find("</supermesh>") != std::string::npos)
161 {
162 break;
163 }
164 }
165 const QString strXML(oss.str().c_str());
166
167 // convert string to XML
168 QDomDocument doc;
169 if (!doc.setContent(strXML))
170 {
171 ERR("FEFLOWGeoInterface::readSuperMesh(): Illegal XML format error");
172 return;
173 }
174
175 // get geometry data from XML
176 QDomElement docElem = doc.documentElement(); // #supermesh
177 // #nodes
178 QDomElement nodesEle = docElem.firstChildElement("nodes");
179 if (nodesEle.isNull())
180 {
181 return;
182 }
183
184 {
185 const QString str = nodesEle.attribute("count");
186 const long n_points = str.toLong();
187 points.resize(n_points);
188 // fixed
189 readPoints(nodesEle, "fixed", dimension, points);
190 readPoints(nodesEle, "linear", dimension, points);
191 readPoints(nodesEle, "parabolic", dimension, points);
192 }
193
194 // #polygons
195 QDomElement polygonsEle = docElem.firstChildElement("polygons");
196 if (polygonsEle.isNull())
197 {
198 return;
199 }
200
201 {
202 QDomNode child = polygonsEle.firstChild();
203 while (!child.isNull())
204 {
205 if (child.nodeName() != "polygon")
206 {
207 child = child.nextSibling();
208 continue;
209 }
210 QDomElement xmlEle = child.firstChildElement("nodes");
211 if (xmlEle.isNull())
212 {
213 continue;
214 }
215 const QString str = xmlEle.attribute("count");
216 const std::size_t n_points = str.toLong();
217 QString str_ptId_list = xmlEle.text().simplified();
218 {
219 auto* line = new GeoLib::Polyline(points);
220 lines.push_back(line);
221 std::istringstream ss(str_ptId_list.toStdString());
222 for (std::size_t i = 0; i < n_points; i++)
223 {
224 int pt_id = 0;
225 ss >> pt_id;
226 line->addPoint(pt_id - 1);
227 }
228 line->addPoint(line->getPointID(0));
229 }
230 child = child.nextSibling();
231 }
232 }
233}
234
235} // namespace FileIO
Filename manipulation routines.
Definition of the GEOObjects class.
Definition of the Point class.
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
Definition of the Polygon class.
Definition of string helper functions.
static void readPoints(QDomElement &nodesEle, const std::string &tag, int dim, std::vector< GeoLib::Point * > &points)
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)
Container class for geometric objects.
Definition GEOObjects.h:57
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()))
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:40
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:41
void trim(std::string &str, char ch)
std::string extractBaseNameWithoutExtension(std::string const &pathname)