https://mooseframework.inl.gov
PointIndexedMap.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "MooseUtils.h"
13 #include "MooseHashing.h"
14 #include "libmesh/point.h"
15 
20 {
21  PointIndexedMap(const Point & mesh_max_coords)
22  {
23  for (auto i : make_range(LIBMESH_DIM))
24  normalization(i) =
25  MooseUtils::absoluteFuzzyEqual(mesh_max_coords(i), 0) ? 1 : mesh_max_coords(i);
26  }
27 
33  inline Point getRoundedPoint(const Point & p) const
34  {
35  // We cant support coordinates too far from the normalization point
36  mooseAssert(p(0) / normalization(0) < 1 && p(1) / normalization(1) < 1 &&
37  p(2) / normalization(2) < 1,
38  "Point coordinates for indexing must be normalized below 1. "
39  "Point: "
40  << p << " normalization: " << normalization);
41 
42  std::vector<Real> rounded_p{round(p(0) / normalization(0) * pow(10, 12)),
43  round(p(1) / normalization(1) * pow(10, 12)),
44  round(p(2) / normalization(2) * pow(10, 12))};
45  return Point(rounded_p[0], rounded_p[1], rounded_p[2]);
46  }
47 
48  // This needs to be moved into libMesh according to Fande
49  // The hash helps sort the points in buckets
50  // Hashing the floats also leads to floating point comparison errors in their own way
51  // We hash a rounding of the float instead
52  struct hash_point
53  {
54  std::size_t operator()(const Point & p) const
55  {
56  std::size_t seed = 0;
57  Moose::hash_combine(seed, p(0), p(1), p(2));
58  return seed;
59  }
60  };
61 
63  std::unordered_map<Point, Number, hash_point> base_map;
64 
67 
68  Number & operator[](Point p)
69  {
70  auto it = find(p);
71  if (it != end())
72  return const_cast<Number &>(it->second);
73  else
74  {
75  const auto rp = getRoundedPoint(p);
76  return base_map[rp];
77  }
78  }
79 
80  unsigned int hasKey(Point p)
81  {
82  auto it = find(p);
83  if (it != end())
84  return true;
85  else
86  return false;
87  }
88 
89  std::unordered_map<Point, Number, hash_point>::const_iterator find(const Point & pt) const
90  {
91  const auto rp = getRoundedPoint(pt);
92 
93  auto it = base_map.find(rp);
94  if (it != base_map.end())
95  return it;
96  else
97  {
98  // Search the point with coordinates rounded down to origin
99  auto rounded = base_map.find(rp);
100  if (rounded != base_map.end())
101  return rounded;
102 
103  // To store the output of tentative searches
104  std::unordered_map<Point, Number, hash_point>::const_iterator out;
105 
106  // Search in all directions around
107  for (int i : make_range(2))
108  for (int j : make_range(2))
109  for (int k : make_range(2))
110  if (attempt_find(pt, 2 * i - 1, 2 * j - 1, 2 * k - 1, out))
111  return out;
112 
113  return base_map.end();
114  }
115  }
116 
117  bool attempt_find(const Point & p,
118  Real dx,
119  Real dy,
120  Real dz,
121  std::unordered_map<Point, Number, hash_point>::const_iterator & out) const
122  {
123  // Some epsilon to move the point by.
124  // There is no multiplicative epsilon that will reliably change the last decimal
125  const auto eps = 1e-13;
126  const auto shifted_rp = getRoundedPoint(p + Point(dx * eps * normalization(0),
127  dy * eps * normalization(1),
128  dz * eps * normalization(2)));
129  out = base_map.find(shifted_rp);
130  if (out != base_map.end())
131  return true;
132  return false;
133  }
134 
135  std::unordered_map<Point, Number, hash_point>::const_iterator end() const
136  {
137  return base_map.end();
138  }
139 };
PointIndexedMap(const Point &mesh_max_coords)
int eps(unsigned int i, unsigned int j)
2D version
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:380
std::unordered_map< Point, Number, hash_point > base_map
The container indexed by points.
std::unordered_map< Point, Number, hash_point >::const_iterator end() const
void hash_combine(std::size_t &)
Used for hash function specialization for Attribute objects.
Definition: MooseHashing.h:22
T pow(const T &x)
T round(T x)
Definition: MathUtils.h:77
Point normalization
Normalization factors used to scale points before insertions/comparisons.
std::unordered_map< Point, Number, hash_point >::const_iterator find(const Point &pt) const
An unordered map indexed by Point, eg 3 floating point numbers Because floating point rounding errors...
Point getRoundedPoint(const Point &p) const
Normalize, expand then round a point to create local bins.
OStreamProxy out
IntRange< T > make_range(T beg, T end)
Real Number
bool attempt_find(const Point &p, Real dx, Real dy, Real dz, std::unordered_map< Point, Number, hash_point >::const_iterator &out) const
Number & operator[](Point p)
unsigned int hasKey(Point p)
std::size_t operator()(const Point &p) const