166#ifdef ESPRESSO_CALIPER
167 CALI_CXX_MARK_FUNCTION;
171#ifdef ESPRESSO_CALIPER
172 CALI_MARK_BEGIN(
"copy_particles_to_GPU");
175#ifdef ESPRESSO_CALIPER
176 CALI_MARK_END(
"copy_particles_to_GPU");
181#ifdef ESPRESSO_COLLISION_DETECTION
182 collision_detection->clear_queue();
183 auto const collision_detection_cutoff = collision_detection->cutoff();
187 bond_breakage->clear_queue();
188 auto particles = cell_structure->local_particles();
195#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
202 auto const elc_kernel = coulomb.pair_force_elc_kernel();
203 auto const coulomb_kernel = coulomb.pair_force_kernel();
204 auto const dipoles_kernel = dipoles.pair_force_kernel();
205 auto const coulomb_u_kernel = coulomb.pair_energy_kernel();
206 auto *
const virial = get_npt_virial();
209 auto bond_kernel = [coulomb_kernel_ptr =
get_ptr(coulomb_kernel),
210 &bonded_ias = *bonded_ias,
211 &bond_breakage = *bond_breakage, virial,
212 &box_geo = *box_geo](
Particle &p1,
int bond_id,
213 std::span<Particle *> partners) {
215 box_geo, virial, coulomb_kernel_ptr);
219 cell_structure->get_verlet_skin(),
220 get_interaction_range(),
223 collision_detection_cutoff};
225#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
227 get_interaction_range(), propagation->integ_switch);
229#ifdef ESPRESSO_ELECTROSTATICS
230 if (coulomb.impl->extension) {
231 update_icc_particles();
237#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
238#ifdef ESPRESSO_CALIPER
239 CALI_MARK_BEGIN(
"cabana_short_range");
241 using execution_space = Kokkos::DefaultExecutionSpace;
242 auto const &unique_particles = cell_structure->get_unique_particles();
243 auto const &local_force = cell_structure->get_local_force();
244#ifdef ESPRESSO_ROTATION
245 auto const &local_torque = cell_structure->get_local_torque();
248 auto const &local_virial = cell_structure->get_local_virial();
250 auto const &aosoa = cell_structure->get_aosoa();
253 *bonded_ias, *nonbonded_ias,
get_ptr(coulomb_kernel),
255 *thermostat, *box_geo, unique_particles, local_force,
256#ifdef ESPRESSO_ROTATION
260 virial, local_virial,
265 get_interaction_range(), bonded_ias->maximal_cutoff(),
266 verlet_criterion, propagation->integ_switch);
268 int num_threads = execution_space().concurrency();
269 Kokkos::RangePolicy<execution_space> policy(std::size_t{0},
270 unique_particles.size());
271 Kokkos::parallel_for(
"reduction", policy,
273#ifdef ESPRESSO_ROTATION
276 &unique_particles, num_threads](std::size_t
const i) {
278#ifdef ESPRESSO_ROTATION
281 for (
int tid = 0; tid < num_threads; ++tid) {
282 force[0] += local_force(i, tid, 0);
283 force[1] += local_force(i, tid, 1);
284 force[2] += local_force(i, tid, 2);
285#ifdef ESPRESSO_ROTATION
286 torque[0] += local_torque(i, tid, 0);
287 torque[1] += local_torque(i, tid, 1);
288 torque[2] += local_torque(i, tid, 2);
291 unique_particles.at(i)->force() += force;
292#ifdef ESPRESSO_ROTATION
293 unique_particles.at(i)->torque() += torque;
300 for (
int tid = 0; tid < num_threads; ++tid) {
301 (*virial)[0] += local_virial(tid, 0);
302 (*virial)[1] += local_virial(tid, 1);
303 (*virial)[2] += local_virial(tid, 2);
308#ifdef ESPRESSO_COLLISION_DETECTION
309 auto collision_kernel = [&collision_detection = *collision_detection](
312 collision_detection.detect_collision(p1, p2, d.dist2);
314 if (not collision_detection->is_off()) {
315 cell_structure->non_bonded_loop(collision_kernel, verlet_criterion);
319#ifdef ESPRESSO_CALIPER
320 CALI_MARK_END(
"cabana_short_range");
325#ifdef ESPRESSO_CALIPER
326 CALI_MARK_BEGIN(
"serial_short_range");
329 auto pair_kernel = [coulomb_kernel_ptr =
get_ptr(coulomb_kernel),
330 dipoles_kernel_ptr =
get_ptr(dipoles_kernel),
331 elc_kernel_ptr =
get_ptr(elc_kernel),
332 coulomb_u_kernel_ptr =
get_ptr(coulomb_u_kernel),
333 &nonbonded_ias = *nonbonded_ias,
334 &thermostat = *thermostat, &bonded_ias = *bonded_ias,
336#ifdef ESPRESSO_COLLISION_DETECTION
337 &collision_detection = *collision_detection,
341 auto const &ia_params = nonbonded_ias.get_ia_param(p1.type(), p2.type());
343 p1, p2, d.vec21, sqrt(d.dist2), d.dist2, p1.q() * p2.q(), ia_params,
344 thermostat, box_geo, bonded_ias, virial, coulomb_kernel_ptr,
345 dipoles_kernel_ptr, elc_kernel_ptr, coulomb_u_kernel_ptr);
346#ifdef ESPRESSO_COLLISION_DETECTION
347 if (not collision_detection.is_off()) {
348 collision_detection.detect_collision(p1, p2, d.dist2);
353 short_range_loop(bond_kernel, pair_kernel, *cell_structure, maximal_cutoff(),
354 bonded_ias->maximal_cutoff(), verlet_criterion);
356#ifdef ESPRESSO_CALIPER
357 CALI_MARK_END(
"serial_short_range");
362 constraints->add_forces(particles, get_sim_time());
363 oif_global->calculate_forces();
366 immersed_boundaries->volume_conservation(*cell_structure);
368 if (thermostat->lb and (propagation->used_propagations &
370#ifdef ESPRESSO_CALIPER
371 CALI_MARK_BEGIN(
"lb_particle_coupling");
373 lb_couple_particles();
374#ifdef ESPRESSO_CALIPER
375 CALI_MARK_END(
"lb_particle_coupling");
381#ifdef ESPRESSO_CALIPER
382 CALI_MARK_BEGIN(
"copy_forces_from_GPU");
384 gpu.copy_forces_to_host(particles,
this_node);
386#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
387 gpu.copy_dip_fld_to_host(particles,
this_node);
390#ifdef ESPRESSO_CALIPER
391 CALI_MARK_END(
"copy_forces_from_GPU");
396#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
397 if (propagation->used_propagations &
403#ifdef ESPRESSO_VIRTUAL_SITES_CENTER_OF_MASS
404 if (propagation->used_propagations &
411 cell_structure->ghosts_reduce_forces();
414 comfixed->apply(particles);
420 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.