OGS
MeshLib::MeshElementGrid Class Referencefinal

Detailed Description

MeshElementGrid implements a grid data structure supporting search operations and covers a given mesh. It consists of grid cells that are all of the same size. Grid cells contain pointers to intersecting mesh elements.

Attention
The user has to ensure the validity of the pointers while the MeshElementGrid instance lives.

Definition at line 32 of file MeshElementGrid.h.

#include <MeshElementGrid.h>

Collaboration diagram for MeshLib::MeshElementGrid:
[legend]

Public Member Functions

 MeshElementGrid (MeshLib::Mesh const &mesh)
 
template<typename POINT >
std::vector< MeshLib::Element const * > getElementsInVolume (POINT const &min, POINT const &max) const
 
Eigen::Vector3d const & getMinPoint () const
 
Eigen::Vector3d const & getMaxPoint () const
 

Private Member Functions

void sortElementsInGridCells (MeshLib::Mesh const &mesh)
 
bool sortElementInGridCells (MeshLib::Element const &element)
 
std::pair< bool, std::array< std::size_t, 3 > > getGridCellCoordinates (MathLib::Point3d const &p) const
 

Private Attributes

GeoLib::AABB _aabb
 
std::array< double, 3 > _step_sizes {}
 
std::array< double, 3 > _inverse_step_sizes {}
 
std::array< std::size_t, 3 > _n_steps
 
std::vector< std::vector< MeshLib::Element const * > > _elements_in_grid_box
 

Constructor & Destructor Documentation

◆ MeshElementGrid()

MeshLib::MeshElementGrid::MeshElementGrid ( MeshLib::Mesh const & mesh)
explicit

Constructs a grid. Grid cells contains intersecting mesh elements.

Parameters
meshthe MeshLib::Mesh instance the grid will be constructed from

Definition at line 24 of file MeshElementGrid.cpp.

25 : _aabb{mesh.getNodes().cbegin(), mesh.getNodes().cend()},
26 _n_steps({{1, 1, 1}})
27{
28 auto getDimensions = [](auto const& min, auto const& max)
29 {
30 std::bitset<3> dim; // all bits are set to zero.
31 for (std::size_t k(0); k < 3; ++k)
32 {
33 double const tolerance(
34 std::nexttoward(max[k], std::numeric_limits<double>::max()) -
35 max[k]);
36 if (std::abs(max[k] - min[k]) > tolerance)
37 {
38 dim[k] = true;
39 }
40 }
41 return dim;
42 };
43
44 auto const [min_pnt, max_pnt] = _aabb.getMinMaxPoints();
45 auto const dim = getDimensions(min_pnt, max_pnt);
46
47 std::array<double, 3> const delta{{max_pnt[0] - min_pnt[0],
48 max_pnt[1] - min_pnt[1],
49 max_pnt[2] - min_pnt[2]}};
50
51 const std::size_t n_eles(mesh.getNumberOfElements());
52 const std::size_t n_eles_per_cell(100);
53
54 // *** condition: n_eles / n_cells < n_eles_per_cell
55 // where n_cells = _n_steps[0] * _n_steps[1] * _n_steps[2]
56 // *** with _n_steps[0] =
57 // ceil(pow(n_eles*delta[0]*delta[0]/(n_eles_per_cell*delta[1]*delta[2]),
58 // 1/3.)));
59 // _n_steps[1] = _n_steps[0] * delta[1]/delta[0],
60 // _n_steps[2] = _n_steps[0] * delta[2]/delta[0]
61 auto sc_ceil = [](double v)
62 { return static_cast<std::size_t>(std::ceil(v)); };
63
64 switch (dim.count())
65 {
66 case 3: // 3d case
67 _n_steps[0] =
68 sc_ceil(std::cbrt(n_eles * delta[0] * delta[0] /
69 (n_eles_per_cell * delta[1] * delta[2])));
70 _n_steps[1] =
71 sc_ceil(_n_steps[0] * std::min(delta[1] / delta[0], 100.0));
72 _n_steps[2] =
73 sc_ceil(_n_steps[0] * std::min(delta[2] / delta[0], 100.0));
74 break;
75 case 2: // 2d cases
76 if (dim[0] && dim[2])
77 { // 2d case: xz plane, y = const
78 _n_steps[0] = sc_ceil(std::sqrt(n_eles * delta[0] /
79 (n_eles_per_cell * delta[2])));
80 _n_steps[2] = sc_ceil(_n_steps[0] * delta[2] / delta[0]);
81 }
82 else if (dim[0] && dim[1])
83 { // 2d case: xy plane, z = const
84 _n_steps[0] = sc_ceil(std::sqrt(n_eles * delta[0] /
85 (n_eles_per_cell * delta[1])));
86 _n_steps[1] = sc_ceil(_n_steps[0] * delta[1] / delta[0]);
87 }
88 else if (dim[1] && dim[2])
89 { // 2d case: yz plane, x = const
90 _n_steps[1] = sc_ceil(std::sqrt(n_eles * delta[1] /
91 (n_eles_per_cell * delta[2])));
92 _n_steps[2] =
93 sc_ceil(n_eles * delta[2] / (n_eles_per_cell * delta[1]));
94 }
95 break;
96 case 1: // 1d cases
97 for (std::size_t k(0); k < 3; ++k)
98 {
99 if (dim[k])
100 {
101 _n_steps[k] =
102 sc_ceil(static_cast<double>(n_eles) / n_eles_per_cell);
103 }
104 }
105 }
106
107 // some frequently used expressions to fill the vector of elements per grid
108 // cell
109 for (std::size_t k(0); k < 3; k++)
110 {
111 _step_sizes[k] = delta[k] / _n_steps[k];
112 _inverse_step_sizes[k] = 1.0 / _step_sizes[k];
113 }
114
115 _elements_in_grid_box.resize(_n_steps[0] * _n_steps[1] * _n_steps[2]);
117}
std::pair< std::size_t, std::size_t > getDimensions(std::string const &line)
Returns raster dimensions from the "Zone"-description.
MinMaxPoints getMinMaxPoints() const
Definition AABB.h:174
void sortElementsInGridCells(MeshLib::Mesh const &mesh)
std::vector< std::vector< MeshLib::Element const * > > _elements_in_grid_box
std::array< double, 3 > _inverse_step_sizes
std::array< std::size_t, 3 > _n_steps
std::array< double, 3 > _step_sizes

