OGS
computeSurfaceNodeIDsInPolygonalRegion.cpp
Go to the documentation of this file.
1
13#include <tclap/CmdLine.h>
14
15#include <algorithm>
16#include <fstream>
17#include <iomanip>
18#include <memory>
19#include <string>
20#include <vector>
21
23#include "BaseLib/Error.h"
24#include "BaseLib/FileTools.h"
25#include "BaseLib/Logging.h"
26#include "BaseLib/MPI.h"
28#include "GeoLib/GEOObjects.h"
29#include "GeoLib/Polygon.h"
30#include "InfoLib/GitInfo.h"
32#include "MeshLib/Mesh.h"
33#include "MeshLib/Node.h"
35
37 std::string const& id_area_fname, std::string const& csv_fname,
38 std::vector<std::pair<std::size_t, double>> const& ids_and_areas,
39 std::vector<MeshLib::Node*> const& mesh_nodes)
40{
41 std::ofstream ids_and_area_out(id_area_fname);
42 if (!ids_and_area_out)
43 {
44 OGS_FATAL("Unable to open the file '{:s}' - aborting.", id_area_fname);
45 }
46 std::ofstream csv_out(csv_fname);
47 if (!csv_out)
48 {
49 OGS_FATAL("Unable to open the file '{:s}' - aborting.", csv_fname);
50 }
51
52 ids_and_area_out << std::setprecision(20);
53 csv_out << std::setprecision(20);
54
55 ids_and_area_out << ids_and_areas[0].first << " "
56 << ids_and_areas[0].second;
57 csv_out << "ID x y z area node_id\n"; // CSV header
58 csv_out << 0 << " " << *mesh_nodes[ids_and_areas[0].first]
59 << ids_and_areas[0].second << " " << ids_and_areas[0].first;
60 for (std::size_t k(1); k < ids_and_areas.size(); k++)
61 {
62 ids_and_area_out << "\n"
63 << ids_and_areas[k].first << " "
64 << ids_and_areas[k].second;
65 csv_out << "\n"
66 << k << " " << *mesh_nodes[ids_and_areas[k].first]
67 << ids_and_areas[k].second << " " << ids_and_areas[k].first;
68 }
69 ids_and_area_out << "\n";
70 csv_out << "\n";
71}
72
73int main(int argc, char* argv[])
74{
75 TCLAP::CmdLine cmd(
76 "Computes ids of mesh nodes that are in polygonal regions and resides "
77 "on the top surface. The polygonal regions have to be given in a gml- "
78 "or gli-file. The found mesh nodes and the associated area are written "
79 "as txt and csv data. The documentation is available at "
80 "https://docs.opengeosys.org/docs/tools/model-preparation/"
81 "computesurfacenodeidsinpolygonalregion.\n\n"
82 "OpenGeoSys-6 software, version " +
84 ".\n"
85 "Copyright (c) 2012-2025, OpenGeoSys Community "
86 "(http://www.opengeosys.org)",
88 TCLAP::ValueArg<std::string> mesh_in(
89 "m", "mesh-input-file",
90 "Input (.vtu). The name of the file containing the input mesh", true,
91 "", "INPUT_FILE");
92 cmd.add(mesh_in);
93 TCLAP::ValueArg<std::string> geo_in(
94 "g", "geo-file",
95 "Input (.gml). The name of the input file containing the polygons",
96 true, "", "INPUT_FILE");
97 cmd.add(geo_in);
98
99 TCLAP::ValueArg<std::string> gmsh_path_arg(
100 "", "gmsh-path", "Input (.msh). The path to the input binary file",
101 false, "", "INPUT_FILE");
102 cmd.add(gmsh_path_arg);
103 auto log_level_arg = BaseLib::makeLogLevelArg();
104 cmd.add(log_level_arg);
105 cmd.parse(argc, argv);
106
107 BaseLib::MPI::Setup mpi_setup(argc, argv);
108 BaseLib::initOGSLogger(log_level_arg.getValue());
109
110 std::unique_ptr<MeshLib::Mesh const> mesh(
111 MeshLib::IO::readMeshFromFile(mesh_in.getValue()));
112 INFO("Mesh read: {:d} nodes, {:d} elements.", mesh->getNumberOfNodes(),
113 mesh->getNumberOfElements());
114
115 GeoLib::GEOObjects geo_objs;
116 FileIO::readGeometryFromFile(geo_in.getValue(), geo_objs,
117 gmsh_path_arg.getValue());
118 auto const geo_name = geo_objs.getGeometryNames()[0];
119 INFO("Geometry '{:s}' read: {:d} points, {:d} polylines.",
120 geo_name,
121 geo_objs.getPointVec(geo_name)->size(),
122 geo_objs.getPolylineVec(geo_name)->size());
123
124 Eigen::Vector3d const dir({0.0, 0.0, -1.0});
125 double angle(90);
126
127 auto computeElementTopSurfaceAreas =
128 [](MeshLib::Mesh const& mesh, Eigen::Vector3d const& d, double angle)
129 {
130 std::unique_ptr<MeshLib::Mesh> surface_mesh(
132 angle));
134 *surface_mesh);
135 };
136
137 std::vector<double> areas(computeElementTopSurfaceAreas(*mesh, dir, angle));
138 std::vector<MeshLib::Node*> all_sfc_nodes(
140 angle));
141
142 std::for_each(all_sfc_nodes.begin(), all_sfc_nodes.end(),
143 [](MeshLib::Node* p) { (*p)[2] = 0.0; });
144
145 std::vector<MeshLib::Node*> const& mesh_nodes(mesh->getNodes());
146 GeoLib::PolylineVec const* ply_vec(geo_objs.getPolylineVecObj(geo_name));
147 auto const& plys(ply_vec->getVector());
148
149 for (std::size_t j(0); j < plys.size(); j++)
150 {
151 if (!plys[j]->isClosed())
152 {
153 continue;
154 }
155 std::string polygon_name;
156 ply_vec->getNameOfElement(plys[j], polygon_name);
157 if (polygon_name.empty())
158 {
159 polygon_name = "Polygon-" + std::to_string(j);
160 }
161 // create Polygon from Polyline
162 GeoLib::Polygon const polygon{*plys[j]};
163 // ids of mesh nodes on surface that are within the given polygon
164 std::vector<std::pair<std::size_t, double>> ids_and_areas;
165 for (std::size_t k(0); k < all_sfc_nodes.size(); k++)
166 {
167 MeshLib::Node const& surface_node(*(all_sfc_nodes[k]));
168 if (polygon.isPntInPolygon(surface_node))
169 {
170 ids_and_areas.emplace_back(surface_node.getID(), areas[k]);
171 }
172 }
173 if (ids_and_areas.empty())
174 {
175 ERR("Polygonal part of surface '{:s}' doesn't contains nodes. No "
176 "output will be generated.",
177 polygon_name);
178 continue;
179 }
180
181 std::string const out_path(BaseLib::extractPath(geo_in.getValue()));
182 std::string id_and_area_fname(out_path + polygon_name);
183 std::string csv_fname(out_path + polygon_name);
184 id_and_area_fname += std::to_string(j) + ".txt";
185 csv_fname += std::to_string(j) + ".csv";
186 INFO(
187 "Polygonal part of surface '{}' contains {} nodes. Writing to "
188 "files '{}' and '{}'.",
189 polygon_name,
190 ids_and_areas.size(),
191 id_and_area_fname,
192 csv_fname);
193 writeToFile(id_and_area_fname, csv_fname, ids_and_areas, mesh_nodes);
194 }
195
196 std::for_each(all_sfc_nodes.begin(), all_sfc_nodes.end(),
197 std::default_delete<MeshLib::Node>());
198
199 return EXIT_SUCCESS;
200}
#define OGS_FATAL(...)
Definition Error.h:26
Filename manipulation routines.
Definition of the GEOObjects class.
Git information.
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:36
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:48
Definition of the MeshSurfaceExtraction class.
Definition of the Mesh class.
Definition of the Node class.
Definition of the Polygon class.
Container class for geometric objects.
Definition GEOObjects.h:57
std::vector< std::string > getGeometryNames() const
Returns the names of all geometry vectors.
const std::vector< Point * > * getPointVec(const std::string &name) const
const PolylineVec * getPolylineVecObj(const std::string &name) const
const std::vector< Polyline * > * getPolylineVec(const std::string &name) const
The class TemplateVec takes a unique name and manages a std::vector of pointers to data elements of t...
bool getNameOfElement(const T *data, std::string &name) const
std::vector< T * > const & getVector() const
std::size_t getID() const
static std::vector< double > getSurfaceAreaForNodes(const MeshLib::Mesh &mesh)
Returns a vector of the areas assigned to each node on a surface mesh.
static MeshLib::Mesh * getMeshSurface(const MeshLib::Mesh &subsfc_mesh, Eigen::Vector3d const &dir, double angle, std::string_view subsfc_node_id_prop_name="", std::string_view subsfc_element_id_prop_name="", std::string_view face_id_prop_name="")
static std::vector< MeshLib::Node * > getSurfaceNodes(const MeshLib::Mesh &mesh, Eigen::Vector3d const &dir, double angle)
Returns the surface nodes of a mesh.
int main(int argc, char *argv[])
void writeToFile(std::string const &id_area_fname, std::string const &csv_fname, std::vector< std::pair< std::size_t, double > > const &ids_and_areas, std::vector< MeshLib::Node * > const &mesh_nodes)
TCLAP::ValueArg< std::string > makeLogLevelArg()
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:64
std::string extractPath(std::string const &pathname)
void readGeometryFromFile(std::string const &fname, GeoLib::GEOObjects &geo_objs, std::string const &gmsh_path)
GITINFOLIB_EXPORT const std::string ogs_version
MeshLib::Mesh * readMeshFromFile(const std::string &file_name, bool const compute_element_neighbors)
Definition of readMeshFromFile function.