31#include "collision_detection/CollisionDetection.hpp"
33#include "constraints/Constraints.hpp"
37#include "galilei/ComFixed.hpp"
51#include "system/System.hpp"
59#ifdef ESPRESSO_CALIPER
63#include <Cabana_Core.hpp>
103 if (
not system.comfixed->get_fixed_types().empty())
106 if (
system.get_force_cap() != 0.)
110 if (
system.propagation->used_propagations &
115#ifdef ESPRESSO_VIRTUAL_SITES_INERTIALESS_TRACERS
120#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
121 if (
system.dipoles.impl->solver.has_value()) {
127 auto const integ =
system.propagation->integ_switch;
132 if (force_cap > 0.) {
144#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
157 auto const &aosoa =
system.cell_structure->get_aosoa();
171 auto const &elc_kernel,
auto const &coulomb_kernel,
172 auto const &dipoles_kernel,
auto const &coulomb_u_kernel) {
174 auto const &unique_particles =
system.cell_structure->get_unique_particles();
177#ifdef ESPRESSO_ROTATION
180#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
186 auto const &aosoa =
system.cell_structure->get_aosoa();
199#ifdef ESPRESSO_ROTATION
202#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
215template <
bool HasCoulomb>
231 std::size_t
const n) {
239#ifdef ESPRESSO_ELECTROSTATICS
248 Kokkos::parallel_for(
"specialized_nonbonded_pairs",
249 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(
265 [[
maybe_unused]]
auto const &elc_kernel,
auto const &coulomb_kernel,
273#ifdef ESPRESSO_DIPOLES
274 if (
get_ptr(dipoles_kernel) !=
nullptr)
277#ifdef ESPRESSO_ELECTROSTATICS
278 if (
get_ptr(elc_kernel) !=
nullptr)
281 auto const &nonbonded_ias = *
system.nonbonded_ias;
287 if ((nonbonded_ias.combined_active_pair_mask() &
292 if (nonbonded_ias.any_thole_configured())
295 auto &cell_structure = *
system.cell_structure;
296 auto const &aosoa = cell_structure.get_aosoa();
297#ifdef ESPRESSO_EXCLUSIONS
302 if (aosoa.has_any_exclusion())
307 auto const minimum_image =
system.box_geo->cuboid_minimum_image();
310#ifdef ESPRESSO_ELECTROSTATICS
323 static_cast<void>(coulomb_kernel);
332#ifdef ESPRESSO_CALIPER
336 auto const &unique_particles =
system.cell_structure->get_unique_particles();
337 auto &local_force =
system.cell_structure->get_local_force();
339 Kokkos::Experimental::contribute(local_force,
scatter_force);
340#ifdef ESPRESSO_ROTATION
345 auto &local_torque =
system.cell_structure->get_local_torque();
351#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
353 auto &local_dip_fld =
system.cell_structure->get_local_dip_fld();
360 auto &local_virial =
system.cell_structure->get_local_virial();
361 if (
system.cell_structure->virial_replicas_dirty()) {
367 using execution_space = Kokkos::DefaultHostExecutionSpace;
368 Kokkos::RangePolicy<execution_space> policy(std::size_t{0},
369 unique_particles.size());
370 Kokkos::parallel_for(
"reduction", policy,
378 &unique_particles](std::size_t
const i) {
380 force[0] += local_force(i, 0);
381 force[1] += local_force(i, 1);
382 force[2] += local_force(i, 2);
383 unique_particles.at(i)->force() += force;
384#ifdef ESPRESSO_ROTATION
387 torque[0] += local_torque(i, 0);
388 torque[1] += local_torque(i, 1);
389 torque[2] += local_torque(i, 2);
390 unique_particles.at(i)->torque() += torque;
393#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
396 dip_fld[0] += local_dip_fld(i, 0);
397 dip_fld[1] += local_dip_fld(i, 1);
398 dip_fld[2] += local_dip_fld(i, 2);
399 unique_particles.at(i)->dip_fld() += dip_fld;
407 (*virial)[0] += local_virial(0);
408 (*virial)[1] += local_virial(1);
409 (*virial)[2] += local_virial(2);
415#ifdef ESPRESSO_CALIPER
420#ifdef ESPRESSO_CALIPER
424#ifdef ESPRESSO_CALIPER
430#ifdef ESPRESSO_COLLISION_DETECTION
431 collision_detection->clear_queue();
436 bond_breakage->clear_queue();
437 auto particles = cell_structure->local_particles();
444#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
445 if (dipoles.impl->solver.has_value()) {
452 auto const elc_kernel = coulomb.pair_force_elc_kernel();
453 auto const coulomb_kernel = coulomb.pair_force_kernel();
454 auto const dipoles_kernel = dipoles.pair_force_kernel();
455 auto const coulomb_u_kernel = coulomb.pair_energy_kernel();
456 auto *
const virial = get_npt_virial();
463 cell_structure->get_verlet_skin(),
464 get_interaction_range(),
471#ifdef ESPRESSO_ELECTROSTATICS
472 if (coulomb.impl->extension) {
473 update_icc_particles();
477#ifdef ESPRESSO_CALIPER
480#ifdef ESPRESSO_ELECTROSTATICS
481 coulomb.calc_long_range_force();
483#ifdef ESPRESSO_DIPOLES
484 dipoles.calc_long_range_force();
486#ifdef ESPRESSO_CALIPER
490#ifdef ESPRESSO_CALIPER
493 auto &
bs = cell_structure->bond_state();
504 dipoles_kernel, coulomb_u_kernel);
507 *
this,
virial, elc_kernel, coulomb_kernel, dipoles_kernel);
518 get_interaction_range() > 0.
and
521 not cell_structure->use_verlet_list);
522#ifdef ESPRESSO_ROTATION
528#ifdef ESPRESSO_DIPOLES
529 get_ptr(dipoles_kernel) !=
nullptr;
534 cell_structure->mark_torque_replicas_dirty();
535#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
536 cell_structure->mark_dip_fld_replicas_dirty();
545 auto const have_bonds = cell_structure->get_local_pair_bond_numbers() > 0
or
546 cell_structure->get_local_angle_bond_numbers() > 0
or
547 cell_structure->get_local_dihedral_bond_numbers() > 0;
550 cell_structure->mark_virial_replicas_dirty();
556 *cell_structure, get_interaction_range(),
563#ifdef ESPRESSO_COLLISION_DETECTION
567 collision_detection.detect_collision(
p1,
p2, d.dist2);
569 if (
not collision_detection->is_off()) {
575#ifdef ESPRESSO_CALIPER
579 constraints->add_forces(particles, get_sim_time());
580 oif_global->calculate_forces();
583 immersed_boundaries->volume_conservation(*cell_structure);
585 if (thermostat->lb
and (propagation->used_propagations &
587#ifdef ESPRESSO_CALIPER
590 lb_couple_particles();
591#ifdef ESPRESSO_CALIPER
598#ifdef ESPRESSO_CALIPER
601 gpu->copy_forces_to_host(particles,
this_node);
603#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
604 gpu->copy_dip_fld_to_host(particles,
this_node);
607#ifdef ESPRESSO_CALIPER
613#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
614 if (propagation->used_propagations &
620#ifdef ESPRESSO_VIRTUAL_SITES_CENTER_OF_MASS
621 if (propagation->used_propagations &
632 assert(comfixed->get_fixed_types().empty() &&
633 "ghost_reduce_overlap: comfixed must be inactive on the eligible "
636 "ghost_reduce_overlap: force_cap must be 0 on the eligible path");
637 cell_structure->ghosts_reduce_forces_start();
640 cell_structure->ghosts_reduce_forces();
641#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
642 if (dipoles.impl->solver.has_value()) {
643 cell_structure->ghosts_reduce_dipole_field();
648 comfixed->apply(particles);
655 propagation->recalc_forces =
false;
@ INTEG_METHOD_STEEPEST_DESCENT
@ INTEG_METHOD_SYMPLECTIC_EULER
Vector implementation and trait types for boost qvm interoperability.
Zero-overhead Caliper guards for the inactive (no CALI_CONFIG) case.
#define ESPRESSO_CALI_MARK_END(name)
Guarded CALI_MARK_END — no-op when inactive.
#define ESPRESSO_CALI_MARK_BEGIN(name)
Guarded CALI_MARK_BEGIN — no-op when inactive.
#define ESPRESSO_CALI_MARK_FUNCTION
Guarded drop-in replacement for CALI_CXX_MARK_FUNCTION.
This file contains everything related to the global cell structure / cell system.
double maximal_cutoff() const
Calculate the maximal cutoff of bonded interactions, required to determine the cell size for communic...
Describes a cell structure / cell system.
void for_each_local_particle(ParticleCallback auto &&f, bool parallel=true) const
Run a kernel on all local particles.
Kokkos::Experimental::ScatterView< double *[3], Kokkos::LayoutRight, memory_space > ScatterForce
Cuboid minimum-image fold parameters for hot pair loops.
void calculate_forces()
Calculate all forces.
Returns true if the particles are to be considered for short range interactions.
void vs_com_back_transfer_forces_and_torques(CellStructure &cell_structure)
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
boost::mpi::communicator comm_cart
The communicator.
int this_node
The number of this node.
constexpr double inactive_cutoff
Special cutoff value for an inactive interaction.
const T * get_ptr(std::optional< T > const &opt)
static BondsKernelData create_kokkos_bonds_kernel_data(System::System const &system)
static ShortRangeVerletPairLoop create_specialized_verlet_pair_loop(System::System const &system, Utils::Vector3d const *virial, auto const &elc_kernel, auto const &coulomb_kernel, auto const &dipoles_kernel)
static void reinit_dip_fld(CellStructure const &cell_structure)
static void force_capping(CellStructure &cell_structure, double force_cap)
static ForcesKernel create_cabana_neighbor_kernel(System::System const &system, Utils::Vector3d *virial, auto const &elc_kernel, auto const &coulomb_kernel, auto const &dipoles_kernel, auto const &coulomb_u_kernel)
static ShortRangeVerletPairLoop make_specialized_verlet_pair_loop(InteractionsNonBonded const &nonbonded_ias, CellStructure::AoSoA_pack const &aosoa, CellStructure::ScatterForce scatter_force, CuboidMinimumImage const &minimum_image, double const max_cutoff_sq, Coulomb::ShortRangeForceKernel::kernel_type const *coulomb_ptr=nullptr, CoulombP3M const *p3m=nullptr)
static bool ghost_reduce_overlap_eligible(System::System const &system)
Eligibility check for the split-phase ghost force reduction.
static void reduce_cabana_forces_and_torques(System::System const &system, Utils::Vector3d *virial)
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.
void init_forces_and_thermostat(System::System const &system)
Combined force initialization and Langevin noise application.
Ghost particles and particle exchange.
@ GHOSTTRANS_TORQUE
transfer torque (reduced with force; runtime-conditional)
ICC is a method that allows to take into account the influence of arbitrarily shaped dielectric inter...
@ TRANS_VS_CENTER_OF_MASS
@ TRANS_LB_MOMENTUM_EXCHANGE
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Various procedures concerning interactions between particles.
Exports for the NpT code.
void vs_relative_back_transfer_forces_and_torques(CellStructure &cell_structure)
This file contains all subroutines required to process rotational motion.
void cabana_short_range(auto const &pair_bonds_kernel, auto const &angle_bonds_kernel, auto const &dihedral_bonds_kernel, auto const &nonbonded_kernel, CellStructure &cell_structure, double pair_cutoff, double bond_cutoff, auto const &make_verlet_criterion, auto const integ_switch, ShortRangeVerletPairLoop const &verlet_pair_loop={})
std::function< void(CellStructure::ListType const &, std::size_t)> ShortRangeVerletPairLoop
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION bool gay_berne_active(double dist, IA_parameters const &ia_params)
void update_verlet_state(System::System const &system, double const collision_cut)
BondedInteractionsMap const & bonded_ias
Solver::ShortRangeForceKernel kernel_type
Distance vector and length handed to pair kernels.
BondedInteractionsMap const & bonded_ias
Struct holding all information for one particle.
constexpr auto const & dip_fld() const
constexpr auto const & force() const
Own-the-loop specialization of the non-bonded pair kernel.