ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
dpd.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2025 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 * Implementation of dpd.hpp.
23 */
24#include <config/config.hpp>
25
26#ifdef ESPRESSO_DPD
27
28#include "dpd.hpp"
29
30#include "BoxGeometry.hpp"
32#include "cells.hpp"
34#include "random.hpp"
35#include "system/System.hpp"
36#include "thermostat.hpp"
37
38#include <utils/Vector.hpp>
39#include <utils/math/sqr.hpp>
41#include <utils/matrix.hpp>
42
43#include <boost/mpi/collectives/reduce.hpp>
44
45#include <algorithm>
46#include <cmath>
47#include <cstdint>
48#include <functional>
49
50/** Return a random uniform 3D vector with the Philox thermostat.
51 * Random numbers depend on
52 * 1. dpd_rng_counter (initialized by seed) which is increased on integration
53 * 2. Salt (decorrelates different counters)
54 * 3. Two particle IDs (order-independent, decorrelates particles, gets rid of
55 * seed-per-node)
56 */
57static Utils::Vector3d dpd_noise(DPDThermostat const &dpd, int pid1, int pid2) {
58 auto const pref = (pid1 < pid2) ? 1.0 : -1.0;
59 return pref * Random::noise_uniform<RNGSalt::SALT_DPD>(
60 dpd.rng_counter(), dpd.rng_seed(),
61 (pid1 < pid2) ? pid2 : pid1, (pid1 < pid2) ? pid1 : pid2);
62}
63
64void InteractionsNonBonded::dpd_init(double kT, double time_step) {
65 auto const max_type = get_max_seen_particle_type();
66 for (int type_a = 0; type_a <= max_type; type_a++) {
67 for (int type_b = type_a; type_b <= max_type; type_b++) {
68 auto &ia_params = get_ia_param(type_a, type_b);
69
70 ia_params.dpd.radial.pref =
71 sqrt(24.0 * kT * ia_params.dpd.radial.gamma / time_step);
72 ia_params.dpd.trans.pref =
73 sqrt(24.0 * kT * ia_params.dpd.trans.gamma / time_step);
74 }
75 }
76}
77
80 Utils::Vector3d const &p1_velocity, int const &p1_id,
81 Utils::Vector3d const &p2_position,
82 Utils::Vector3d const &p2_velocity, int const &p2_id,
83 DPDThermostat const &dpd, BoxGeometry const &box_geo,
84 IA_parameters const &ia_params, Utils::Vector3d const &d,
85 double dist, double dist2) {
86 if (ia_params.dpd.radial.cutoff <= 0.0 && ia_params.dpd.trans.cutoff <= 0.0) {
87 return {};
88 }
89
90 auto const v21 = box_geo.velocity_difference(p1_position, p2_position,
91 p1_velocity, p2_velocity);
92 auto const noise_vec =
93 (ia_params.dpd.radial.pref > 0.0 || ia_params.dpd.trans.pref > 0.0)
94 ? dpd_noise(dpd, p1_id, p2_id)
96
97 auto const f_r = dpd_pair_force(ia_params.dpd.radial, v21, dist, noise_vec);
98 auto const f_t = dpd_pair_force(ia_params.dpd.trans, v21, dist, noise_vec);
99
100 /* Projection operator to radial direction */
101 auto const P = tensor_product(d / dist2, d);
102 /* This is equivalent to P * f_r + (1 - P) * f_t, but with
103 * doing only one matrix-vector multiplication */
104 auto const force = P * (f_r - f_t) + f_t;
105 return force;
106}
107
109 auto const &box_geo = *system.box_geo;
110 auto const &nonbonded_ias = *system.nonbonded_ias;
111 auto &cell_structure = *system.cell_structure;
112 system.on_observable_calc();
113
115 cell_structure.non_bonded_loop([&stress, &box_geo, &nonbonded_ias](
116 Particle const &p1, Particle const &p2,
117 Distance const &d) {
118 auto const v21 =
119 box_geo.velocity_difference(p1.pos(), p2.pos(), p1.v(), p2.v());
120
121 auto const &ia_params = nonbonded_ias.get_ia_param(p1.type(), p2.type());
122 auto const dist = std::sqrt(d.dist2);
123
124 auto const f_r = dpd_pair_force(ia_params.dpd.radial, v21, dist, {});
125 auto const f_t = dpd_pair_force(ia_params.dpd.trans, v21, dist, {});
126
127 /* Projection operator to radial direction */
128 auto const P = tensor_product(d.vec21 / d.dist2, d.vec21);
129 /* This is equivalent to P * f_r + (1 - P) * f_t, but with
130 * doing only one matrix-vector multiplication */
131 auto const f = P * (f_r - f_t) + f_t;
132
133 stress += tensor_product(d.vec21, f);
134 });
135
136 return stress;
137}
138
140 auto const local_stress = dpd_viscous_stress_local(system);
141 return -Utils::flatten(local_stress);
142}
143
144/**
145 * @brief Viscous stress tensor of the DPD interaction.
146 *
147 * This calculates the total viscous stress contribution of the
148 * DPD interaction. It contains only the dissipative contributions
149 * of the interaction without noise. It's calculated as the
150 * sum over all pair virials as
151 * \f[
152 * \sigma^{\nu\mu} = V^{-1}\sum_i \sum_{j < i} r_{i,j}^{\nu} (- \gamma_{i,j}
153 * v_{i,j})^{\mu} \f] where \f$\gamma_{i,j}\f$ is the (in general tensor valued)
154 * DPD friction coefficient for particles i and j, \f$v_{i,j}\f$, \f$r_{i,j}\f$
155 * are their relative velocity and distance and \f$V\f$ is the box volume.
156 *
157 * @return Stress tensor contribution.
158 */
160 boost::mpi::communicator const &comm) {
161 auto const local_stress = dpd_viscous_stress_local(system);
162 std::remove_const_t<decltype(local_stress)> global_stress{};
163
164 boost::mpi::reduce(comm, local_stress, global_stress, std::plus<>(), 0);
165
166 return Utils::flatten(global_stress) / system.box_geo->volume();
167}
168
169#endif // ESPRESSO_DPD
Vector implementation and trait types for boost qvm interoperability.
This file contains everything related to the global cell structure / cell system.
Utils::Vector3d velocity_difference(Utils::Vector3d const &x, Utils::Vector3d const &y, Utils::Vector3d const &u, Utils::Vector3d const &v) const
Calculate the velocity difference including the Lees-Edwards velocity.
void dpd_init(double kT, double time_step)
Definition dpd.cpp:64
auto & get_ia_param(int i, int j)
Get interaction parameters between particle types i and j.
Main system class.
void on_observable_calc()
called before calculating observables, i.e.
std::shared_ptr< CellStructure > cell_structure
std::shared_ptr< BoxGeometry > box_geo
std::shared_ptr< InteractionsNonBonded > nonbonded_ias
static auto dpd_viscous_stress_local(System::System &system)
Definition dpd.cpp:108
Utils::Vector9d dpd_stress(System::System &system, boost::mpi::communicator const &comm)
Viscous stress tensor of the DPD interaction.
Definition dpd.cpp:159
Utils::Vector3d dpd_pair_force(Utils::Vector3d const &p1_position, Utils::Vector3d const &p1_velocity, int const &p1_id, Utils::Vector3d const &p2_position, Utils::Vector3d const &p2_velocity, int const &p2_id, DPDThermostat const &dpd, BoxGeometry const &box_geo, IA_parameters const &ia_params, Utils::Vector3d const &d, double dist, double dist2)
Definition dpd.cpp:79
Utils::Vector9d dpd_pressure_local(System::System &system)
Local contribution to the pressure tensor.
Definition dpd.cpp:139
static Utils::Vector3d dpd_noise(DPDThermostat const &dpd, int pid1, int pid2)
Return a random uniform 3D vector with the Philox thermostat.
Definition dpd.cpp:57
Routines to use DPD as thermostat or pair force .
Matrix implementation and trait types for boost qvm interoperability.
void flatten(Range const &v, OutputIterator out)
Flatten a range of ranges.
Definition flatten.hpp:56
Various procedures concerning interactions between particles.
Random number generation using Philox.
uint64_t rng_counter() const
Get current value of the RNG.
uint32_t rng_seed() const
Thermostat for dissipative particle dynamics.
Distance vector and length handed to pair kernels.
Utils::Vector3d vec21
Parameters for non-bonded interactions.
Struct holding all information for one particle.
Definition Particle.hpp:450
auto const & v() const
Definition Particle.hpp:488
auto const & type() const
Definition Particle.hpp:473
auto const & pos() const
Definition Particle.hpp:486
Matrix representation with static size.
Definition matrix.hpp:65