196 auto const &unique_particles = system.
cell_structure->get_unique_particles();
197 auto const &local_force = system.
cell_structure->get_local_force();
198#ifdef ESPRESSO_ROTATION
199 auto const &local_torque = system.
cell_structure->get_local_torque();
202 auto const &local_virial = system.
cell_structure->get_local_virial();
205 using execution_space = Kokkos::DefaultExecutionSpace;
206 int num_threads = execution_space().concurrency();
207 Kokkos::RangePolicy<execution_space> policy(std::size_t{0},
208 unique_particles.size());
209 Kokkos::parallel_for(
"reduction", policy,
211#ifdef ESPRESSO_ROTATION
214 &unique_particles, num_threads](std::size_t
const i) {
216#ifdef ESPRESSO_ROTATION
219 for (
int tid = 0; tid < num_threads; ++tid) {
220 force[0] += local_force(i, tid, 0);
221 force[1] += local_force(i, tid, 1);
222 force[2] += local_force(i, tid, 2);
223#ifdef ESPRESSO_ROTATION
224 torque[0] += local_torque(i, tid, 0);
225 torque[1] += local_torque(i, tid, 1);
226 torque[2] += local_torque(i, tid, 2);
229 unique_particles.at(i)->force() += force;
230#ifdef ESPRESSO_ROTATION
231 unique_particles.at(i)->torque() += torque;
238 for (
int tid = 0; tid < num_threads; ++tid) {
239 (*virial)[0] += local_virial(tid, 0);
240 (*virial)[1] += local_virial(tid, 1);
241 (*virial)[2] += local_virial(tid, 2);
249#ifdef ESPRESSO_CALIPER
250 CALI_CXX_MARK_FUNCTION;
254#ifdef ESPRESSO_CALIPER
255 CALI_MARK_BEGIN(
"copy_particles_to_GPU");
258#ifdef ESPRESSO_CALIPER
259 CALI_MARK_END(
"copy_particles_to_GPU");
264#ifdef ESPRESSO_COLLISION_DETECTION
265 collision_detection->clear_queue();
266 auto const collision_detection_cutoff = collision_detection->cutoff();
270 bond_breakage->clear_queue();
271 auto particles = cell_structure->local_particles();
278#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
285 auto const elc_kernel = coulomb.pair_force_elc_kernel();
286 auto const coulomb_kernel = coulomb.pair_force_kernel();
287 auto const dipoles_kernel = dipoles.pair_force_kernel();
288 auto const coulomb_u_kernel = coulomb.pair_energy_kernel();
289 auto *
const virial = get_npt_virial();
292 auto bond_kernel = [coulomb_kernel_ptr =
get_ptr(coulomb_kernel),
293 &bonded_ias = *bonded_ias,
294 &bond_breakage = *bond_breakage, virial,
295 &box_geo = *box_geo](
Particle &p1,
int bond_id,
296 std::span<Particle *> partners) {
298 box_geo, virial, coulomb_kernel_ptr);
302 cell_structure->get_verlet_skin(),
303 get_interaction_range(),
306 collision_detection_cutoff};
308#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
310 get_interaction_range(), propagation->integ_switch);
312#ifdef ESPRESSO_ELECTROSTATICS
313 if (coulomb.impl->extension) {
314 update_icc_particles();
318#ifdef ESPRESSO_CALIPER
319 CALI_MARK_BEGIN(
"calc_long_range_forces");
321#ifdef ESPRESSO_ELECTROSTATICS
322 coulomb.calc_long_range_force();
324#ifdef ESPRESSO_DIPOLES
325 dipoles.calc_long_range_force();
327#ifdef ESPRESSO_CALIPER
328 CALI_MARK_END(
"calc_long_range_forces");
331#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
332#ifdef ESPRESSO_CALIPER
333 CALI_MARK_BEGIN(
"cabana_short_range");
336 auto first_neighbor_kernel =
338 dipoles_kernel, coulomb_u_kernel);
341 get_interaction_range(), bonded_ias->maximal_cutoff(),
342 verlet_criterion, propagation->integ_switch);
347#ifdef ESPRESSO_COLLISION_DETECTION
348 auto collision_kernel = [&collision_detection = *collision_detection](
351 collision_detection.detect_collision(p1, p2, d.dist2);
353 if (not collision_detection->is_off()) {
354 cell_structure->non_bonded_loop(collision_kernel, verlet_criterion);
358#ifdef ESPRESSO_CALIPER
359 CALI_MARK_END(
"cabana_short_range");
364#ifdef ESPRESSO_CALIPER
365 CALI_MARK_BEGIN(
"serial_short_range");
368 auto pair_kernel = [coulomb_kernel_ptr =
get_ptr(coulomb_kernel),
369 dipoles_kernel_ptr =
get_ptr(dipoles_kernel),
370 elc_kernel_ptr =
get_ptr(elc_kernel),
371 coulomb_u_kernel_ptr =
get_ptr(coulomb_u_kernel),
372 &nonbonded_ias = *nonbonded_ias,
373 &thermostat = *thermostat, &bonded_ias = *bonded_ias,
375#ifdef ESPRESSO_COLLISION_DETECTION
376 &collision_detection = *collision_detection,
379 system_max_cutoff2 =
Utils::sqr(maximal_cutoff())](
381 if (d.dist2 > system_max_cutoff2)
383 auto const &ia_params = nonbonded_ias.get_ia_param(p1.type(), p2.type());
385 p1, p2, d.vec21, sqrt(d.dist2), d.dist2, p1.q() * p2.q(), ia_params,
386 thermostat, box_geo, bonded_ias, virial, coulomb_kernel_ptr,
387 dipoles_kernel_ptr, elc_kernel_ptr, coulomb_u_kernel_ptr);
388#ifdef ESPRESSO_COLLISION_DETECTION
389 if (not collision_detection.is_off()) {
390 collision_detection.detect_collision(p1, p2, d.dist2);
395 short_range_loop(bond_kernel, pair_kernel, *cell_structure, maximal_cutoff(),
396 bonded_ias->maximal_cutoff(), verlet_criterion);
398#ifdef ESPRESSO_CALIPER
399 CALI_MARK_END(
"serial_short_range");
404 constraints->add_forces(particles, get_sim_time());
405 oif_global->calculate_forces();
408 immersed_boundaries->volume_conservation(*cell_structure);
410 if (thermostat->lb and (propagation->used_propagations &
412#ifdef ESPRESSO_CALIPER
413 CALI_MARK_BEGIN(
"lb_particle_coupling");
415 lb_couple_particles();
416#ifdef ESPRESSO_CALIPER
417 CALI_MARK_END(
"lb_particle_coupling");
423#ifdef ESPRESSO_CALIPER
424 CALI_MARK_BEGIN(
"copy_forces_from_GPU");
426 gpu->copy_forces_to_host(particles,
this_node);
428#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
429 gpu->copy_dip_fld_to_host(particles,
this_node);
432#ifdef ESPRESSO_CALIPER
433 CALI_MARK_END(
"copy_forces_from_GPU");
438#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
439 if (propagation->used_propagations &
445#ifdef ESPRESSO_VIRTUAL_SITES_CENTER_OF_MASS
446 if (propagation->used_propagations &
453 cell_structure->ghosts_reduce_forces();
456 comfixed->apply(particles);
462 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.