OGS
FEFLOWGeoInterface.cpp
Go to the documentation of this file.
1 
9 #include "FEFLOWGeoInterface.h"
10 
11 #include <QDomElement>
12 #include <QString>
13 #include <QtXml/QDomDocument>
14 #include <boost/algorithm/string/trim.hpp>
15 #include <cctype>
16 #include <memory>
17 
18 #include "BaseLib/FileTools.h"
19 #include "BaseLib/Logging.h"
20 #include "BaseLib/StringTools.h"
21 #include "GeoLib/GEOObjects.h"
22 #include "GeoLib/Point.h"
23 #include "GeoLib/Polygon.h"
24 
25 namespace FileIO
26 {
27 void FEFLOWGeoInterface::readFEFLOWFile(const std::string& filename,
28  GeoLib::GEOObjects& geo_objects)
29 {
30  std::ifstream in(filename.c_str());
31  if (!in)
32  {
33  ERR("FEFLOWGeoInterface::readFEFLOWFile(): Could not open file {:s}.",
34  filename);
35  return;
36  }
37 
38  unsigned dimension = 0;
39  std::vector<GeoLib::Point*>* points = nullptr;
40  std::vector<GeoLib::Polyline*>* lines = nullptr;
41 
42  bool isXZplane = false;
43 
44  std::string line_string;
45  std::stringstream line_stream;
46  while (!in.eof())
47  {
48  getline(in, line_string);
49  //....................................................................
50  // CLASS: the version number follows afterward, e.g. CLASS (v.5.313)
51  if (line_string.find("CLASS") != std::string::npos)
52  {
53  getline(in, line_string);
54  line_stream.str(line_string);
55  // problem class, time mode, problem orientation, dimension, ...
56  unsigned dummy = 0;
57  for (int i = 0; i < 3; i++)
58  {
59  line_stream >> dummy;
60  }
61  line_stream >> dimension;
62  line_stream.clear();
63  }
64  //....................................................................
65  // GRAVITY
66  else if (line_string == "GRAVITY")
67  {
68  getline(in, line_string);
69  line_stream.str(line_string);
70  double vec[3] = {};
71  line_stream >> vec[0] >> vec[1] >> vec[2];
72  if (vec[0] == 0.0 && vec[1] == -1.0 && vec[2] == 0.0)
73  {
74  // x-z plane
75  isXZplane = true;
76  }
77  line_stream.clear();
78  }
79  //....................................................................
80  // SUPERMESH
81  else if (line_string == "SUPERMESH")
82  {
83  readSuperMesh(in, dimension, points, lines);
84  }
85  //....................................................................
86  }
87  in.close();
88 
89  std::string project_name(
91  if (points)
92  {
93  geo_objects.addPointVec(
94  std::unique_ptr<std::vector<GeoLib::Point*>>(points), project_name);
95  }
96  if (lines)
97  {
98  geo_objects.addPolylineVec(
99  std::unique_ptr<std::vector<GeoLib::Polyline*>>(lines),
100  project_name);
101  }
102 
103  if (isXZplane && points)
104  {
105  for (auto* pt : *points)
106  {
107  (*pt)[2] = (*pt)[1];
108  (*pt)[1] = .0;
109  }
110  }
111 }
112 
113 void 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 
147 void FEFLOWGeoInterface::readSuperMesh(std::ifstream& in,
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  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  points = new std::vector<GeoLib::Point*>();
179  QDomElement nodesEle = docElem.firstChildElement("nodes");
180  if (nodesEle.isNull())
181  {
182  return;
183  }
184 
185  {
186  const QString str = nodesEle.attribute("count");
187  const long n_points = str.toLong();
188  points->resize(n_points);
189  // fixed
190  readPoints(nodesEle, "fixed", dimension, *points);
191  readPoints(nodesEle, "linear", dimension, *points);
192  readPoints(nodesEle, "parabolic", dimension, *points);
193  }
194 
195  // #polygons
196  lines = new std::vector<GeoLib::Polyline*>();
197  QDomElement polygonsEle = docElem.firstChildElement("polygons");
198  if (polygonsEle.isNull())
199  {
200  return;
201  }
202 
203  {
204  QDomNode child = polygonsEle.firstChild();
205  while (!child.isNull())
206  {
207  if (child.nodeName() != "polygon")
208  {
209  child = child.nextSibling();
210  continue;
211  }
212  QDomElement xmlEle = child.firstChildElement("nodes");
213  if (xmlEle.isNull())
214  {
215  continue;
216  }
217  const QString str = xmlEle.attribute("count");
218  const std::size_t n_points = str.toLong();
219  QString str_ptId_list = xmlEle.text().simplified();
220  {
221  auto* line = new GeoLib::Polyline(*points);
222  lines->push_back(line);
223  std::istringstream ss(str_ptId_list.toStdString());
224  for (std::size_t i = 0; i < n_points; i++)
225  {
226  int pt_id = 0;
227  ss >> pt_id;
228  line->addPoint(pt_id - 1);
229  }
230  line->addPoint(line->getPointID(0));
231  }
232  child = child.nextSibling();
233  }
234  }
235 }
236 
237 } // namespace FileIO
Filename manipulation routines.
Definition of the GEOObjects class.
Definition of the Point class.
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
Definition of the Polygon class.
Definition of string helper functions.
static void readSuperMesh(std::ifstream &in, unsigned dimension, std::vector< GeoLib::Point * > *&points, std::vector< GeoLib::Polyline * > *&lines)
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)
Container class for geometric objects.
Definition: GEOObjects.h:61
void addPointVec(std::unique_ptr< std::vector< Point * >> points, std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> pnt_id_name_map=nullptr, double eps=std::sqrt(std::numeric_limits< double >::epsilon()))
Definition: GEOObjects.cpp:51
void addPolylineVec(std::unique_ptr< std::vector< Polyline * >> lines, const std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> ply_names=nullptr)
Definition: GEOObjects.cpp:150
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition: Polyline.h:51
void trim(std::string &str, char ch)
Definition: StringTools.cpp:58
std::string extractBaseNameWithoutExtension(std::string const &pathname)
Definition: FileTools.cpp:180
TemplateElement< PointRule1 > Point
Definition: Point.h:20