54template <std::
floating_po
int T>
55T get_mi_coord_masked(T a, T b, T box_length,
56 T box_length_inv_masked)
noexcept {
57 auto const dx = a - b;
58 return dx - std::rint(dx * box_length_inv_masked) * box_length;
70template <std::
floating_po
int T>
71T get_mi_coord(T a, T b, T box_length,
bool periodic)
noexcept {
72 return get_mi_coord_masked(a, b, box_length,
73 periodic ? T{1} / box_length : T{0});
95 return pos + image_shift(image_box, box);
117 : m_length(length), m_length_inv_masked(length_inv_masked) {}
123 for (
auto c = 0u; c < 3u; ++c) {
124 auto const dx = detail::get_mi_coord_masked(a[c], b[c], m_length[c],
125 m_length_inv_masked[c]);
146 double const *sy,
double const *sz,
double *dx0,
147 double *dx1,
double *dx2,
double *dsq)
const noexcept {
148 auto const lx = m_length[0u];
149 auto const ly = m_length[1u];
150 auto const lz = m_length[2u];
151 auto const ix = m_length_inv_masked[0u];
152 auto const iy = m_length_inv_masked[1u];
153 auto const iz = m_length_inv_masked[2u];
154 for (
int t = 0; t < m; ++t) {
155 auto const a0 = detail::get_mi_coord_masked(xi, sx[t], lx, ix);
156 auto const a1 = detail::get_mi_coord_masked(yi, sy[t], ly, iy);
157 auto const a2 = detail::get_mi_coord_masked(zi, sz[t], lz, iz);
185 m_lees_edwards_bc = rhs.m_lees_edwards_bc;
191 std::bitset<3> m_periodic = 0b111;
214 m_periodic.set(
coord, val);
215 m_length_inv_masked[
coord] = val ? m_length_inv[
coord] : 0.;
226 return m_periodic[
coord];
254 m_length_inv = {1. / box_l[0], 1. / box_l[1], 1. / box_l[2]};
255 for (
auto c = 0u; c < 3u; ++c) {
256 m_length_inv_masked[c] = m_periodic[c] ? m_length_inv[c] : 0.;
258 m_length_half = 0.5 * box_l;
275 template <std::
floating_po
int T>
279 return detail::get_mi_coord_masked(
280 a, b,
static_cast<T
>(m_length[
coord]),
281 static_cast<T
>(m_length_inv_masked[
coord]));
299 template <std::
floating_po
int T>
308 a_tmp[shear_plane_normal], m_length[shear_plane_normal]);
310 b_tmp[shear_plane_normal], m_length[shear_plane_normal]);
312 m_length_inv, m_periodic);
334 template <std::
floating_po
int T>
345 return d0 * d0 + d1 * d1 + d2 * d2;
362 template <std::
floating_po
int T>
364 get_mi_vector(T
const &a0, T
const &a1, T
const &a2, T
const &b0, T
const &b1,
365 T
const &b2)
const noexcept {
368 T a_tmp[3] = {a0, a1, a2};
369 T b_tmp[3] = {b0, b1, b2};
371 a_tmp[shear_plane_normal], m_length[shear_plane_normal]);
373 b_tmp[shear_plane_normal], m_length[shear_plane_normal]);
376 m_length_half, m_length_inv, m_periodic);
408 auto const &le = m_lees_edwards_bc;
410 auto const shear_direction = le.shear_direction;
411 auto const dy = x[shear_plane_normal] - y[shear_plane_normal];
412 if (std::fabs(dy) >
length_half()[shear_plane_normal]) {
413 ret[shear_direction] -= std::copysign(1.0, dy) * le.shear_velocity;
425 for (
auto i = 0u; i < 3u; i++) {
429 if (result.second == std::numeric_limits<int>::min() or
430 result.second == std::numeric_limits<int>::max()) {
431 throw std::runtime_error(
432 "Overflow in the image box count while folding a particle "
433 "coordinate into the primary simulation box. Maybe a particle "
434 "experienced a huge force.");
436 std::tie(pos[i], image_box[i]) = result;
447 auto pos_folded = pos;
448 for (
auto i = 0u; i < 3u; i++) {
465 auto image_box_folded = image_box;
466 for (
auto i = 0u; i < 3u; i++) {
468 image_box_folded[i] =
473 return image_box_folded;
478 return detail::image_shift(image_box, m_length);
484 return detail::unfolded_position(pos, image_box, m_length);
static int coord(std::string const &s)
Vector implementation and trait types for boost qvm interoperability.
Compiler-attribute macros shared across ESPResSo headers.
#define ESPRESSO_ATTR_ALWAYS_INLINE
auto folded_image_box(Utils::Vector3d const &pos, Utils::Vector3i const &image_box) const noexcept
Calculate image box of coordinates folded to primary simulation box.
void lees_edwards_update(double pos_offset, double shear_velocity)
Update the Lees-Edwards parameters of the box geometry for the current simulation time.
Utils::Vector3d const & length() const
Box length.
auto folded_position(Utils::Vector3d const &pos) const noexcept
Calculate coordinates folded to primary simulation box.
LeesEdwardsBC const & lees_edwards_bc() const
BoxGeometry(BoxGeometry const &rhs)
constexpr bool periodic(unsigned coord) const
Check periodicity in direction.
ESPRESSO_ATTR_ALWAYS_INLINE Utils::Vector3< T > get_mi_vector(Utils::Vector3< T > const &a, Utils::Vector3< T > const &b) const noexcept
Get the minimum-image vector between two coordinates.
ESPRESSO_ATTR_ALWAYS_INLINE Utils::Vector3< T > get_mi_vector(T const &a0, T const &a1, T const &a2, T const &b0, T const &b1, T const &b2) const noexcept
Get the minimum-image vector between two coordinates.
T get_mi_coord(T a, T b, unsigned coord) const noexcept
Get the minimum-image distance between two coordinates.
ESPRESSO_ATTR_ALWAYS_INLINE T get_mi_dist2(Utils::Vector3< T > const &a, Utils::Vector3< T > const &b) const noexcept
Get the squared minimum-image distance between two coordinates.
auto cuboid_minimum_image() const
Cuboid minimum-image fold parameters for hoisting into kernels.
Utils::Vector3d velocity_difference(Utils::Vector3d const &x, Utils::Vector3d const &y, Utils::Vector3d const &u, Utils::Vector3d const &v) const noexcept
Calculate the velocity difference including the Lees-Edwards velocity.
auto unfolded_position(Utils::Vector3d const &pos, Utils::Vector3i const &image_box) const noexcept
Unfold particle coordinates to image box.
double volume() const
Box volume.
Utils::Vector3d const & length_half() const
Half box length.
auto image_shift(Utils::Vector3i const &image_box) const noexcept
Calculate image box shift vector.
Utils::Vector3d const & length_inv() const
Inverse box length.
void set_periodic(unsigned coord, bool val)
Set periodicity for direction.
void set_length(Utils::Vector3d const &box_l)
Set box side lengths.
void set_lees_edwards_bc(LeesEdwardsBC bc)
void fold_position(Utils::Vector3d &pos, Utils::Vector3i &image_box) const
Fold coordinates to primary simulation box in-place.
void set_type(BoxType type)
Cuboid minimum-image fold parameters for hot pair loops.
CuboidMinimumImage(Utils::Vector3d const &length, Utils::Vector3d const &length_inv_masked)
ESPRESSO_ATTR_ALWAYS_INLINE double dist2(Utils::Vector3d const &a, Utils::Vector3d const &b) const noexcept
Squared minimum-image distance between two coordinates.
ESPRESSO_ATTR_ALWAYS_INLINE void batch_vector_dist2(double xi, double yi, double zi, int m, double const *sx, double const *sy, double const *sz, double *dx0, double *dx1, double *dx2, double *dsq) const noexcept
Batched minimum-image vector and squared distance: one point (xi, yi, zi) against m others held in th...
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value) noexcept
Create a vector that has all entries set to the same value.
auto periodic_fold(std::floating_point auto x, std::integral auto i, std::floating_point auto l) noexcept
Fold value into primary interval.
T product(Vector< T, N > const &v)
auto hadamard_product(Vector< T, N > const &a, Vector< U, N > const &b)
unsigned int shear_plane_normal
Utils::Vector3d distance(Utils::Vector3d const &d, Utils::Vector3d const &l, Utils::Vector3d const &, Utils::Vector3d const &l_inv, std::bitset< 3 > const periodic) const