40 UniformGrid3(
const double lower[3],
const double spacing[3],
const int numCells[3],
const T& initial = T {})
43 for (
int a = 0; a < 3; ++a) {
44 if (!(spacing[a] > 0.0))
45 throw std::invalid_argument(
"UniformGrid3: the spacing must be positive");
47 throw std::invalid_argument(
"UniformGrid3: the number of cells must be at least 1");
48 m_lower[a] = lower[a];
49 m_spacing[a] = spacing[a];
50 m_numCells[a] = numCells[a];
51 size *=
static_cast<std::size_t
>(numCells[a] + 1);
53 m_values.assign(size, initial);
57 int NumCells(
int axis)
const {
return m_numCells[axis]; }
60 double Spacing(
int axis)
const {
return m_spacing[axis]; }
63 double NodeCoordinate(
int axis,
int index)
const {
return m_lower[axis] + index * m_spacing[axis]; }
66 T&
At(
int i,
int j,
int k) {
return m_values[Index(i, j, k)]; }
69 const T&
At(
int i,
int j,
int k)
const {
return m_values[Index(i, j, k)]; }
82 for (
int a = 0; a < 3; ++a) {
83 const double scaled = (pos[a] - m_lower[a]) / m_spacing[a];
84 if (!(scaled >= -boundarySlack && scaled <= m_numCells[a] + boundarySlack))
104 for (
int a = 0; a < 3; ++a) {
105 const double scaled = std::clamp((pos[a] - m_lower[a]) / m_spacing[a], 0.0,
static_cast<double>(m_numCells[a]));
106 cell[a] = std::min(
static_cast<int>(std::floor(scaled)), m_numCells[a] - 1);
107 fraction[a] = scaled - cell[a];
110 for (
int corner = 0; corner < 8; ++corner) {
113 for (
int a = 0; a < 3; ++a) {
114 const bool upper = (corner >> a) & 1;
115 node[a] = cell[a] + (upper ? 1 : 0);
116 weight *= upper ? fraction[a] : 1.0 - fraction[a];
118 sum = sum + weight *
At(node[0], node[1], node[2]);
125 static constexpr double boundarySlack = 1e-9;
127 std::size_t Index(
int i,
int j,
int k)
const
129 const std::size_t numX =
static_cast<std::size_t
>(m_numCells[0] + 1);
130 const std::size_t numY =
static_cast<std::size_t
>(m_numCells[1] + 1);
131 return static_cast<std::size_t
>(i) + numX * (
static_cast<std::size_t
>(j) + numY *
static_cast<std::size_t
>(k));
134 double m_lower[3] = {0.0, 0.0, 0.0};
135 double m_spacing[3] = {1.0, 1.0, 1.0};
136 int m_numCells[3] = {0, 0, 0};
137 std::vector<T> m_values;