Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
forces.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010
4 * Max-Planck-Institute for Polymer Research, Theory Group
5 *
6 * This file is part of ESPResSo.
7 *
8 * ESPResSo is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * ESPResSo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21/** \file
22 * Force calculation.
23 *
24 * The corresponding header file is forces.hpp.
25 */
26
27#include "BoxGeometry.hpp"
28#include "Particle.hpp"
29#include "ParticleRange.hpp"
30#include "PropagationMode.hpp"
33#include "cells.hpp"
34#include "collision_detection/CollisionDetection.hpp"
35#include "communication.hpp"
36#include "constraints/Constraints.hpp"
38#include "forces_inline.hpp"
39#include "galilei/ComFixed.hpp"
46#include "npt.hpp"
47#include "rotation.hpp"
48#include "short_range_loop.hpp"
49#include "system/System.hpp"
50#include "thermostat.hpp"
52
53#include <utils/Vector.hpp>
54#include <utils/math/sqr.hpp>
55
56#include <boost/variant.hpp>
57
58#ifdef CALIPER
59#include <caliper/cali.h>
60#endif
61
62#include <cassert>
63#include <cmath>
64#include <memory>
65#include <span>
66#include <variant>
67
68/** External particle forces */
70 ParticleForce f = {};
71
72#ifdef EXTERNAL_FORCES
73 f.f += p.ext_force();
74#ifdef ROTATION
75 f.torque += p.ext_torque();
76#endif
77#endif
78
79#ifdef ENGINE
80 // apply a swimming force in the direction of
81 // the particle's orientation axis
82 if (p.swimming().swimming and !p.swimming().is_engine_force_on_fluid) {
83 f.f += p.swimming().f_swim * p.calc_director();
84 }
85#endif
86
87 return f;
88}
89
90void init_forces(const CellStructure &cell_structure) {
91#ifdef CALIPER
92 CALI_CXX_MARK_FUNCTION;
93#endif
94
95 cell_structure.for_each_local_particle(
96 [](Particle &p) { p.force_and_torque() = external_force(p); });
97
98 init_forces_ghosts(cell_structure);
99}
100
101void init_forces_ghosts(const CellStructure &cell_structure) {
102 cell_structure.for_each_ghost_particle(
103 [](Particle &p) { p.force_and_torque() = {}; });
104}
105
106static void force_capping(CellStructure &cell_structure, double force_cap) {
107 if (force_cap > 0.) {
108 auto const force_cap_sq = Utils::sqr(force_cap);
109 cell_structure.for_each_local_particle(
110 [&force_cap, &force_cap_sq](Particle &p) {
111 auto const force_sq = p.force().norm2();
112 if (force_sq > force_cap_sq) {
113 p.force() *= force_cap / std::sqrt(force_sq);
114 }
115 });
116 }
117}
118
120#ifdef CALIPER
121 CALI_CXX_MARK_FUNCTION;
122#endif
123#ifdef CUDA
124#ifdef CALIPER
125 CALI_MARK_BEGIN("copy_particles_to_GPU");
126#endif
127 gpu.update();
128#ifdef CALIPER
129 CALI_MARK_END("copy_particles_to_GPU");
130#endif
131#endif // CUDA
132
133#ifdef COLLISION_DETECTION
134 collision_detection->clear_queue();
135#endif
136 bond_breakage->clear_queue();
137 auto particles = cell_structure->local_particles();
138#ifdef ELECTROSTATICS
139 if (coulomb.impl->extension) {
140 if (auto icc = std::get_if<std::shared_ptr<ICCStar>>(
141 get_ptr(coulomb.impl->extension))) {
142 auto ghost_particles = cell_structure->ghost_particles();
143 (**icc).iteration(*cell_structure, particles, ghost_particles);
144 }
145 }
146#endif // ELECTROSTATICS
147#ifdef NPT
148 if (propagation->used_propagations & PropagationMode::TRANS_LANGEVIN_NPT) {
149 // reset virial part of instantaneous pressure
150 npt_inst_pressure->p_vir = Utils::Vector3d{};
151 }
152#endif
153 init_forces(*cell_structure);
154 thermostat_force_init();
155
156 calc_long_range_forces(particles);
157
158 auto const elc_kernel = coulomb.pair_force_elc_kernel();
159 auto const coulomb_kernel = coulomb.pair_force_kernel();
160 auto const dipoles_kernel = dipoles.pair_force_kernel();
161
162#ifdef ELECTROSTATICS
163 auto const coulomb_cutoff = coulomb.cutoff();
164#else
165 auto const coulomb_cutoff = INACTIVE_CUTOFF;
166#endif
167
168#ifdef DIPOLES
169 auto const dipole_cutoff = dipoles.cutoff();
170#else
171 auto const dipole_cutoff = INACTIVE_CUTOFF;
172#endif
173#ifdef COLLISION_DETECTION
174 auto const collision_detection_cutoff = collision_detection->cutoff();
175#else
176 auto const collision_detection_cutoff = INACTIVE_CUTOFF;
177#endif
178
180 [coulomb_kernel_ptr = get_ptr(coulomb_kernel), &bonded_ias = *bonded_ias,
181 &bond_breakage = *bond_breakage, &box_geo = *box_geo](
182 Particle &p1, int bond_id, std::span<Particle *> partners) {
183 return add_bonded_force(p1, bond_id, partners, bonded_ias,
184 bond_breakage, box_geo, coulomb_kernel_ptr);
185 },
186 [coulomb_kernel_ptr = get_ptr(coulomb_kernel),
187 dipoles_kernel_ptr = get_ptr(dipoles_kernel),
188 elc_kernel_ptr = get_ptr(elc_kernel), &nonbonded_ias = *nonbonded_ias,
189 &thermostat = *thermostat, &bonded_ias = *bonded_ias,
190#ifdef COLLISION_DETECTION
191 &collision_detection = *collision_detection,
192#endif
193 &box_geo = *box_geo](Particle &p1, Particle &p2, Distance const &d) {
194 auto const &ia_params =
195 nonbonded_ias.get_ia_param(p1.type(), p2.type());
196 add_non_bonded_pair_force(p1, p2, d.vec21, sqrt(d.dist2), d.dist2,
197 ia_params, thermostat, box_geo, bonded_ias,
198 coulomb_kernel_ptr, dipoles_kernel_ptr,
199 elc_kernel_ptr);
200#ifdef COLLISION_DETECTION
201 if (not collision_detection.is_off()) {
202 collision_detection.detect_collision(p1, p2, d.dist2);
203 }
204#endif
205 },
206 *cell_structure, maximal_cutoff(), bonded_ias->maximal_cutoff(),
207 VerletCriterion<>{*this, cell_structure->get_verlet_skin(),
208 get_interaction_range(), coulomb_cutoff, dipole_cutoff,
209 collision_detection_cutoff});
210
211 constraints->add_forces(particles, get_sim_time());
212 oif_global->calculate_forces();
213
214 // Must be done here. Forces need to be ghost-communicated
215 immersed_boundaries->volume_conservation(*cell_structure);
216
217 if (thermostat->lb and (propagation->used_propagations &
219 lb_couple_particles();
220 }
221
222#ifdef CUDA
223#ifdef CALIPER
224 CALI_MARK_BEGIN("copy_forces_from_GPU");
225#endif
226 gpu.copy_forces_to_host(particles, this_node);
227#ifdef CALIPER
228 CALI_MARK_END("copy_forces_from_GPU");
229#endif
230#endif // CUDA
231
232#ifdef VIRTUAL_SITES_RELATIVE
233 if (propagation->used_propagations &
236 }
237#endif
238
239 // Communication step: ghost forces
240 cell_structure->ghosts_reduce_forces();
241
242 // should be pretty late, since it needs to zero out the total force
243 comfixed->apply(particles);
244
245 // Needs to be the last one to be effective
246 force_capping(*cell_structure, force_cap);
247
248 // mark that forces are now up-to-date
249 propagation->recalc_forces = false;
250}
251
252void calc_long_range_forces(const ParticleRange &particles) {
253#ifdef CALIPER
254 CALI_CXX_MARK_FUNCTION;
255#endif
256
257#ifdef ELECTROSTATICS
258 /* calculate k-space part of electrostatic interaction. */
260#endif // ELECTROSTATICS
261
262#ifdef DIPOLES
263 /* calculate k-space part of the magnetostatic interaction. */
265#endif // DIPOLES
266}
267
268#ifdef NPT
273#endif
Vector implementation and trait types for boost qvm interoperability.
This file contains everything related to the global cell structure / cell system.
A range of particles.
void npt_add_virial_contribution(double energy)
Definition npt.cpp:122
void calculate_forces()
Calculate all forces.
Definition forces.cpp:119
Returns true if the particles are to be considered for short range interactions.
int this_node
The number of this node.
const T * get_ptr(std::optional< T > const &opt)
static void force_capping(CellStructure &cell_structure, double force_cap)
Definition forces.cpp:106
void init_forces_ghosts(const CellStructure &cell_structure)
Set forces of all ghosts to zero.
Definition forces.cpp:101
static ParticleForce external_force(Particle const &p)
External particle forces.
Definition forces.cpp:69
void init_forces(const CellStructure &cell_structure)
Assign external forces/torques to real particles and zero to ghosts.
Definition forces.cpp:90
void npt_add_virial_force_contribution(const Utils::Vector3d &force, const Utils::Vector3d &d)
Update the NpT virial.
Definition forces.cpp:269
void calc_long_range_forces(const ParticleRange &particles)
Calculate long range forces (P3M, ...).
Definition forces.cpp:252
Force calculation.
void add_non_bonded_pair_force(Particle &p1, Particle &p2, Utils::Vector3d const &d, double dist, double dist2, IA_parameters const &ia_params, Thermostat::Thermostat const &thermostat, BoxGeometry const &box_geo, BondedInteractionsMap const &bonded_ias, Coulomb::ShortRangeForceKernel::kernel_type const *coulomb_kernel, Dipoles::ShortRangeForceKernel::kernel_type const *dipoles_kernel, Coulomb::ShortRangeForceCorrectionsKernel::kernel_type const *elc_kernel)
Calculate non-bonded forces between a pair of particles and update their forces and torques.
bool add_bonded_force(Particle &p1, int bond_id, std::span< Particle * > partners, BondedInteractionsMap const &bonded_ia_params, BondBreakage::BondBreakage &bond_breakage, BoxGeometry const &box_geo, Coulomb::ShortRangeForceKernel::kernel_type const *kernel)
ICC is a method that allows to take into account the influence of arbitrarily shaped dielectric inter...
Solver const & get_coulomb()
Definition coulomb.cpp:66
Solver const & get_dipoles()
Definition dipoles.cpp:49
System & get_system()
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
Various procedures concerning interactions between particles.
constexpr double INACTIVE_CUTOFF
Cutoff for deactivated interactions.
Exports for the NpT code.
void vs_relative_back_transfer_forces_and_torques(CellStructure &cell_structure)
Definition relative.cpp:165
This file contains all subroutines required to process rotational motion.
void short_range_loop(BondKernel bond_kernel, PairKernel pair_kernel, CellStructure &cell_structure, double pair_cutoff, double bond_cutoff, VerletCriterion const &verlet_criterion={})
Describes a cell structure / cell system.
void for_each_local_particle(Kernel f) const
Run a kernel on all local particles.
void for_each_ghost_particle(Kernel f) const
Run a kernel on all ghost particles.
void calc_long_range_force(ParticleRange const &particles) const
Definition coulomb.cpp:256
void calc_long_range_force(ParticleRange const &particles) const
Definition dipoles.cpp:199
Distance vector and length handed to pair kernels.
Force information on a particle.
Definition Particle.hpp:290
Utils::Vector3d torque
torque.
Definition Particle.hpp:320
Utils::Vector3d f
force.
Definition Particle.hpp:316
Struct holding all information for one particle.
Definition Particle.hpp:395
auto const & swimming() const
Definition Particle.hpp:561
auto const & force_and_torque() const
Definition Particle.hpp:437
auto const & ext_force() const
Definition Particle.hpp:554
auto const & type() const
Definition Particle.hpp:418
auto const & ext_torque() const
Definition Particle.hpp:484
auto const & force() const
Definition Particle.hpp:435
auto calc_director() const
Definition Particle.hpp:487