OGS
IntegrateBoreholesIntoMesh.cpp
Go to the documentation of this file.
1 
10 #include <iterator>
11 #include <limits>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 // ThirdParty
17 #include <tclap/CmdLine.h>
18 
19 #include "GeoLib/GEOObjects.h"
21 #include "InfoLib/GitInfo.h"
23 #include "MeshLib/Elements/Line.h"
26 #include "MeshLib/Mesh.h"
28 #include "MeshLib/Node.h"
29 
30 std::vector<std::size_t> getNodes(
31  GeoLib::Point const& pnt, std::vector<MeshLib::Node*> const& nodes,
32  MeshLib::PropertyVector<int> const& mat_ids,
33  std::pair<int, int> const& mat_limits,
34  std::pair<double, double> const& elevation_limits,
35  MeshLib::Mesh const& mesh)
36 {
37  std::vector<std::size_t> pnt_nodes;
38  for (auto node : nodes)
39  {
40  double const eps = std::numeric_limits<double>::epsilon();
41  if (std::abs((*node)[0] - pnt[0]) < eps &&
42  std::abs((*node)[1] - pnt[1]) < eps)
43  {
44  auto const& elems = mesh.getElementsConnectedToNode(*node);
45  for (auto e : elems)
46  {
47  if (mat_ids[e->getID()] >= mat_limits.first &&
48  mat_ids[e->getID()] <= mat_limits.second &&
49  (*node)[2] >= elevation_limits.first &&
50  (*node)[2] <= elevation_limits.second)
51  {
52  pnt_nodes.push_back(node->getID());
53  break;
54  }
55  }
56  }
57  }
58  if (pnt_nodes.size() < 2)
59  {
60  WARN("No nodes found for point {:d}...", pnt.getID());
61  }
62  else
63  {
64  // sort found nodes from top to bottom (required for BHE simulations)
65  std::sort(pnt_nodes.begin(), pnt_nodes.end(),
66  [nodes](std::size_t a, std::size_t b)
67  { return (*nodes[a])[2] > (*nodes[b])[2]; });
68  }
69  return pnt_nodes;
70 }
71 
72 int main(int argc, char* argv[])
73 {
74  TCLAP::CmdLine cmd(
75  "Integrates line elements representing boreholes into a pre-existing "
76  "3D mesh. Corresponding nodes matching the (x,y)-coordinates given in "
77  "the gml-file are found in the mesh and connected from top to bottom "
78  "via line elements. Each borehole (i.e. all points at a given "
79  "(x,y)-location but at different depths) is assigned a unique material "
80  "ID. Vertical limits of boreholes can be specified via Material IDs "
81  "and/or elevation. Point not matching any mesh nodes or located outside"
82  " the mesh are ignored.\n\n"
83  "OpenGeoSys-6 software, version " +
85  ".\n"
86  "Copyright (c) 2012-2021, OpenGeoSys Community "
87  "(http://www.opengeosys.org)",
89 
90  double const dmax = std::numeric_limits<double>::max();
91  TCLAP::ValueArg<double> max_elevation_arg(
92  "", "max-elevation", "Maximum elevation for an integrated borehole",
93  false, 0, "a number");
94  cmd.add(max_elevation_arg);
95  TCLAP::ValueArg<double> min_elevation_arg(
96  "", "min-elevation", "Minimum elevation for an integrated borehole",
97  false, 0, "a number");
98  cmd.add(min_elevation_arg);
99  TCLAP::ValueArg<int> max_id_arg(
100  "", "max-id", "Maximum MaterialID for an integrated borehole", false,
101  -1, "a number");
102  cmd.add(max_id_arg);
103  TCLAP::ValueArg<int> min_id_arg(
104  "", "min-id", "Minimum MaterialID for an integrated borehole", false,
105  -1, "a number");
106  cmd.add(min_id_arg);
107  TCLAP::ValueArg<std::string> geo_arg("g", "geo",
108  "Name of the geometry file (*.gml)",
109  true, "", "geometry file name");
110  cmd.add(geo_arg);
111  TCLAP::ValueArg<std::string> output_arg("o", "output",
112  "Name of the output mesh (*.vtu)",
113  true, "", "output file name");
114  cmd.add(output_arg);
115  TCLAP::ValueArg<std::string> input_arg("i", "input",
116  "Name of the input mesh (*.vtu)",
117  true, "", "input file name");
118  cmd.add(input_arg);
119  cmd.parse(argc, argv);
120 
121  std::pair<int, int> mat_limits(0, std::numeric_limits<int>::max());
122  std::pair<double, double> elevation_limits(
123  std::numeric_limits<double>::lowest(), dmax);
124 
125  if (min_id_arg.isSet() != max_id_arg.isSet())
126  {
127  ERR("If minimum MaterialID is set, maximum ID must be set, too (and "
128  "vice versa).");
129  return EXIT_FAILURE;
130  }
131  if (min_id_arg.isSet() && max_id_arg.isSet())
132  {
133  mat_limits =
134  std::make_pair(min_id_arg.getValue(), max_id_arg.getValue());
135  }
136  if (mat_limits.first > mat_limits.second)
137  {
138  std::swap(mat_limits.first, mat_limits.second);
139  }
140  if (min_id_arg.isSet() && (mat_limits.first < 0 || mat_limits.second < 0))
141  {
142  ERR("Specified MaterialIDs must have non-negative values.");
143  return EXIT_FAILURE;
144  }
145  if (min_elevation_arg.isSet() != max_elevation_arg.isSet())
146  {
147  ERR("If minimum elevation is set, maximum elevation must be set, too "
148  "(and vice versa).");
149  return EXIT_FAILURE;
150  }
151  if (min_elevation_arg.isSet() && max_elevation_arg.isSet())
152  {
153  elevation_limits = std::make_pair(min_elevation_arg.getValue(),
154  max_elevation_arg.getValue());
155  }
156  if (elevation_limits.first > elevation_limits.second)
157  {
158  std::swap(elevation_limits.first, elevation_limits.second);
159  }
160 
161  std::string const& mesh_name = input_arg.getValue();
162  std::string const& output_name = output_arg.getValue();
163  std::string const& geo_name = geo_arg.getValue();
164 
165  GeoLib::GEOObjects geo;
167  if (!xml_io.readFile(geo_name))
168  {
169  ERR("Failed to read geometry file `{:s}'.", geo_name);
170  return EXIT_FAILURE;
171  }
172  std::vector<GeoLib::Point*> const& points =
173  *geo.getPointVec(geo.getGeometryNames()[0]);
174 
175  std::unique_ptr<MeshLib::Mesh> const mesh(
176  MeshLib::IO::readMeshFromFile(mesh_name));
177  if (mesh == nullptr)
178  {
179  ERR("Failed to read input mesh file `{:s}'.", mesh_name);
180  return EXIT_FAILURE;
181  }
182  if (mesh->getDimension() != 3)
183  {
184  ERR("Method can only be applied to 3D meshes.");
185  return EXIT_FAILURE;
186  }
187 
188  auto const& nodes = mesh->getNodes();
189  auto const& mat_ids = MeshLib::materialIDs(*mesh);
190  if (mat_ids == nullptr)
191  {
192  ERR("Mesh is required to have MaterialIDs");
193  return EXIT_FAILURE;
194  }
195 
196  auto const& elems = mesh->getElements();
197  MeshLib::Properties props;
198  auto new_mat_ids = props.createNewPropertyVector<int>(
199  "MaterialIDs", MeshLib::MeshItemType::Cell);
200  std::copy(mat_ids->cbegin(), mat_ids->cend(),
201  std::back_inserter(*new_mat_ids));
202  int const max_id = *std::max_element(mat_ids->begin(), mat_ids->end());
203  std::vector<MeshLib::Node*> new_nodes = MeshLib::copyNodeVector(nodes);
204  std::size_t const n_points = points.size();
205  std::vector<MeshLib::Element*> new_elems =
206  MeshLib::copyElementVector(elems, new_nodes);
207 
208  for (std::size_t i = 0; i < n_points; ++i)
209  {
210  std::vector<std::size_t> const& line_nodes = getNodes(
211  *points[i], nodes, *mat_ids, mat_limits, elevation_limits, *mesh);
212  std::size_t const n_line_nodes = line_nodes.size();
213  if (n_line_nodes < 2)
214  {
215  continue;
216  }
217  for (std::size_t j = 0; j < n_line_nodes - 1; ++j)
218  {
219  new_elems.push_back(new MeshLib::Line(
220  {new_nodes[line_nodes[j]], new_nodes[line_nodes[j + 1]]},
221  elems.size()));
222  new_mat_ids->push_back(max_id + i + 1);
223  }
224  }
225 
226  MeshLib::Mesh const result("result", new_nodes, new_elems, props);
227  MeshLib::IO::VtuInterface vtu(&result);
228  vtu.writeToFile(output_name);
229  return EXIT_SUCCESS;
230 }
Definition of the BoostXmlGmlInterface class.
Definition of Duplicate functions.
Definition of the Element class.
Definition of the GEOObjects class.
Git information.
int main(int argc, char *argv[])
std::vector< std::size_t > getNodes(GeoLib::Point const &pnt, std::vector< MeshLib::Node * > const &nodes, MeshLib::PropertyVector< int > const &mat_ids, std::pair< int, int > const &mat_limits, std::pair< double, double > const &elevation_limits, MeshLib::Mesh const &mesh)
Definition of the Line class.
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:37
Definition of the Mesh class.
Definition of the Node class.
Implementation of the VtuInterface class.
Container class for geometric objects.
Definition: GEOObjects.h:61
std::vector< std::string > getGeometryNames() const
Returns the names of all geometry vectors.
Definition: GEOObjects.cpp:401
const std::vector< Point * > * getPointVec(const std::string &name) const
Definition: GEOObjects.cpp:71
bool readFile(const std::string &fname) override
Reads an xml-file containing OGS geometry.
std::size_t getID() const
Definition: Point3dWithID.h:62
Reads and writes VtkXMLUnstructuredGrid-files (vtu) to and from OGS data structures....
Definition: VtuInterface.h:38
bool writeToFile(std::filesystem::path const &file_path)
std::vector< Element const * > const & getElementsConnectedToNode(std::size_t node_id) const
Definition: Mesh.cpp:232
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
Definition: Properties.h:36
PropertyVector< T > * createNewPropertyVector(std::string const &name, MeshItemType mesh_item_type, std::size_t n_components=1)
GITINFOLIB_EXPORT const std::string ogs_version
void copy(PETScVector const &x, PETScVector &y)
Definition: LinAlg.cpp:37
MeshLib::Mesh * readMeshFromFile(const std::string &file_name)
std::vector< Node * > copyNodeVector(const std::vector< Node * > &nodes)
Creates a deep copy of a Node vector.
PropertyVector< int > const * materialIDs(Mesh const &mesh)
Definition: Mesh.cpp:258
std::vector< Element * > copyElementVector(std::vector< Element * > const &elements, std::vector< Node * > const &new_nodes, std::vector< std::size_t > const *const node_id_map)
Definition of readMeshFromFile function.