Member Function Documentation

◆ getElementsInVolume()

template<typename POINT >
std::vector< MeshLib::Element const * > MeshLib::MeshElementGrid::getElementsInVolume ( POINT const & min,
POINT const & max ) const
inline

Fill and return a vector containing elements of all grid cells that have a non-empty intersection with the box that is defined by min and max.

Parameters
minmin point of the box
maxmax point of the box
Returns
a (possible empty) vector of elements

Definition at line 44 of file MeshElementGrid.h.

46 {
47 auto const min_coords(getGridCellCoordinates(min));
48 auto const max_coords(getGridCellCoordinates(max));
49
50 std::vector<MeshLib::Element const*> elements_vec;
51
52 const std::size_t n_plane(_n_steps[0]*_n_steps[1]);
53 for (std::size_t i(min_coords.second[0]); i<=max_coords.second[0]; i++) {
54 for (std::size_t j(min_coords.second[1]); j<=max_coords.second[1]; j++) {
55 for (std::size_t k(min_coords.second[2]); k<=max_coords.second[2]; k++) {
56 std::size_t idx(i+j*_n_steps[0]+k*n_plane);
57 elements_vec.insert(end(elements_vec),
58 begin(_elements_in_grid_box[idx]),
59 end(_elements_in_grid_box[idx]));
60 }
61 }
62 }
63 return elements_vec;
64 }
std::pair< bool, std::array< std::size_t, 3 > > getGridCellCoordinates(MathLib::Point3d const &p) const

References _elements_in_grid_box, _n_steps, and getGridCellCoordinates().

Referenced by MeshGeoToolsLib::getCandidateElementsForLineSegmentIntersection(), getProjectedElement(), and main().

◆ getGridCellCoordinates()

std::pair< bool, std::array< std::size_t, 3 > > MeshLib::MeshElementGrid::getGridCellCoordinates ( MathLib::Point3d const & p) const
private

Computes the grid cell coordinates for given point. The first element of the returned pair (bool) is true if the point is within the grid, else false.

Definition at line 208 of file MeshElementGrid.cpp.

209{
210 bool valid(true);
211 std::array<std::size_t, 3> coords{};
212
213 for (std::size_t k(0); k < 3; ++k)
214 {
215 const double d(p[k] - _aabb.getMinPoint()[k]);
216 if (d < 0.0)
217 {
218 valid = false;
219 coords[k] = 0;
220 }
221 else if (_aabb.getMaxPoint()[k] <= p[k])
222 {
223 valid = false;
224 coords[k] = _n_steps[k] - 1;
225 }
226 else
227 {
228 coords[k] = static_cast<std::size_t>(d * _inverse_step_sizes[k]);
229 }
230 }
231
232 return std::make_pair(valid, coords);
233}
Eigen::Vector3d const & getMaxPoint() const
Definition AABB.h:187
Eigen::Vector3d const & getMinPoint() const
Definition AABB.h:180
constexpr ranges::views::view_closure coords
Definition Mesh.h:232

References _aabb, _inverse_step_sizes, _n_steps, GeoLib::AABB::getMaxPoint(), and GeoLib::AABB::getMinPoint().

Referenced by getElementsInVolume(), and sortElementInGridCells().

◆ getMaxPoint()

Eigen::Vector3d const & MeshLib::MeshElementGrid::getMaxPoint ( ) const

Returns the max point of the internal AABB. The method is a wrapper for AABB::getMaxPoint().

