ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
velocity_verlet_npt_MTK.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "config/config.hpp"
21
22#ifdef ESPRESSO_NPT
24
25#include "BoxGeometry.hpp"
26#include "Particle.hpp"
27#include "ParticleRange.hpp"
29#include "communication.hpp"
30#include "errorhandling.hpp"
32
33#include <utils/Vector.hpp>
34
35#include <boost/mpi/collectives.hpp>
36
37#include <cmath>
38#include <functional>
39
40static constexpr Utils::Vector3i nptgeom_dir{{1, 2, 4}};
41
42/**
43 * @brief Scale and communicate instantaneous NpT pressure and
44 * propagate the conjugate momentum for volume.
45 * @f$ p_{\epsilon}(t+dt) = p_{\epsilon}(t)
46 * + 3 V (P_{\text{inst}} - P_{\text{ext}}) dt / 2 @f$
47 */
48static void
50 InstantaneousPressure &npt_inst_pressure,
51 double time_step) {
52 /* finalize derivation of p_inst */
53 npt_inst_pressure.p_inst = {0., 0.};
54
55 for (auto i = 0u; i < 3u; ++i) {
57 npt_inst_pressure.p_inst[0] +=
58 npt_inst_pressure.p_vir[i] + npt_inst_pressure.p_vel[i];
59 npt_inst_pressure.p_inst[1] += npt_inst_pressure.p_vir[i];
60 }
61 }
62
63 Utils::Vector2d p_sum = {0., 0.};
64 boost::mpi::reduce(::comm_cart, npt_inst_pressure.p_inst, p_sum,
65 std::plus<Utils::Vector2d>(), 0);
66
67 /* propagate p_epsilon */
68 if (::this_node == 0) {
69 npt_inst_pressure.p_inst = p_sum / (nptiso.dimension * nptiso.volume);
70 nptiso.p_epsilon += nptiso.volume *
71 (npt_inst_pressure.p_inst[0] - nptiso.p_ext) * 1.5 *
72 time_step;
73 if (nptiso.particle_number > 1) {
74 nptiso.p_epsilon +=
75 (p_sum[0] - p_sum[1]) *
76 (0.5 / static_cast<double>(nptiso.particle_number - 1)) * time_step;
77 }
78 }
79 boost::mpi::broadcast(::comm_cart, nptiso.p_epsilon, 0);
80}
81
82/* propagate positions with dt/2;
83 * @f$ pos[t+0.5*dt] = pos[t] + vel[t+0.5*dt] * 0.5 * dt @f$
84 */
86 double time_step) {
87 for (auto &p : particles) {
88 for (auto j = 0u; j < 3u; ++j) {
89 if (!p.is_fixed_along(j)) {
90 p.pos()[j] = p.pos()[j] + p.v()[j] * 0.5 * time_step;
91 }
92 }
93 }
94}
95
96/* rescaling positions based on MTK equation;
97 * @f$ pos[t] = \exp(0.5 * dt * p_{\epsilon} / W) * pos[t] @f$
98 */
99static void
101 ParticleRangeNPT const &particles) {
102 auto const propagator =
103 std::exp(nptiso.half_dt_inv_piston * nptiso.p_epsilon);
104
105 for (auto &p : particles) {
106 for (auto j = 0u; j < 3u; ++j) {
107 if (!p.is_fixed_along(j)) {
108 if (nptiso.geometry & NptIsoParameters::nptgeom_dir[j]) {
109 p.pos()[j] *= propagator;
110 }
111 }
112 }
113 }
114}
115
116/**
117 * @brief propagete positions and the volume and add thermal fluctuation.
118 * A and V are the position and volume propagators for half-time step.
119 * O is the propagator corresponding to Ornstein-Uhlenbeck process
120 * representing the stochastic thermostat.
121 * The time evolution follows the sequence A-V-O-V-A in this function,
122 * with propagators applied right to left.
123 */
125 ParticleRangeNPT const &particles, IsotropicNptThermostat const &npt_iso,
126 double time_step, System::System &system) {
127
128 auto &box_geo = *system.box_geo;
129 auto &cell_structure = *system.cell_structure;
130 auto &nptiso = *system.nptiso;
131 double L_new = 0.0;
132
133 /* 1st propagation pos_MTK and pos*/
134 velocity_verlet_npt_propagate_pos_MTK(nptiso, particles);
135 velocity_verlet_npt_propagate_pos(particles, time_step);
136
137 /* stochastic reservoirs for conjugate momentum for particles
138 * @f$ p(t+0.5*dt) = p(t+0.5*dt) \exp(- \gamma_0 dt / m)
139 * + \sqrt{k_B T (1 - \exp(-2 \gamma_0 dt)}N(0,1) @f$
140 */
141 for (auto &p : particles) {
142 auto const v_therm =
143 propagate_therm0_nptiso(npt_iso, p.v(), p.mass(), p.id());
144 for (unsigned int j = 0; j < 3; j++) {
145 if (!p.is_fixed_along(j)) {
146 if (nptiso.geometry & NptIsoParameters::nptgeom_dir[j]) {
147 p.v()[j] = v_therm[j];
148 }
149 }
150 }
151 }
152
153 /* 1st propagatation Volume with dt/2
154 * @f$ V(t+0.5*dt) = \exp(0.5 * dt * 3 * p_{\epsilon} / W) * V(t) @f$,
155 * stochastic reservoirs for conjugate momentum for V
156 * @f$ p_{\epsilon} = p_{epsilon}(t) \exp(- \gamma_V dt / W)
157 * + \sqrt{k_B T (1 - \exp(-2 \gamma_V dt / W)}N(0,1) @f$,
158 * 2nd propagatation Volume with dt/2
159 * @f$ V(t+dt) = \exp(0.5 * dt * 3 * p_{\epsilon} / W) * V(t+0.5*dt) @f$,
160 */
161 if (::this_node == 0) {
162 nptiso.volume *=
163 std::exp(1.5 * nptiso.inv_piston * nptiso.p_epsilon * time_step);
164 nptiso.p_epsilon = propagate_thermV_nptiso(npt_iso, nptiso.p_epsilon);
165 nptiso.volume *=
166 std::exp(1.5 * nptiso.inv_piston * nptiso.p_epsilon * time_step);
167 L_new = pow(nptiso.volume, 1.0 / nptiso.dimension);
168 }
169
170 /* 2nd propagation pos and pos_MTK*/
171 velocity_verlet_npt_propagate_pos(particles, time_step);
172 velocity_verlet_npt_propagate_pos_MTK(nptiso, particles);
173
174 cell_structure.set_resort_particles(Cells::RESORT_LOCAL);
175
176 /* Apply new volume to the box-length, communicate it, and account for
177 * necessary adjustments to the cell geometry */
178 Utils::Vector3d new_box;
179
180 if (::this_node == 0) {
181 new_box = box_geo.length();
182 for (auto i = 0u; i < 3u; ++i) {
183 if (nptiso.cubic_box ||
184 nptiso.geometry & NptIsoParameters::nptgeom_dir[i]) {
185 new_box[i] = L_new;
186 }
187 }
188 }
189
190 boost::mpi::broadcast(::comm_cart, new_box, 0);
191
192 box_geo.set_length(new_box);
193 // fast box length update
194 system.on_boxl_change(true);
195}
196
197/* rescaling momentum based on MTK equation;
198 * @f$ vel[t] = \exp(-0.5 * dt * p_{\epsilon} * (1 + 1 / (N - 1)) / W) * vel[t]
199 * @f$
200 */
201static void
203 InstantaneousPressure &npt_inst_pressure,
204 ParticleRangeNPT const &particles) {
205 npt_inst_pressure.p_vel = {};
206 auto const propagater =
207 std::exp(nptiso.half_dt_inv_piston_and_Nf * nptiso.p_epsilon);
208
209 for (auto &p : particles) {
210 for (auto j = 0u; j < 3u; ++j) {
211 if (!p.is_fixed_along(j)) {
212 if (nptiso.geometry & ::nptgeom_dir[j]) {
213 p.v()[j] *= propagater;
214 npt_inst_pressure.p_vel[j] += Utils::sqr(p.v()[j]) * p.mass();
215 }
216 }
217 }
218 }
219}
220
222 IsotropicNptThermostat const &npt_iso,
223 double time_step, System::System &system) {
224 auto &nptiso = *system.nptiso;
225 auto &npt_inst_pressure = *system.npt_inst_pressure;
226 velocity_verlet_npt_propagate_vel_MTK(nptiso, npt_inst_pressure, particles);
227 velocity_verlet_npt_propagate_p_eps(nptiso, npt_inst_pressure, time_step);
228 velocity_verlet_npt_propagate_vel(nptiso, npt_inst_pressure, particles,
229 time_step);
230 velocity_verlet_npt_propagate_AVOVA_MTK(particles, npt_iso, time_step,
231 system);
232}
233
235 double time_step, System::System &system) {
236 auto &nptiso = *system.nptiso;
237 auto &npt_inst_pressure = *system.npt_inst_pressure;
238 velocity_verlet_npt_propagate_vel(nptiso, npt_inst_pressure, particles,
239 time_step);
240 velocity_verlet_npt_propagate_p_eps(nptiso, npt_inst_pressure, time_step);
241 velocity_verlet_npt_propagate_vel_MTK(nptiso, npt_inst_pressure, particles);
242}
243
244#endif // ESPRESSO_NPT
Vector implementation and trait types for boost qvm interoperability.
Main system class.
void on_boxl_change(bool skip_method_adaption=false)
Called when the box length has changed.
std::shared_ptr< InstantaneousPressure > npt_inst_pressure
std::shared_ptr< NptIsoParameters > nptiso
std::shared_ptr< CellStructure > cell_structure
std::shared_ptr< BoxGeometry > box_geo
boost::mpi::communicator comm_cart
The communicator.
int this_node
The number of this node.
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
double propagate_thermV_nptiso(IsotropicNptThermostat const &npt_iso, double p_epsilon)
Added noise and friction for NpT-sims to NptIsoParameters::p_epsilon; .
Utils::Vector3d propagate_therm0_nptiso(IsotropicNptThermostat const &npt_iso, Utils::Vector3d const &vel, double mass, int p_identity)
Add velocity-dependent noise and friction for NpT-sims to the particle's velocity; .
Instantaneous pressure during force calculation for NPT integration.
Definition npt.hpp:92
Utils::Vector3d p_vel
ideal gas components of p_inst, derived from the velocities
Definition npt.hpp:99
Utils::Vector3d p_vir
virial (short-range) components of p_inst
Definition npt.hpp:97
Utils::Vector2d p_inst
instantaneous pressure for p_inst[0] and virial pressure for p_inst[1] the system currently has
Definition npt.hpp:95
Thermostat for isotropic NPT dynamics.
Parameters of the isotropic NpT-integration scheme.
Definition npt.hpp:42
std::size_t particle_number
number of particles
Definition npt.hpp:57
int geometry
geometry information for the NpT integrator.
Definition npt.hpp:72
static constexpr std::array< int, 3 > nptgeom_dir
Definition npt.hpp:88
double half_dt_inv_piston_and_Nf
the coefficient of propagater of momentum for MTK equation
Definition npt.hpp:65
double half_dt_inv_piston
the coefficient of propagater of position for MTK equation
Definition npt.hpp:63
double p_ext
desired pressure to which the algorithm strives to
Definition npt.hpp:59
int dimension
The number of dimensions in which NpT boxlength motion is coupled to particles.
Definition npt.hpp:75
double p_epsilon
conjugate momentum of volume
Definition npt.hpp:61
double volume
isotropic volume.
Definition npt.hpp:53
void velocity_verlet_npt_propagate_vel(NptIsoParameters const &nptiso, InstantaneousPressure &npt_inst_pressure, ParticleRangeNPT const &particles, double time_step)
Propagate the particle's velocity.
void velocity_verlet_npt_MTK_step_1(ParticleRangeNPT const &particles, IsotropicNptThermostat const &npt_iso, double time_step, System::System &system)
Special propagator for NpT isotropic for MTK approach.
static void velocity_verlet_npt_propagate_vel_MTK(NptIsoParameters const &nptiso, InstantaneousPressure &npt_inst_pressure, ParticleRangeNPT const &particles)
static void velocity_verlet_npt_propagate_p_eps(NptIsoParameters &nptiso, InstantaneousPressure &npt_inst_pressure, double time_step)
Scale and communicate instantaneous NpT pressure and propagate the conjugate momentum for volume.
static void velocity_verlet_npt_propagate_AVOVA_MTK(ParticleRangeNPT const &particles, IsotropicNptThermostat const &npt_iso, double time_step, System::System &system)
propagete positions and the volume and add thermal fluctuation.
static void velocity_verlet_npt_propagate_pos_MTK(NptIsoParameters &nptiso, ParticleRangeNPT const &particles)
static constexpr Utils::Vector3i nptgeom_dir
void velocity_verlet_npt_MTK_step_2(ParticleRangeNPT const &particles, double time_step, System::System &system)
Final integration step of the Velocity Verlet+NpT integrator for Andersen method.
static void velocity_verlet_npt_propagate_pos(ParticleRangeNPT const &particles, double time_step)