10 #ifndef SRC_INCLUDE_LATTICE_H_ 11 #define SRC_INCLUDE_LATTICE_H_ 66 const std::array<int, 3>&
n,
67 const std::array<double, 3>& orig,
bool per,
71 cell_sizes_{l[0] / n[0], l[1] / n[1], l[2] / n[2]},
75 lattice_.resize(n_cells_[0] * n_cells_[1] * n_cells_[2]);
76 const auto& log = logger<LogArea::Lattice>();
77 log.debug(
"Rectangular lattice created: sizes[fm] = (", lattice_sizes_[0],
78 ",", lattice_sizes_[1],
",", lattice_sizes_[2],
"), dims = (",
79 n_cells_[0],
",", n_cells_[1],
",", n_cells_[2],
"), origin = (",
80 origin_[0],
",", origin_[1],
",", origin_[2],
81 "), periodic: ", periodic_);
82 if (n_cells_[0] < 1 || n_cells_[1] < 1 || n_cells_[2] < 1 ||
83 lattice_sizes_[0] < 0.0 || lattice_sizes_[1] < 0.0 ||
84 lattice_sizes_[2] < 0.0) {
85 throw std::invalid_argument(
86 "Lattice sizes should be positive, " 87 "lattice dimensions should be > 0.");
92 void reset() { std::fill(lattice_.begin(), lattice_.end(), T()); }
105 (ix < 0 || ix >= n_cells_[0] ||
106 iy < 0 || iy >= n_cells_[1] ||
107 iz < 0 || iz >= n_cells_[2]);
120 return ThreeVector(origin_[0] + cell_sizes_[0] * (ix + 0.5),
121 origin_[1] + cell_sizes_[1] * (iy + 0.5),
122 origin_[2] + cell_sizes_[2] * (iz + 0.5));
134 const int ix = index % n_cells_[0];
135 index = index / n_cells_[0];
136 const int iy = index % n_cells_[1];
137 const int iz = index / n_cells_[1];
138 return cell_center(ix, iy, iz);
142 const std::array<double, 3>&
lattice_sizes()
const {
return lattice_sizes_; }
145 const std::array<int, 3>&
dimensions()
const {
return n_cells_; }
148 const std::array<double, 3>&
cell_sizes()
const {
return cell_sizes_; }
151 const std::array<double, 3>&
origin()
const {
return origin_; }
160 using iterator =
typename std::vector<T>::iterator;
174 const T&
operator[](std::size_t i)
const {
return lattice_[i]; }
176 std::size_t
size()
const {
return lattice_.size(); }
186 T&
node(
int ix,
int iy,
int iz) {
188 ? lattice_[positive_modulo(ix, n_cells_[0]) +
190 (positive_modulo(iy, n_cells_[1]) +
191 n_cells_[1] * positive_modulo(iz, n_cells_[2]))]
192 : lattice_[ix + n_cells_[0] * (iy + n_cells_[1] * iz)];
210 const int ix = std::floor((r.
x1() - origin_[0]) / cell_sizes_[0]);
211 const int iy = std::floor((r.
x2() - origin_[1]) / cell_sizes_[1]);
212 const int iz = std::floor((r.
x3() - origin_[2]) / cell_sizes_[2]);
213 if (out_of_bounds(ix, iy, iz)) {
217 value = node(ix, iy, iz);
232 template <
typename F>
234 const std::array<int, 3>& upper_bounds, F&& func) {
235 const auto& log = logger<LogArea::Lattice>();
236 log.debug(
"Iterating sublattice with lower bound index (", lower_bounds[0],
237 ",", lower_bounds[1],
",", lower_bounds[2],
238 "), upper bound index (", upper_bounds[0],
",", upper_bounds[1],
239 ",", upper_bounds[2],
")");
242 for (
int iz = lower_bounds[2]; iz < upper_bounds[2]; iz++) {
243 const int z_offset = positive_modulo(iz, n_cells_[2]) * n_cells_[1];
244 for (
int iy = lower_bounds[1]; iy < upper_bounds[1]; iy++) {
246 n_cells_[0] * (positive_modulo(iy, n_cells_[1]) + z_offset);
247 for (
int ix = lower_bounds[0]; ix < upper_bounds[0]; ix++) {
248 const int index = positive_modulo(ix, n_cells_[0]) + y_offset;
249 func(lattice_[index], ix, iy, iz);
254 for (
int iz = lower_bounds[2]; iz < upper_bounds[2]; iz++) {
255 const int z_offset = iz * n_cells_[1];
256 for (
int iy = lower_bounds[1]; iy < upper_bounds[1]; iy++) {
257 const int y_offset = n_cells_[0] * (iy + z_offset);
258 for (
int ix = lower_bounds[0]; ix < upper_bounds[0]; ix++) {
259 func(lattice_[ix + y_offset], ix, iy, iz);
278 template <
typename F>
281 std::array<int, 3> l_bounds, u_bounds;
286 for (
int i = 0; i < 3; i++) {
288 std::ceil((point[i] - origin_[i] - r_cut) / cell_sizes_[i] - 0.5);
290 std::ceil((point[i] - origin_[i] + r_cut) / cell_sizes_[i] - 0.5);
294 for (
int i = 0; i < 3; i++) {
295 if (l_bounds[i] < 0) {
298 if (u_bounds[i] > n_cells_[i]) {
299 u_bounds[i] = n_cells_[i];
301 if (l_bounds[i] > n_cells_[i] || u_bounds[i] < 0) {
306 iterate_sublattice(l_bounds, u_bounds, std::forward<F>(func));
317 template <
typename L>
319 return n_cells_[0] == lat->dimensions()[0] &&
320 n_cells_[1] == lat->dimensions()[1] &&
321 n_cells_[2] == lat->dimensions()[2] &&
322 std::abs(lattice_sizes_[0] - lat->lattice_sizes()[0]) <
324 std::abs(lattice_sizes_[1] - lat->lattice_sizes()[1]) <
326 std::abs(lattice_sizes_[2] - lat->lattice_sizes()[2]) <
328 std::abs(origin_[0] - lat->origin()[0]) <
really_small &&
329 std::abs(origin_[1] - lat->origin()[1]) <
really_small &&
330 std::abs(origin_[2] - lat->origin()[2]) <
really_small &&
331 periodic_ == lat->periodic();
364 return (i + (n << 8)) %
n;
370 #endif // SRC_INCLUDE_LATTICE_H_
bool identical_to_lattice(const L *lat) const
Checks if lattices of possibly different types have identical structure.
The ThreeVector class represents a physical three-vector with the components .
constexpr double really_small
Numerical error tolerance.
const T & operator[](std::size_t i) const
bool out_of_bounds(int ix, int iy, int iz) const
Checks if 3D index is out of lattice bounds.
T & node(int ix, int iy, int iz)
Take the value of a cell given its 3-D indices.
T & operator[](std::size_t i)
LatticeUpdate
Enumerator option for lattice updates.
std::vector< T > lattice_
The lattice itself, array containing physical quantities.
typename std::vector< smash::EnergyMomentumTensor >::iterator iterator
Iterator of lattice.
const std::array< int, 3 > & dimensions() const
const LatticeUpdate when_update_
When the lattice should be recalculated.
const std::array< double, 3 > lattice_sizes_
Lattice sizes in x, y, z directions.
void iterate_in_radius(const ThreeVector &point, const double r_cut, F &&func)
Iterates only nodes, whose cell centers lie not further than r_cut in x, y, z directions from the giv...
Generic numerical functions.
const std::array< double, 3 > origin_
Coordinates of the left down nearer corner.
A container class to hold all the arrays on the lattice and access them.
LatticeUpdate when_update() const
typename std::vector< smash::EnergyMomentumTensor >::const_iterator const_iterator
Const interator of lattice.
const bool periodic_
Whether the lattice is periodic.
void reset()
Sets all values on lattice to zeros.
ThreeVector cell_center(int ix, int iy, int iz) const
Find the coordinates of a given cell.
RectangularLattice(const std::array< double, 3 > &l, const std::array< int, 3 > &n, const std::array< double, 3 > &orig, bool per, const LatticeUpdate upd)
Rectangular lattice constructor.
bool value_at(const ThreeVector &r, T &value)
Interpolates lattice quantity to coordinate r.
const std::array< double, 3 > cell_sizes_
Cell sizes in x, y, z directions.
const std::array< double, 3 > & origin() const
const_iterator begin() const
ThreeVector cell_center(int index) const
Find the coordinate of cell center given the 1d index of the cell.
const std::array< double, 3 > & lattice_sizes() const
int positive_modulo(int i, int n) const
Returns division modulo, which is always between 0 and n-1 in is not suitable, because it returns res...
const_iterator end() const
const std::array< double, 3 > & cell_sizes() const
void iterate_sublattice(const std::array< int, 3 > &lower_bounds, const std::array< int, 3 > &upper_bounds, F &&func)
A sub-lattice iterator, which iterates in a 3D-structured manner and calls a function on every cell...
const std::array< int, 3 > n_cells_
Number of cells in x,y,z directions.