OGS
GMSHAdaptiveMeshDensity.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <list>
7
8#include "BaseLib/Logging.h"
9#include "GeoLib/Point.h"
10#include "GeoLib/Polygon.h"
11#ifndef NDEBUG
12#include "GeoLib/GEOObjects.h"
13#include "GeoLib/Polyline.h"
14#endif
15#include "GeoLib/QuadTree.h"
16#include "MathLib/MathTools.h"
17
18namespace FileIO
19{
20namespace GMSH
21{
23 double station_density,
24 std::size_t max_pnts_per_leaf)
25 : _pnt_density(pnt_density),
26 _station_density(station_density),
27 _max_pnts_per_leaf(max_pnts_per_leaf),
28 _quad_tree(nullptr)
29{
30}
31
36
38 std::vector<GeoLib::Point const*> const& pnts)
39{
40 // *** QuadTree - determining bounding box
41 DBUG(
42 "GMSHAdaptiveMeshDensity::init(): computing axis aligned bounding box "
43 "(2D) for quadtree.");
44
45 GeoLib::Point min(*pnts[0]);
46 GeoLib::Point max(*pnts[0]);
47 std::size_t n_pnts(pnts.size());
48 for (std::size_t k(1); k < n_pnts; k++)
49 {
50 for (std::size_t j(0); j < 2; j++)
51 {
52 if ((*(pnts[k]))[j] < min[j])
53 {
54 min[j] = (*(pnts[k]))[j];
55 }
56 }
57 for (std::size_t j(0); j < 2; j++)
58 {
59 if ((*(pnts[k]))[j] > max[j])
60 {
61 max[j] = (*(pnts[k]))[j];
62 }
63 }
64 }
65 min[2] = 0.0;
66 max[2] = 0.0;
67 DBUG("GMSHAdaptiveMeshDensity::init(): \tok");
68
69 // *** QuadTree - create object
70 DBUG("GMSHAdaptiveMeshDensity::init(): Creating quadtree.");
73 DBUG("GMSHAdaptiveMeshDensity::init(): \tok.");
74
75 // *** QuadTree - insert points
76 addPoints(pnts);
77}
78
80 std::vector<GeoLib::Point const*> const& pnts)
81{
82 // *** QuadTree - insert points
83 const std::size_t n_pnts(pnts.size());
84 DBUG(
85 "GMSHAdaptiveMeshDensity::addPoints(): Inserting {:d} points into "
86 "quadtree.",
87 n_pnts);
88 for (std::size_t k(0); k < n_pnts; k++)
89 {
90 _quad_tree->addPoint(pnts[k]);
91 }
92 DBUG("GMSHAdaptiveMeshDensity::addPoints(): \tok.");
93 _quad_tree->balance();
94}
95
97 GeoLib::Point const* const pnt) const
98{
100 GeoLib::Point ur;
101 _quad_tree->getLeaf(*pnt, ll, ur);
102 return _pnt_density * (ur[0] - ll[0]);
103}
104
106 GeoLib::Point const* const pnt) const
107{
108 GeoLib::Point ll;
109 GeoLib::Point ur;
110 _quad_tree->getLeaf(*pnt, ll, ur);
111 return _station_density * (ur[0] - ll[0]);
112}
113
115 std::vector<GeoLib::Point*>& pnts, std::size_t additional_levels) const
116{
117 // get Steiner points
118 std::size_t max_depth(0);
119 _quad_tree->getMaxDepth(max_depth);
120
121 std::list<GeoLib::QuadTree<GeoLib::Point>*> leaf_list;
122 _quad_tree->getLeafs(leaf_list);
123
124 for (std::list<GeoLib::QuadTree<GeoLib::Point>*>::const_iterator it(
125 leaf_list.begin());
126 it != leaf_list.end();
127 ++it)
128 {
129 if ((*it)->getPoints().empty())
130 {
131 // compute point from square
132 GeoLib::Point ll;
133 GeoLib::Point ur;
134 (*it)->getSquarePoints(ll, ur);
135 if ((*it)->getDepth() + additional_levels > max_depth)
136 {
137 additional_levels = max_depth - (*it)->getDepth();
138 }
139 const std::size_t n_pnts_per_quad_dim = static_cast<std::size_t>(1)
140 << additional_levels;
141 const double delta((ur[0] - ll[0]) / (2 * n_pnts_per_quad_dim));
142 for (std::size_t i(0); i < n_pnts_per_quad_dim; i++)
143 {
144 for (std::size_t j(0); j < n_pnts_per_quad_dim; j++)
145 {
146 pnts.push_back(new GeoLib::Point(
147 ll[0] + (2 * i + 1) * delta,
148 ll[1] + (2 * j + 1) * delta, 0.0, pnts.size()));
149 }
150 }
151 }
152 }
153}
154
155#ifndef NDEBUG
157 GeoLib::GEOObjects& geo_objs) const
158{
159 std::list<GeoLib::QuadTree<GeoLib::Point>*> leaf_list;
160 _quad_tree->getLeafs(leaf_list);
161
162 std::string quad_tree_geo("QuadTree");
163 {
164 std::vector<GeoLib::Point*> points{};
165 for (auto const leaf : leaf_list)
166 {
167 // fetch corner points from leaf
168 GeoLib::Point ll;
169 GeoLib::Point ur;
170 leaf->getSquarePoints(ll, ur);
171 std::size_t const pnt_offset(points.size());
172 points.push_back(new GeoLib::Point(ll, pnt_offset));
173 points.push_back(
174 new GeoLib::Point(ur[0], ll[1], 0.0, pnt_offset + 1));
175 points.push_back(new GeoLib::Point(ur, pnt_offset + 2));
176 points.push_back(
177 new GeoLib::Point(ll[0], ur[1], 0.0, pnt_offset + 3));
178 }
179 geo_objs.addPointVec(std::move(points), quad_tree_geo,
181 }
182 auto& points = geo_objs.getPointVecObj(quad_tree_geo)->getVector();
183
184 std::vector<GeoLib::Polyline*> polylines{};
185 for (std::size_t l = 0; l < leaf_list.size(); ++l)
186 {
187 auto* polyline = new GeoLib::Polyline(points);
188 for (std::size_t p = 0; p < 4; ++p)
189 {
190 polyline->addPoint(4 * l + p);
191 }
192 polyline->closePolyline();
193 polylines.push_back(polyline);
194 }
195 geo_objs.addPolylineVec(std::move(polylines), quad_tree_geo,
197
198 return quad_tree_geo;
199}
200#endif
201} // namespace GMSH
202
203} // end namespace FileIO
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
double getMeshDensityAtPoint(GeoLib::Point const *const pnt) const override
double getMeshDensityAtStation(GeoLib::Point const *const) const override
std::string getQuadTreeGeometry(GeoLib::GEOObjects &geo_objs) const
void getSteinerPoints(std::vector< GeoLib::Point * > &pnts, std::size_t additional_levels=0) const
void initialize(std::vector< GeoLib::Point const * > const &pnts) override
GMSHAdaptiveMeshDensity(double pnt_density, double station_density, std::size_t max_pnts_per_leaf)
void addPoints(std::vector< GeoLib::Point const * > const &pnts)
GeoLib::QuadTree< GeoLib::Point > * _quad_tree
Container class for geometric objects.
Definition GEOObjects.h:46
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()))
const PointVec * getPointVecObj(const std::string &name) const
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:29
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:30
std::vector< T * > const & getVector() const
Definition TemplateVec.h:94