ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
SpecializedForcesKernel< HasCoulomb > Struct Template Reference

Own-the-loop specialization of the non-bonded pair kernel. More...

#include <forces_cabana.hpp>

+ Collaboration diagram for SpecializedForcesKernel< HasCoulomb >:

Public Member Functions

ESPRESSO_ATTR_ALWAYS_INLINE void operator() (std::size_t const i) const
 

Public Attributes

InteractionsNonBonded constnonbonded_ias
 
CellStructure::AoSoA_pack constaosoa
 
CellStructure::ScatterForce local_force
 
Kokkos::View< int const *, Kokkos::HostSpace > counts
 
Kokkos::View< int const **, Kokkos::LayoutRight, Kokkos::HostSpace > neighbors
 
CuboidMinimumImage minimum_image
 
double system_max_cutoff_sq
 
Coulomb::ShortRangeForceKernel::kernel_type constcoulomb_kernel
 
CoulombP3M constp3m
 

Static Public Attributes

static constexpr int tile_size = 64
 

Detailed Description

template<bool HasCoulomb>
struct SpecializedForcesKernel< HasCoulomb >

Own-the-loop specialization of the non-bonded pair kernel.

Handles the common case of a cuboid box with only central radial pair forces active, optionally with real-space electrostatics (HasCoulomb). The dispatch in forces.cpp selects it only when no torque-producing, asymmetric, thermostat or exclusion interaction is active (no dipoles, ELC, DPD, NPT virial, exclusions, Thole or Gay-Berne, no Lees-Edwards), and falls back to ForcesKernel otherwise.

Unlike ForcesKernel (invoked once per pair by Cabana::neighbor_parallel_for), this owns the Verlet-list loop and runs once per particle. That lets it hoist the per-particle position, type and charge, capture the cuboid box parameters by value, and obtain the ScatterView accessor once per particle instead of once per pair – the per-pair access() is an omp_get_thread_num call that dominates the LJ pair cost. It also accumulates the i-side force in a local register over all of particle i's neighbors and updates the ScatterView once per particle instead of once per pair; the j-side write stays per-pair (each neighbor j is distinct). This removes the per-pair i-side accessor update at the cost of changing the i-side summation order (a single register sum added once, rather than incremental scatter adds), so the result matches ForcesKernel to floating-point round-off rather than bitwise. if constexpr (HasCoulomb) compiles the electrostatics path in or out entirely.

The neighbors are processed in fixed-size tiles, each in three passes: a scalar gather of the neighbor positions into SoA scratch, a vectorized minimum-image pass (CuboidMinimumImage::batch_vector_dist2) that folds the whole tile at once and squares the distances, and a scalar pass that runs the short-range force only for the pairs whose squared distance passes the cutoff gate. The vectorized pass yields the same per-pair fold vector and squared distance as the scalar path, so identity is preserved.

Definition at line 420 of file forces_cabana.hpp.

Member Function Documentation

◆ operator()()

Member Data Documentation

◆ aosoa

◆ coulomb_kernel

◆ counts

template<bool HasCoulomb>
Kokkos::View<int const *, Kokkos::HostSpace> SpecializedForcesKernel< HasCoulomb >::counts

◆ local_force

◆ minimum_image

template<bool HasCoulomb>
CuboidMinimumImage SpecializedForcesKernel< HasCoulomb >::minimum_image

◆ neighbors

template<bool HasCoulomb>
Kokkos::View<int const **, Kokkos::LayoutRight, Kokkos::HostSpace> SpecializedForcesKernel< HasCoulomb >::neighbors

◆ nonbonded_ias

template<bool HasCoulomb>
InteractionsNonBonded const& SpecializedForcesKernel< HasCoulomb >::nonbonded_ias

◆ p3m

template<bool HasCoulomb>
CoulombP3M const* SpecializedForcesKernel< HasCoulomb >::p3m

◆ system_max_cutoff_sq

template<bool HasCoulomb>
double SpecializedForcesKernel< HasCoulomb >::system_max_cutoff_sq

◆ tile_size

template<bool HasCoulomb>
constexpr int SpecializedForcesKernel< HasCoulomb >::tile_size = 64
staticconstexpr

The documentation for this struct was generated from the following file: