Loading [MathJax]/extensions/tex2jax.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
rattle.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
22#include "rattle.hpp"
23
24#ifdef BOND_CONSTRAINT
25
26#include "BoxGeometry.hpp"
27#include "Particle.hpp"
28#include "ParticleRange.hpp"
32#include "communication.hpp"
33#include "errorhandling.hpp"
34
35#include <boost/mpi/collectives/all_reduce.hpp>
36#include <boost/range/algorithm.hpp>
37
38#include <cmath>
39#include <functional>
40#include <span>
41
42static void check_convergence(int cnt, char const *const name) {
43 static constexpr char const *const msg = " failed to converge after ";
44 if (cnt >= SHAKE_MAX_ITERATIONS) {
45 runtimeErrorMsg() << name << msg << cnt << " iterations";
46 }
47}
48
49/**
50 * @brief copy current position
51 *
52 * @param particles particle range
53 * @param ghost_particles ghost particle range
54 */
55void save_old_position(const ParticleRange &particles,
56 const ParticleRange &ghost_particles) {
57 auto save_pos = [](Particle &p) { p.pos_last_time_step() = p.pos(); };
58
59 boost::for_each(particles, save_pos);
60 boost::for_each(ghost_particles, save_pos);
61}
62
63/**
64 * @brief reset correction vectors to zero
65 *
66 * @param particles particle range
67 * @param ghost_particles ghost particle range
68 */
69static void init_correction_vector(const ParticleRange &particles,
70 const ParticleRange &ghost_particles) {
71 auto reset_force = [](Particle &p) { p.rattle_params().correction.fill(0); };
72
73 boost::for_each(particles, reset_force);
74 boost::for_each(ghost_particles, reset_force);
75}
76
77/**
78 * @brief Calculate the positional correction for the particles.
79 *
80 * @param ia_params Parameters
81 * @param box_geo Box geometry.
82 * @param p1 First particle.
83 * @param p2 Second particle.
84 * @return True if there was a correction.
85 */
86static bool calculate_positional_correction(RigidBond const &ia_params,
87 BoxGeometry const &box_geo,
88 Particle &p1, Particle &p2) {
89 auto const r_ij = box_geo.get_mi_vector(p1.pos(), p2.pos());
90 auto const r_ij2 = r_ij.norm2();
91
92 if (std::abs(1.0 - r_ij2 / ia_params.d2) > ia_params.p_tol) {
93 auto const r_ij_t =
95 auto const r_ij_dot = r_ij_t * r_ij;
96 auto const G =
97 0.50 * (ia_params.d2 - r_ij2) / r_ij_dot / (p1.mass() + p2.mass());
98
99 auto const pos_corr = G * r_ij_t;
100 p1.rattle_params().correction += pos_corr * p2.mass();
101 p2.rattle_params().correction -= pos_corr * p1.mass();
102
103 return true;
104 }
105
106 return false;
107}
108
109/**
110 * @brief Compute the correction vectors using given kernel.
111 *
112 * @param cs cell structure
113 * @param box_geo Box geometry
114 * @param bonded_ias Bonded interactions
115 * @param kernel kernel function
116 * @return True if correction is necessary
117 */
118template <typename Kernel>
120 BoxGeometry const &box_geo,
121 BondedInteractionsMap const &bonded_ias,
122 Kernel kernel) {
123 bool correction = false;
124 cs.bond_loop([&correction, &kernel, &box_geo, &bonded_ias](
125 Particle &p1, int bond_id, std::span<Particle *> partners) {
126 auto const &iaparams = *bonded_ias.at(bond_id);
127
128 if (auto const *bond = boost::get<RigidBond>(&iaparams)) {
129 auto const corrected = kernel(*bond, box_geo, p1, *partners[0]);
130 if (corrected)
131 correction = true;
132 }
133
134 /* Rigid bonds cannot break */
135 return false;
136 });
137
138 return correction;
139}
140
141/**
142 * @brief Apply positional corrections
143 *
144 * @param particles particle range
145 */
146static void apply_positional_correction(const ParticleRange &particles) {
147 boost::for_each(particles, [](Particle &p) {
148 p.pos() += p.rattle_params().correction;
149 p.v() += p.rattle_params().correction;
150 });
151}
152
154 BondedInteractionsMap const &bonded_ias) {
157
158 auto particles = cs.local_particles();
159 auto ghost_particles = cs.ghost_particles();
160
161 int cnt;
162 for (cnt = 0; cnt < SHAKE_MAX_ITERATIONS; ++cnt) {
163 init_correction_vector(particles, ghost_particles);
164 bool const repeat_ = compute_correction_vector(
165 cs, box_geo, bonded_ias, calculate_positional_correction);
166 bool const repeat =
167 boost::mpi::all_reduce(comm_cart, repeat_, std::logical_or<bool>());
168
169 // no correction is necessary, skip communication and bail out
170 if (!repeat)
171 break;
172
174
177 }
178 check_convergence(cnt, "RATTLE");
179
180 auto const resort_level =
182 cs.set_resort_particles(resort_level);
183}
184
185/**
186 * @brief Calculate the velocity correction for the particles.
187 *
188 * The position correction is accumulated in the forces
189 * of the particles so that it can be reduced over the ghosts.
190 *
191 * @param ia_params Parameters
192 * @param box_geo Box geometry.
193 * @param p1 First particle.
194 * @param p2 Second particle.
195 * @return True if there was a correction.
196 */
197static bool calculate_velocity_correction(RigidBond const &ia_params,
198 BoxGeometry const &box_geo,
199 Particle &p1, Particle &p2) {
200 auto const v_ij = p1.v() - p2.v();
201 auto const r_ij = box_geo.get_mi_vector(p1.pos(), p2.pos());
202
203 auto const v_proj = v_ij * r_ij;
204 if (std::abs(v_proj) > ia_params.v_tol) {
205 auto const K = v_proj / ia_params.d2 / (p1.mass() + p2.mass());
206
207 auto const vel_corr = K * r_ij;
208
209 p1.rattle_params().correction -= vel_corr * p2.mass();
210 p2.rattle_params().correction += vel_corr * p1.mass();
211
212 return true;
213 }
214
215 return false;
216}
217
218/**
219 * @brief Apply velocity corrections
220 *
221 * @param particles particle range
222 */
223static void apply_velocity_correction(ParticleRange const &particles) {
224 boost::for_each(particles,
225 [](Particle &p) { p.v() += p.rattle_params().correction; });
226}
227
229 BondedInteractionsMap const &bonded_ias) {
231
232 auto particles = cs.local_particles();
233 auto ghost_particles = cs.ghost_particles();
234
235 int cnt;
236 for (cnt = 0; cnt < SHAKE_MAX_ITERATIONS; ++cnt) {
237 init_correction_vector(particles, ghost_particles);
238 bool const repeat_ = compute_correction_vector(
239 cs, box_geo, bonded_ias, calculate_velocity_correction);
240 bool const repeat =
241 boost::mpi::all_reduce(comm_cart, repeat_, std::logical_or<bool>());
242
243 // no correction is necessary, skip communication and bail out
244 if (!repeat)
245 break;
246
248
249 apply_velocity_correction(particles);
251 }
252 check_convergence(cnt, "VEL RATTLE");
253}
254
255#endif
Data structures for bonded interactions.
container for bonded interactions.
mapped_type at(key_type const &key) const
Utils::Vector< T, 3 > get_mi_vector(const Utils::Vector< T, 3 > &a, const Utils::Vector< T, 3 > &b) const
Get the minimum-image vector between two coordinates.
A range of particles.
boost::mpi::communicator comm_cart
The communicator.
#define SHAKE_MAX_ITERATIONS
Maximal number of iterations in the RATTLE algorithm before it bails out.
Definition config.hpp:88
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
#define runtimeErrorMsg()
@ DATA_PART_MOMENTUM
Particle::m.
@ DATA_PART_PROPERTIES
Particle::p.
@ DATA_PART_POSITION
Particle::r.
void correct_velocity_shake(CellStructure &cs, BoxGeometry const &box_geo, BondedInteractionsMap const &bonded_ias)
Correction of current velocities using RATTLE algorithm.
Definition rattle.cpp:228
void save_old_position(const ParticleRange &particles, const ParticleRange &ghost_particles)
copy current position
Definition rattle.cpp:55
void correct_position_shake(CellStructure &cs, BoxGeometry const &box_geo, BondedInteractionsMap const &bonded_ias)
Propagate velocity and position while using SHAKE algorithm for bond constraint.
Definition rattle.cpp:153
static void init_correction_vector(const ParticleRange &particles, const ParticleRange &ghost_particles)
reset correction vectors to zero
Definition rattle.cpp:69
static void apply_positional_correction(const ParticleRange &particles)
Apply positional corrections.
Definition rattle.cpp:146
static bool calculate_velocity_correction(RigidBond const &ia_params, BoxGeometry const &box_geo, Particle &p1, Particle &p2)
Calculate the velocity correction for the particles.
Definition rattle.cpp:197
static void check_convergence(int cnt, char const *const name)
Definition rattle.cpp:42
static void apply_velocity_correction(ParticleRange const &particles)
Apply velocity corrections.
Definition rattle.cpp:223
static bool compute_correction_vector(CellStructure &cs, BoxGeometry const &box_geo, BondedInteractionsMap const &bonded_ias, Kernel kernel)
Compute the correction vectors using given kernel.
Definition rattle.cpp:119
static bool calculate_positional_correction(RigidBond const &ia_params, BoxGeometry const &box_geo, Particle &p1, Particle &p2)
Calculate the positional correction for the particles.
Definition rattle.cpp:86
RATTLE algorithm ().
Definition of the rigid bond data type for the Rattle algorithm.
Describes a cell structure / cell system.
ParticleRange ghost_particles() const
void update_ghosts_and_resort_particle(unsigned data_parts)
Update ghost particles, with particle resort if needed.
void ghosts_update(unsigned data_parts)
Update ghost particles.
bool check_resort_required(Utils::Vector3d const &additional_offset={}) const
Check whether a particle has moved further than half the skin since the last Verlet list update,...
void bond_loop(BondKernel const &bond_kernel)
Bonded pair loop.
void set_resort_particles(Cells::Resort level)
Increase the local resort level at least to level.
ParticleRange local_particles() const
void ghosts_reduce_rattle_correction()
Add rattle corrections from ghost particles to real particles.
Struct holding all information for one particle.
Definition Particle.hpp:395
auto const & rattle_params() const
Definition Particle.hpp:567
auto const & mass() const
Definition Particle.hpp:452
auto const & pos_last_time_step() const
Definition Particle.hpp:565
auto const & v() const
Definition Particle.hpp:433
auto const & pos() const
Definition Particle.hpp:431
Parameters for the rigid_bond/SHAKE/RATTLE ALGORITHM.
double d2
Square of the length of Constrained Bond.
double v_tol
Velocity Tolerance/Accuracy for termination of RATTLE/SHAKE iterations during velocity corrections.
double p_tol
Positional Tolerance/Accuracy value for termination of RATTLE/SHAKE iterations during position correc...