10 #ifndef SRC_INCLUDE_SMASH_LATTICE_H_
11 #define SRC_INCLUDE_SMASH_LATTICE_H_
25 static constexpr
int LLattice = LogArea::Lattice::id;
67 const std::array<int, 3>&
n,
68 const std::array<double, 3>& orig,
bool per,
79 "Rectangular lattice created: sizes[fm] = (",
lattice_sizes_[0],
",",
81 ",",
n_cells_[1],
",",
n_cells_[2],
"), origin = (",
origin_[0],
",",
86 throw std::invalid_argument(
87 "Lattice sizes should be positive, "
88 "number of lattice cells should be > 0.");
172 using iterator =
typename std::vector<T>::iterator;
225 return index1d(ix - 1, iy, iz);
242 return index1d(ix + 1, iy, iz);
259 return index1d(ix, iy - 1, iz);
276 return index1d(ix, iy + 1, iz);
293 return index1d(ix, iy, iz - 1);
310 return index1d(ix, iy, iz + 1);
324 throw std::runtime_error(
325 "Lattice is too small for gradient calculation"
326 " (should be at least 2x2x2)");
330 throw std::invalid_argument(
331 "Lattice for gradient should have the"
332 " same origin/dims/periodicity as the original one.");
342 for (
int iz = 0; iz <
n_cells_[2]; iz++) {
343 const int z_offset = diz * iz;
344 for (
int iy = 0; iy <
n_cells_[1]; iy++) {
345 const int y_offset = diy * iy + z_offset;
346 for (
int ix = 0; ix <
n_cells_[0]; ix++) {
347 const int index = ix + y_offset;
349 (grad_lat)[index].set_x1(
356 (grad_lat)[index].set_x1(
363 (grad_lat)[index].set_x1(
368 (grad_lat)[index].set_x2(
375 (grad_lat)[index].set_x2(
382 (grad_lat)[index].set_x2(
387 (grad_lat)[index].set_x3(
394 (grad_lat)[index].set_x3(
401 (grad_lat)[index].set_x3(
423 throw std::runtime_error(
424 "Lattice is too small for gradient calculation"
425 " (should be at least 2x2x2)");
429 throw std::invalid_argument(
430 "Lattice for gradient should have the"
431 " same origin/dims/periodicity as the original one.");
441 for (
int iz = 0; iz <
n_cells_[2]; iz++) {
442 const int z_offset = diz * iz;
443 for (
int iy = 0; iy <
n_cells_[1]; iy++) {
444 const int y_offset = diy * iy + z_offset;
445 for (
int ix = 0; ix <
n_cells_[0]; ix++) {
446 const int index = ix + y_offset;
454 grad_t_jmu = (
lattice_[index] - (old_lat)[index]) * (1.0 / time_step);
507 (grad_lat)[index][0] = grad_t_jmu;
508 (grad_lat)[index][1] = grad_x_jmu;
509 (grad_lat)[index][2] = grad_y_jmu;
510 (grad_lat)[index][3] = grad_z_jmu;
524 T&
node(
int ix,
int iy,
int iz) {
555 value =
node(ix, iy, iz);
570 template <
typename F>
572 const std::array<int, 3>& upper_bounds, F&& func) {
574 "Iterating sublattice with lower bound index (", lower_bounds[0],
",",
575 lower_bounds[1],
",", lower_bounds[2],
"), upper bound index (",
576 upper_bounds[0],
",", upper_bounds[1],
",", upper_bounds[2],
")");
579 for (
int iz = lower_bounds[2]; iz < upper_bounds[2]; iz++) {
581 for (
int iy = lower_bounds[1]; iy < upper_bounds[1]; iy++) {
584 for (
int ix = lower_bounds[0]; ix < upper_bounds[0]; ix++) {
591 for (
int iz = lower_bounds[2]; iz < upper_bounds[2]; iz++) {
592 const int z_offset = iz *
n_cells_[1];
593 for (
int iy = lower_bounds[1]; iy < upper_bounds[1]; iy++) {
594 const int y_offset =
n_cells_[0] * (iy + z_offset);
595 for (
int ix = lower_bounds[0]; ix < upper_bounds[0]; ix++) {
596 func(
lattice_[ix + y_offset], ix, iy, iz);
616 template <
typename F>
618 std::array<int, 3> l_bounds, u_bounds;
623 for (
int i = 0; i < 3; i++) {
631 for (
int i = 0; i < 3; i++) {
632 if (l_bounds[i] < 0) {
638 if (l_bounds[i] >
n_cells_[i] || u_bounds[i] < 0) {
657 template <
typename F>
662 point, {rcut, rcut, rcut},
663 [&point, &integral, &integrand,
this](T value,
int ix,
int iy,
int iz) {
665 integral += integrand(pos, value, point) * this->
cell_volume_;
682 template <
typename F>
684 const std::array<double, 3>& rectangle, F&& func) {
685 std::array<int, 3> l_bounds, u_bounds;
692 for (
int i = 0; i < 3; i++) {
693 l_bounds[i] = std::ceil(
695 u_bounds[i] = std::ceil(
700 for (
int i = 0; i < 3; i++) {
701 if (l_bounds[i] < 0) {
707 if (l_bounds[i] >
n_cells_[i] || u_bounds[i] < 0) {
726 template <
typename F>
734 "Iterating over nearest neighbors of the cell at ix = ", ix,
735 ", iy = ", iy,
", iz = ", iz);
738 const int i =
index1d(ix, iy, iz);
755 func(
lattice_[ibackward], ibackward, i);
758 func(
lattice_[iforward], iforward, i);
769 template <
typename L>
771 return n_cells_[0] == lat->n_cells()[0] &&
818 return (i + (
n << 8)) %
n;
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
A container class to hold all the arrays on the lattice and access them.
const double cell_volume_
Volume of a cell.
bool out_of_bounds(int ix, int iy, int iz) const
Checks if 3D index is out of lattice bounds.
const std::array< double, 3 > & origin() const
const_iterator end() const
const std::array< int, 3 > n_cells_
Number of cells in x,y,z directions.
int index_right(int ix, int iy, int iz)
Given the indices of a cell in the x, y, and z directions, return index of the nearest cell in the +x...
int index_left(int ix, int iy, int iz)
Given the indices of a cell in the x, y, and z directions, return index of the nearest cell in the -x...
const bool periodic_
Whether the lattice is periodic.
int index1d(int ix, int iy, int iz)
Return the index of a given cell.
const std::array< double, 3 > & lattice_sizes() const
T & operator[](std::size_t i)
const T & operator[](std::size_t i) const
int index_up(int ix, int iy, int iz)
Given the indices of a cell in the x, y, and z directions, return index of the nearest cell in the +y...
bool identical_to_lattice(const L *lat) const
Checks if lattices of possibly different types have identical structure.
const std::array< double, 3 > origin_
Coordinates of the left down nearer corner.
int index_backward(int ix, int iy, int iz)
Given the indices of a cell in the x, y, and z directions, return index of the nearest cell in the -z...
void reset()
Sets all values on lattice to zeros.
LatticeUpdate when_update() const
void compute_four_gradient_lattice(RectangularLattice< FourVector > &old_lat, double time_step, RectangularLattice< std::array< FourVector, 4 >> &grad_lat) const
Compute a fourgradient on a lattice of FourVectors jmu via the finite difference method.
const LatticeUpdate when_update_
When the lattice should be recalculated.
const std::array< int, 3 > & n_cells() const
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.
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.
void compute_gradient_lattice(RectangularLattice< ThreeVector > &grad_lat) const
Compute a gradient on a lattice of doubles via the finite difference method.
ThreeVector cell_center(int ix, int iy, int iz) const
Find the coordinates of a given cell.
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...
int index_forward(int ix, int iy, int iz)
Given the indices of a cell in the x, y, and z directions, return index of the nearest cell in the +z...
typename std::vector< T >::const_iterator const_iterator
Const interator of lattice.
void assign_value(int lattice_index, T value)
Overwrite with a template value T at a given node.
void iterate_in_cube(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 give...
RectangularLattice(RectangularLattice< T > const &rl)
Copy-constructor.
const_iterator begin() const
void integrate_volume(F &integral, F(*integrand)(ThreeVector, T &, ThreeVector), const double rcut, const ThreeVector &point)
Calculate a volume integral with given integrand.
void iterate_nearest_neighbors(const ThreeVector &point, F &&func)
Iterates only over nodes corresponding to the center cell (the cell containing the given point) and i...
typename std::vector< T >::iterator iterator
Iterator of lattice.
void iterate_in_rectangle(const ThreeVector &point, const std::array< double, 3 > &rectangle, F &&func)
Iterates only nodes whose cell centers lie not further than d_x in x-, d_y in y-, and d_z in z-direct...
const std::array< double, 3 > lattice_sizes_
Lattice sizes in x, y, z directions.
T & node(int ix, int iy, int iz)
Take the value of a cell given its 3-D indices.
const std::array< double, 3 > cell_sizes_
Cell sizes in x, y, z directions.
bool value_at(const ThreeVector &r, T &value)
Interpolates lattice quantity to coordinate r.
std::vector< T > lattice_
The lattice itself, array containing physical quantities.
ThreeVector cell_center(int index) const
Find the coordinate of cell center given the 1d index of the cell.
int index_down(int ix, int iy, int iz)
Given the indices of a cell in the x, y, and z directions, return index of the nearest cell in the -y...
const std::array< double, 3 > & cell_sizes() const
The ThreeVector class represents a physical three-vector with the components .
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
LatticeUpdate
Enumerator option for lattice updates.
constexpr double really_small
Numerical error tolerance.
static constexpr int LLattice
Generic numerical functions.