https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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(Moose::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
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};
void hash_combine(std::size_t &)
Used for hash function specialization for Attribute objects.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:165
std::size_t operator()(const Point &p) const
An unordered map indexed by Point, eg 3 floating point numbers Because floating point rounding errors...
std::unordered_map< Point, Number, hash_point > base_map
The container indexed by points.
unsigned int hasKey(Point p)
Point getRoundedPoint(const Point &p) const
Normalize, expand then round a point to create local bins.
Point normalization
Normalization factors used to scale points before insertions/comparisons.
std::unordered_map< Point, Number, hash_point >::const_iterator end() const
std::unordered_map< Point, Number, hash_point >::const_iterator find(const Point &pt) const
Number & operator[](Point p)
bool attempt_find(const Point &p, Real dx, Real dy, Real dz, std::unordered_map< Point, Number, hash_point >::const_iterator &out) const
PointIndexedMap(const Point &mesh_max_coords)