193 auto const &unique_particles = system.
cell_structure->get_unique_particles();
194 auto const &local_force = system.
cell_structure->get_local_force();
195#ifdef ESPRESSO_ROTATION
196 auto const &local_torque = system.
cell_structure->get_local_torque();
199 auto const &local_virial = system.
cell_structure->get_local_virial();
202 using execution_space = Kokkos::DefaultExecutionSpace;
203 int num_threads = execution_space().concurrency();
204 Kokkos::RangePolicy<execution_space> policy(std::size_t{0},
205 unique_particles.size());
206 Kokkos::parallel_for(
"reduction", policy,
208#ifdef ESPRESSO_ROTATION
211 &unique_particles, num_threads](std::size_t
const i) {
213#ifdef ESPRESSO_ROTATION
216 for (
int tid = 0; tid < num_threads; ++tid) {
217 force[0] += local_force(i, tid, 0);
218 force[1] += local_force(i, tid, 1);
219 force[2] += local_force(i, tid, 2);
220#ifdef ESPRESSO_ROTATION
221 torque[0] += local_torque(i, tid, 0);
222 torque[1] += local_torque(i, tid, 1);
223 torque[2] += local_torque(i, tid, 2);
226 unique_particles.at(i)->force() += force;
227#ifdef ESPRESSO_ROTATION
228 unique_particles.at(i)->torque() += torque;
235 for (
int tid = 0; tid < num_threads; ++tid) {
236 (*virial)[0] += local_virial(tid, 0);
237 (*virial)[1] += local_virial(tid, 1);
238 (*virial)[2] += local_virial(tid, 2);
246#ifdef ESPRESSO_CALIPER
247 CALI_CXX_MARK_FUNCTION;
251#ifdef ESPRESSO_CALIPER
252 CALI_MARK_BEGIN(
"copy_particles_to_GPU");
255#ifdef ESPRESSO_CALIPER
256 CALI_MARK_END(
"copy_particles_to_GPU");
261#ifdef ESPRESSO_COLLISION_DETECTION
262 collision_detection->clear_queue();
263 auto const collision_detection_cutoff = collision_detection->cutoff();
267 bond_breakage->clear_queue();
268 auto particles = cell_structure->local_particles();
275#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
282 auto const elc_kernel = coulomb.pair_force_elc_kernel();
283 auto const coulomb_kernel = coulomb.pair_force_kernel();
284 auto const dipoles_kernel = dipoles.pair_force_kernel();
285 auto const coulomb_u_kernel = coulomb.pair_energy_kernel();
286 auto *
const virial = get_npt_virial();
289 auto bond_kernel = [coulomb_kernel_ptr =
get_ptr(coulomb_kernel),
290 &bonded_ias = *bonded_ias,
291 &bond_breakage = *bond_breakage, virial,
292 &box_geo = *box_geo](
Particle &p1,
int bond_id,
293 std::span<Particle *> partners) {
295 box_geo, virial, coulomb_kernel_ptr);
299 cell_structure->get_verlet_skin(),
300 get_interaction_range(),
303 collision_detection_cutoff};
305#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
307 get_interaction_range(), propagation->integ_switch);
309#ifdef ESPRESSO_ELECTROSTATICS
310 if (coulomb.impl->extension) {
311 update_icc_particles();
315#ifdef ESPRESSO_CALIPER
316 CALI_MARK_BEGIN(
"calc_long_range_forces");
318#ifdef ESPRESSO_ELECTROSTATICS
319 coulomb.calc_long_range_force();
321#ifdef ESPRESSO_DIPOLES
322 dipoles.calc_long_range_force();
324#ifdef ESPRESSO_CALIPER
325 CALI_MARK_END(
"calc_long_range_forces");
328#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
329#ifdef ESPRESSO_CALIPER
330 CALI_MARK_BEGIN(
"cabana_short_range");
333 auto first_neighbor_kernel =
335 dipoles_kernel, coulomb_u_kernel);
338 get_interaction_range(), bonded_ias->maximal_cutoff(),
339 verlet_criterion, propagation->integ_switch);
344#ifdef ESPRESSO_COLLISION_DETECTION
345 auto collision_kernel = [&collision_detection = *collision_detection](
348 collision_detection.detect_collision(p1, p2, d.dist2);
350 if (not collision_detection->is_off()) {
351 cell_structure->non_bonded_loop(collision_kernel, verlet_criterion);
355#ifdef ESPRESSO_CALIPER
356 CALI_MARK_END(
"cabana_short_range");
361#ifdef ESPRESSO_CALIPER
362 CALI_MARK_BEGIN(
"serial_short_range");
365 auto pair_kernel = [coulomb_kernel_ptr =
get_ptr(coulomb_kernel),
366 dipoles_kernel_ptr =
get_ptr(dipoles_kernel),
367 elc_kernel_ptr =
get_ptr(elc_kernel),
368 coulomb_u_kernel_ptr =
get_ptr(coulomb_u_kernel),
369 &nonbonded_ias = *nonbonded_ias,
370 &thermostat = *thermostat, &bonded_ias = *bonded_ias,
372#ifdef ESPRESSO_COLLISION_DETECTION
373 &collision_detection = *collision_detection,
377 auto const &ia_params = nonbonded_ias.get_ia_param(p1.type(), p2.type());
379 p1, p2, d.vec21, sqrt(d.dist2), d.dist2, p1.q() * p2.q(), ia_params,
380 thermostat, box_geo, bonded_ias, virial, coulomb_kernel_ptr,
381 dipoles_kernel_ptr, elc_kernel_ptr, coulomb_u_kernel_ptr);
382#ifdef ESPRESSO_COLLISION_DETECTION
383 if (not collision_detection.is_off()) {
384 collision_detection.detect_collision(p1, p2, d.dist2);
389 short_range_loop(bond_kernel, pair_kernel, *cell_structure, maximal_cutoff(),
390 bonded_ias->maximal_cutoff(), verlet_criterion);
392#ifdef ESPRESSO_CALIPER
393 CALI_MARK_END(
"serial_short_range");
398 constraints->add_forces(particles, get_sim_time());
399 oif_global->calculate_forces();
402 immersed_boundaries->volume_conservation(*cell_structure);
404 if (thermostat->lb and (propagation->used_propagations &
406#ifdef ESPRESSO_CALIPER
407 CALI_MARK_BEGIN(
"lb_particle_coupling");
409 lb_couple_particles();
410#ifdef ESPRESSO_CALIPER
411 CALI_MARK_END(
"lb_particle_coupling");
417#ifdef ESPRESSO_CALIPER
418 CALI_MARK_BEGIN(
"copy_forces_from_GPU");
420 gpu.copy_forces_to_host(particles,
this_node);
422#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
423 gpu.copy_dip_fld_to_host(particles,
this_node);
426#ifdef ESPRESSO_CALIPER
427 CALI_MARK_END(
"copy_forces_from_GPU");
432#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
433 if (propagation->used_propagations &
439#ifdef ESPRESSO_VIRTUAL_SITES_CENTER_OF_MASS
440 if (propagation->used_propagations &
447 cell_structure->ghosts_reduce_forces();
450 comfixed->apply(particles);
456 propagation->recalc_forces =
false;
void add_non_bonded_pair_force(Particle &p1, Particle &p2, Utils::Vector3d const &d, double dist, double dist2, double q1q2, IA_parameters const &ia_params, Thermostat::Thermostat const &thermostat, BoxGeometry const &box_geo, BondedInteractionsMap const &bonded_ias, Utils::Vector3d *const virial, 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)
Calculate non-bonded forces between a pair of particles and update their forces and torques.
Force information on a particle.
Struct holding all information for one particle.