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.
 
const PdgCode d(PdgCode::from_decimal(1000010020))
Deuteron.
 
LatticeUpdate
Enumerator option for lattice updates.
 
constexpr double really_small
Numerical error tolerance.
 
static constexpr int LLattice
 
Generic numerical functions.