Definition at line 124 of file MeshElementGrid.cpp.

125{
126 return _aabb.getMaxPoint();
127}

References _aabb, and GeoLib::AABB::getMaxPoint().

Referenced by MeshGeoToolsLib::getCandidateElementsForLineSegmentIntersection().

◆ getMinPoint()

Eigen::Vector3d const & MeshLib::MeshElementGrid::getMinPoint ( ) const

Returns the min point of the internal AABB. The method is a wrapper for GeoLib::AABB::getMinPoint().

Definition at line 119 of file MeshElementGrid.cpp.

120{
121 return _aabb.getMinPoint();
122}

References _aabb, and GeoLib::AABB::getMinPoint().

Referenced by MeshGeoToolsLib::getCandidateElementsForLineSegmentIntersection().

◆ sortElementInGridCells()

bool MeshLib::MeshElementGrid::sortElementInGridCells ( MeshLib::Element const & element)
private

Definition at line 141 of file MeshElementGrid.cpp.

142{
143 std::array<std::size_t, 3> min{};
144 std::array<std::size_t, 3> max{};
145 std::pair<bool, std::array<std::size_t, 3>> c(getGridCellCoordinates(
146 *(static_cast<MathLib::Point3d const*>(element.getNode(0)))));
147 if (c.first)
148 {
149 min = c.second;
150 max = min;
151 }
152 else
153 {
154 return false;
155 }
156
157 for (std::size_t k(1); k < element.getNumberOfNodes(); ++k)
158 {
159 // compute coordinates of the grid for each node of the element
161 *(static_cast<MathLib::Point3d const*>(element.getNode(k))));
162 if (!c.first)
163 {
164 return false;
165 }
166
167 for (std::size_t j(0); j < 3; ++j)
168 {
169 if (min[j] > c.second[j])
170 {
171 min[j] = c.second[j];
172 }
173 if (max[j] < c.second[j])
174 {
175 max[j] = c.second[j];
176 }
177 }
178 }
179
180 const std::size_t n_plane(_n_steps[0] * _n_steps[1]);
181
182 // If a node of an element is almost equal to the upper right point of the
183 // AABB the grid cell coordinates computed by getGridCellCoordintes() could
184 // be to large (due to numerical errors). The following lines ensure that
185 // the grid cell coordinates are in the valid range.
186 for (std::size_t k(0); k < 3; ++k)
187 {
188 max[k] = std::min(_n_steps[k] - 1, max[k]);
189 }
190
191 // insert the element into the grid cells
192 for (std::size_t i(min[0]); i <= max[0]; i++)
193 {
194 for (std::size_t j(min[1]); j <= max[1]; j++)
195 {
196 for (std::size_t k(min[2]); k <= max[2]; k++)
197 {
198 _elements_in_grid_box[i + j * _n_steps[0] + k * n_plane]
199 .push_back(&element);
200 }
201 }
202 }
203
204 return true;
205}

References _elements_in_grid_box, _n_steps, getGridCellCoordinates(), MeshLib::Element::getNode(), and MeshLib::Element::getNumberOfNodes().

Referenced by sortElementsInGridCells().

◆ sortElementsInGridCells()

void MeshLib::MeshElementGrid::sortElementsInGridCells ( MeshLib::Mesh const & mesh)
private

Definition at line 129 of file MeshElementGrid.cpp.

130{
131 for (auto const element : mesh.getElements())
132 {
133 if (!sortElementInGridCells(*element))
134 {
135 OGS_FATAL("Sorting element (id={:d}) into mesh element grid.",
136 element->getID());
137 }
138 }
139}
#define OGS_FATAL(...)
Definition Error.h:26
bool sortElementInGridCells(MeshLib::Element const &element)

References MeshLib::Mesh::getElements(), OGS_FATAL, and sortElementInGridCells().

Member Data Documentation

◆ _aabb

GeoLib::AABB MeshLib::MeshElementGrid::_aabb
private

Definition at line 77 of file MeshElementGrid.h.

Referenced by getGridCellCoordinates(), getMaxPoint(), and getMinPoint().

◆ _elements_in_grid_box

std::vector<std::vector<MeshLib::Element const*> > MeshLib::MeshElementGrid::_elements_in_grid_box
private

Definition at line 86 of file MeshElementGrid.h.

Referenced by getElementsInVolume(), and sortElementInGridCells().

◆ _inverse_step_sizes

std::array<double,3> MeshLib::MeshElementGrid::_inverse_step_sizes {}
private

Definition at line 84 of file MeshElementGrid.h.

84{};

Referenced by getGridCellCoordinates().

◆ _n_steps

std::array<std::size_t,3> MeshLib::MeshElementGrid::_n_steps
private

◆ _step_sizes

std::array<double,3> MeshLib::MeshElementGrid::_step_sizes {}
private

Definition at line 83 of file MeshElementGrid.h.

83{};

The documentation for this class was generated from the following files: