30#include <Cabana_Core.hpp>
31#include <Kokkos_ScatterView.hpp>
48 if (
auto const &solver = coulomb.
impl->solver; solver.has_value()) {
49 if (std::holds_alternative<std::shared_ptr<CoulombP3M>>(*solver)) {
50 return std::get<std::shared_ptr<CoulombP3M>>(*solver).get();
57#ifdef ESPRESSO_ELECTROSTATICS
73 return p3m->pair_force(q1q2, d, dist);
76 return (*coulomb_kernel)(q1q2, d, dist);
91#ifdef ESPRESSO_ROTATION
94#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
116 std::vector<Particle *>
const &unique_particles_,
118#ifdef ESPRESSO_ROTATION
121#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
135#ifdef ESPRESSO_ROTATION
138#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
157 std::size_t j)
const {
165 auto const dist_sq = d.norm2();
170 auto const dist = std::sqrt(dist_sq);
171 auto const &ia_params =
177#if defined(ESPRESSO_EXCLUSIONS) or defined(ESPRESSO_THOLE)
178 bool need_particle_pointers =
false;
179#ifdef ESPRESSO_EXCLUSIONS
183 need_particle_pointers |=
189 if (need_particle_pointers) {
199 if (dist <= ia_params.max_cut) {
200#ifdef ESPRESSO_EXCLUSIONS
201 bool skip_non_bonded =
false;
206 constexpr bool skip_non_bonded =
false;
208 if (not skip_non_bonded) {
219#ifdef ESPRESSO_GAY_BERNE
234 box_geo, ia_params, d, dist, dist_sq);
252 virial = hadamard_product(pf.f, d);
256#ifdef ESPRESSO_ELECTROSTATICS
272 (*elc_kernel)(pos1, pos2, f1_asym, f2_asym, q1q2);
278 virial[0] += (*coulomb_u_kernel)(pos1, pos2, q1q2, d, dist);
285#ifdef ESPRESSO_DIPOLES
291#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
297#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
298 dip_fld_i, dip_fld_j,
301#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
303 access_dip_fld(i, 0) += dip_fld_i[0];
304 access_dip_fld(i, 1) += dip_fld_i[1];
305 access_dip_fld(i, 2) += dip_fld_i[2];
306 access_dip_fld(j, 0) += dip_fld_j[0];
307 access_dip_fld(j, 1) += dip_fld_j[1];
308 access_dip_fld(j, 2) += dip_fld_j[2];
318 virial[0] += d * dip_pf.f;
327#ifdef ESPRESSO_ELECTROSTATICS
334 access_force(i, 0) += pf.f[0];
335 access_force(i, 1) += pf.f[1];
336 access_force(i, 2) += pf.f[2];
337#ifdef ESPRESSO_ROTATION
339 access_torque(i, 0) += pf.torque[0];
340 access_torque(i, 1) += pf.torque[1];
341 access_torque(i, 2) += pf.torque[2];
344 access_force(j, 0) += opf.f[0];
345 access_force(j, 1) += opf.f[1];
346 access_force(j, 2) += opf.f[2];
347#ifdef ESPRESSO_ROTATION
348 access_torque(j, 0) += opf.torque[0];
349 access_torque(j, 1) += opf.torque[1];
350 access_torque(j, 2) += opf.torque[2];
355 access_virial(0) += virial[0];
356 access_virial(1) += virial[1];
357 access_virial(2) += virial[2];
426 Kokkos::View<int const *, Kokkos::HostSpace>
counts;
427 Kokkos::View<int const **, Kokkos::LayoutRight, Kokkos::HostSpace>
neighbors;
430#ifdef ESPRESSO_ELECTROSTATICS
439 auto const n_neighbors =
counts(i);
440 if (n_neighbors == 0)
447#ifdef ESPRESSO_ELECTROSTATICS
448 double charge_i = 0.;
449 if constexpr (HasCoulomb) {
466 for (
int base = 0; base < n_neighbors; base +=
tile_size) {
469 auto const m = Kokkos::min(+
tile_size, n_neighbors - base);
472 for (
int t = 0; t < m; ++t) {
475 auto const row_j =
static_cast<std::size_t
>(j);
487 for (
int t = 0; t < m; ++t) {
490 auto const j =
static_cast<std::size_t
>(js[t]);
492 auto const dist = std::sqrt(dsq[t]);
493 auto const &ia_params =
497 if (dist <= ia_params.max_cut) {
500#ifdef ESPRESSO_ELECTROSTATICS
501 if constexpr (HasCoulomb) {
503 if (charge_i != 0. and charge_j != 0.) {
504 auto const q1q2 = charge_i * charge_j;
516 access_force(j, 0) -= f[0];
517 access_force(j, 1) -= f[1];
518 access_force(j, 2) -= f[2];
523 access_force(i, 0) += f_i[0];
524 access_force(i, 1) += f_i[1];
525 access_force(i, 2) += f_i[2];
Vector implementation and trait types for boost qvm interoperability.
#define ESPRESSO_ATTR_ALWAYS_INLINE
container for bonded interactions.
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.
Kokkos::Experimental::ScatterView< double *[3], Kokkos::LayoutRight, memory_space > ScatterForce
Kokkos::Experimental::ScatterView< double[3], Kokkos::LayoutRight, memory_space > ScatterVirial
Cuboid minimum-image fold parameters for hot pair loops.
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...
auto & get_ia_param(int i, int j)
Get interaction parameters between particle types i and j.
std::shared_ptr< DPDThermostat > dpd
int thermo_switch
Bitmask of currently active thermostats.
Utils::Vector3d dpd_pair_force(Utils::Vector3d const &p1_position, Utils::Vector3d const &p1_velocity, int p1_id, Utils::Vector3d const &p2_position, Utils::Vector3d const &p2_velocity, int p2_id, DPDThermostat const &dpd, BoxGeometry const &box_geo, IA_parameters const &ia_params, Utils::Vector3d const &d, double dist, double dist2)
bool do_nonbonded(Particle const &p1, Particle const &p2)
Determine if the non-bonded interactions between p1 and p2 should be calculated.
CoulombP3M const * get_toplevel_p3m_solver(Coulomb::Solver const &coulomb)
The active P3M solver, or nullptr.
constexpr unsigned specialized_kernel_pair_mask
Pair potentials fully handled by SpecializedForcesKernel, i.e.
ESPRESSO_ATTR_ALWAYS_INLINE Utils::Vector3d coulomb_pair_force(double q1q2, Utils::Vector3d const &d, double dist, Coulomb::ShortRangeForceKernel::kernel_type const *coulomb_kernel, CoulombP3M const *p3m)
Real-space charge-charge pair force: the P3M fast path when the solver is (top-level) P3M,...
ParticleForce calc_opposing_force(ParticleForce const &pf, Utils::Vector3d const &d)
ESPRESSO_ATTR_ALWAYS_INLINE Utils::Vector3d calc_central_radial_force(IA_parameters const &ia_params, Utils::Vector3d const &d, double const dist)
ParticleForce gb_pair_force(Utils::Vector3d const &ui, Utils::Vector3d const &uj, IA_parameters const &ia_params, Utils::Vector3d const &d, double dist)
Calculate Gay-Berne force and torques.
DEVICE_QUALIFIER constexpr unsigned pair_potential_bit(PairPotential p)
Bitmask for a pair potential.
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION bool gay_berne_active(double dist, IA_parameters const &ia_params)
KOKKOS_INLINE_FUNCTION bool thole_active(IA_parameters const &ia_params, bool has_coulomb_kernel)
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION bool dpd_active(IA_parameters const &ia_params, int thermo_switch)
DEVICE_QUALIFIER bool has_exclusion(std::size_t i) const
PositionViewType position
DEVICE_QUALIFIER Utils::Vector< T, N > get_vector_at(Kokkos::View< T *[N], array_layout, Kokkos::HostSpace > const &view, std::size_t i) const
DirectorViewType director
VelocityViewType velocity
Solver::ShortRangeEnergyKernel kernel_type
Solver::ShortRangeForceCorrectionsKernel kernel_type
Solver::ShortRangeForceKernel kernel_type
std::unique_ptr< Implementation > impl
Pointer-to-implementation.
Solver::ShortRangeForceKernel kernel_type
std::vector< Particle * > const & unique_particles
CellStructure::ScatterForce local_force
Coulomb::ShortRangeEnergyKernel::kernel_type const *const coulomb_u_kernel
Coulomb::ShortRangeForceCorrectionsKernel::kernel_type const * elc_kernel
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION bool npt_active() const
CellStructure::ScatterVirial local_virial
CellStructure::ScatterForce local_dip_fld
BoxGeometry const & box_geo
double system_max_cutoff_sq
Dipoles::ShortRangeForceKernel::kernel_type const *const dipoles_kernel
CellStructure::AoSoA_pack const & aosoa
CellStructure::ScatterForce local_torque
InteractionsNonBonded const & nonbonded_ias
Utils::Vector3d *const global_virial
ForcesKernel(BondedInteractionsMap const &bonded_ias_, InteractionsNonBonded const &nonbonded_ias_, Coulomb::ShortRangeForceKernel::kernel_type const *coulomb_kernel_, Dipoles::ShortRangeForceKernel::kernel_type const *dipoles_kernel_, Coulomb::ShortRangeForceCorrectionsKernel::kernel_type const *elc_kernel_, Coulomb::ShortRangeEnergyKernel::kernel_type const *coulomb_u_kernel_, Coulomb::Solver const &coulomb_, Thermostat::Thermostat const &thermostat_, BoxGeometry const &box_geo_, std::vector< Particle * > const &unique_particles_, CellStructure::ScatterForce local_force_, CellStructure::ScatterForce local_torque_, CellStructure::ScatterForce local_dip_fld_, Utils::Vector3d *const global_virial_, CellStructure::ScatterVirial local_virial_, CellStructure::AoSoA_pack const &aosoa_, double system_max_cutoff_)
BondedInteractionsMap const & bonded_ias
Coulomb::ShortRangeForceKernel::kernel_type const *const coulomb_kernel
Thermostat::Thermostat const & thermostat
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t i, std::size_t j) const
Force information on a particle.
Struct holding all information for one particle.
Own-the-loop specialization of the non-bonded pair kernel.
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t const i) const
Kokkos::View< int const *, Kokkos::HostSpace > counts
CellStructure::ScatterForce local_force
Coulomb::ShortRangeForceKernel::kernel_type const * coulomb_kernel
InteractionsNonBonded const & nonbonded_ias
static constexpr int tile_size
Kokkos::View< int const **, Kokkos::LayoutRight, Kokkos::HostSpace > neighbors
CellStructure::AoSoA_pack const & aosoa
CuboidMinimumImage minimum_image
double system_max_cutoff_sq
Utils::Vector3d thole_pair_force(Particle const &p1, Particle const &p2, IA_parameters const &ia_params, Utils::Vector3d const &d, double dist, BondedInteractionsMap const &bonded_ias, Coulomb::ShortRangeForceKernel::kernel_type const *kernel)
Calculate Thole force.