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(_aabb.getMinPoint());
45  auto const& max_pnt(_aabb.getMaxPoint());
46  auto const dim = getDimensions(min_pnt, max_pnt);
47 
48  std::array<double, 3> delta{{max_pnt[0] - min_pnt[0],
49  max_pnt[1] - min_pnt[1],
50  max_pnt[2] - min_pnt[2]}};
51 
52  const std::size_t n_eles(mesh.getNumberOfElements());
53  const std::size_t n_eles_per_cell(100);
54 
55  // *** condition: n_eles / n_cells < n_eles_per_cell
56  // where n_cells = _n_steps[0] * _n_steps[1] * _n_steps[2]
57  // *** with _n_steps[0] =
58  // ceil(pow(n_eles*delta[0]*delta[0]/(n_eles_per_cell*delta[1]*delta[2]),
59  // 1/3.)));
60  // _n_steps[1] = _n_steps[0] * delta[1]/delta[0],
61  // _n_steps[2] = _n_steps[0] * delta[2]/delta[0]
62  auto sc_ceil = [](double v)
63  { return static_cast<std::size_t>(std::ceil(v)); };
64 
65  switch (dim.count())
66  {
67  case 3: // 3d case
68  _n_steps[0] =
69  sc_ceil(std::cbrt(n_eles * delta[0] * delta[0] /
70  (n_eles_per_cell * delta[1] * delta[2])));
71  _n_steps[1] =
72  sc_ceil(_n_steps[0] * std::min(delta[1] / delta[0], 100.0));
73  _n_steps[2] =
74  sc_ceil(_n_steps[0] * std::min(delta[2] / delta[0], 100.0));
75  break;
76  case 2: // 2d cases
77  if (dim[0] && dim[2])
78  { // 2d case: xz plane, y = const
79  _n_steps[0] = sc_ceil(std::sqrt(n_eles * delta[0] /
80  (n_eles_per_cell * delta[2])));
81  _n_steps[2] = sc_ceil(_n_steps[0] * delta[2] / delta[0]);
82  }
83  else if (dim[0] && dim[1])
84  { // 2d case: xy plane, z = const
85  _n_steps[0] = sc_ceil(std::sqrt(n_eles * delta[0] /
86  (n_eles_per_cell * delta[1])));
87  _n_steps[1] = sc_ceil(_n_steps[0] * delta[1] / delta[0]);
88  }
89  else if (dim[1] && dim[2])
90  { // 2d case: yz plane, x = const
91  _n_steps[1] = sc_ceil(std::sqrt(n_eles * delta[1] /
92  (n_eles_per_cell * delta[2])));
93  _n_steps[2] =
94  sc_ceil(n_eles * delta[2] / (n_eles_per_cell * delta[1]));
95  }
96  break;
97  case 1: // 1d cases
98  for (std::size_t k(0); k < 3; ++k)
99  {
100  if (dim[k])
101  {
102  _n_steps[k] =
103  sc_ceil(static_cast<double>(n_eles) / n_eles_per_cell);
104  }
105  }
106  }
107 
108  // some frequently used expressions to fill the vector of elements per grid
109  // cell
110  for (std::size_t k(0); k < 3; k++)
111  {
112  _step_sizes[k] = delta[k] / _n_steps[k];
113  _inverse_step_sizes[k] = 1.0 / _step_sizes[k];
114  }
115 
116  _elements_in_grid_box.resize(_n_steps[0] * _n_steps[1] * _n_steps[2]);
118 }
std::pair< std::size_t, std::size_t > getDimensions(std::string const &line)
Returns raster dimensions from the "Zone"-description.
Eigen::Vector3d const & getMinPoint() const
Definition: AABB.h:174
Eigen::Vector3d const & getMaxPoint() const
Definition: AABB.h:181
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
static double const tolerance

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

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

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

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

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

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

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

Referenced by MeshGeoToolsLib::getCandidateElementsForLineSegmentIntersection().

◆ sortElementInGridCells()

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

Definition at line 142 of file MeshElementGrid.cpp.

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

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

Referenced by sortElementsInGridCells().

◆ sortElementsInGridCells()

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

Definition at line 130 of file MeshElementGrid.cpp.

131 {
132  for (auto const element : mesh.getElements())
133  {
134  if (!sortElementInGridCells(*element))
135  {
136  OGS_FATAL("Sorting element (id={:d}) into mesh element grid.",
137  element->getID());
138  }
139  }
140 }
#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.

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.


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