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 24 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 17 of file MeshElementGrid.cpp.

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

References _aabb, _n_steps, and getNodes().

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 36 of file MeshElementGrid.h.

38 {
39 auto const min_coords(getGridCellCoordinates(min));
40 auto const max_coords(getGridCellCoordinates(max));
41
42 std::vector<MeshLib::Element const*> elements_vec;
43
44 const std::size_t n_plane(_n_steps[0]*_n_steps[1]);
45 for (std::size_t i(min_coords.second[0]); i<=max_coords.second[0]; i++) {
46 for (std::size_t j(min_coords.second[1]); j<=max_coords.second[1]; j++) {
47 for (std::size_t k(min_coords.second[2]); k<=max_coords.second[2]; k++) {
48 std::size_t idx(i+j*_n_steps[0]+k*n_plane);
49 elements_vec.insert(end(elements_vec),
50 begin(_elements_in_grid_box[idx]),
51 end(_elements_in_grid_box[idx]));
52 }
53 }
54 }
55 return elements_vec;
56 }
std::pair< bool, std::array< std::size_t, 3 > > getGridCellCoordinates(MathLib::Point3d const &p) const

References _elements_in_grid_box, _n_steps, getGridCellCoordinates(), and MeshLib::POINT.

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 201 of file MeshElementGrid.cpp.

202{
203 bool valid(true);
204 std::array<std::size_t, 3> coords{};
205
206 for (std::size_t k(0); k < 3; ++k)
207 {
208 const double d(p[k] - _aabb.getMinPoint()[k]);
209 if (d < 0.0)
210 {
211 valid = false;
212 coords[k] = 0;
213 }
214 else if (_aabb.getMaxPoint()[k] <= p[k])
215 {
216 valid = false;
217 coords[k] = _n_steps[k] - 1;
218 }
219 else
220 {
221 coords[k] = static_cast<std::size_t>(d * _inverse_step_sizes[k]);
222 }
223 }
224
225 return std::make_pair(valid, coords);
226}
constexpr ranges::views::view_closure coords
Definition Mesh.h:223

References _aabb, _inverse_step_sizes, and _n_steps.

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 117 of file MeshElementGrid.cpp.

118{
119 return _aabb.getMaxPoint();
120}

References _aabb.

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 112 of file MeshElementGrid.cpp.

113{
114 return _aabb.getMinPoint();
115}

References _aabb.

Referenced by MeshGeoToolsLib::getCandidateElementsForLineSegmentIntersection().

◆ sortElementInGridCells()

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

Definition at line 134 of file MeshElementGrid.cpp.

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

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 122 of file MeshElementGrid.cpp.

123{
124 for (auto const element : mesh.getElements())
125 {
126 if (!sortElementInGridCells(*element))
127 {
128 OGS_FATAL("Sorting element (id={:d}) into mesh element grid.",
129 element->getID());
130 }
131 }
132}
#define OGS_FATAL(...)
Definition Error.h:19
bool sortElementInGridCells(MeshLib::Element const &element)

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

Member Data Documentation

◆ _aabb

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

◆ _elements_in_grid_box

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

Definition at line 78 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 76 of file MeshElementGrid.h.

76{};

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 75 of file MeshElementGrid.h.

75{};

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