ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
nonbonded_interaction_data.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2026 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#pragma once
23
24/** \file
25 * Various procedures concerning interactions between particles.
26 */
27
28#include <config/config.hpp>
29
31#include "system/Leaf.hpp"
32
34#include <utils/index.hpp>
36
37#include <algorithm>
38#include <cassert>
39#include <cmath>
40#include <memory>
41#include <vector>
42
43/** Lennard-Jones with shift */
45 double eps = 0.0;
46 double sig = 0.0;
48 double shift = 0.0;
49 double offset = 0.0;
50 double min = 0.0;
51 LJ_Parameters() = default;
52 LJ_Parameters(double epsilon, double sigma, double cutoff, double offset,
53 double min, double shift);
54 double get_auto_shift() const {
55 auto auto_shift = 0.;
56 if (cut != 0.) {
57 auto_shift = Utils::int_pow<6>(sig / cut) - Utils::int_pow<12>(sig / cut);
58 }
59 return auto_shift;
60 }
61 double max_cutoff() const { return cut + offset; }
62 double min_cutoff() const { return min + offset; }
63};
64
65/** WCA potential */
67 double eps = 0.0;
68 double sig = 0.0;
70 WCA_Parameters() = default;
71 WCA_Parameters(double epsilon, double sigma);
72 double max_cutoff() const { return cut; }
73};
74
75/** Generic Lennard-Jones with shift */
77 double eps = 0.0;
78 double sig = 0.0;
80 double shift = 0.0;
81 double offset = 0.0;
82 double lambda = 1.0;
83 double softrad = 0.0;
84 double a1 = 0.0;
85 double a2 = 0.0;
86 double b1 = 0.0;
87 double b2 = 0.0;
88 LJGen_Parameters() = default;
89 LJGen_Parameters(double epsilon, double sigma, double cutoff, double shift,
90 double offset,
92 double lam, double delta,
93#endif
94 double e1, double e2, double b1, double b2);
95 double get_auto_shift() const {
96 auto auto_shift = 0.;
97 if (cut != 0.) {
98 auto_shift = b2 * std::pow(sig / cut, a2) - b1 * std::pow(sig / cut, a1);
99 }
100 return auto_shift;
101 }
102 double max_cutoff() const { return cut + offset; }
103};
104
105/** smooth step potential */
107 double eps = 0.0;
108 double sig = 0.0;
110 double d = 0.0;
111 int n = 0;
112 double k0 = 0.0;
114 SmoothStep_Parameters(double eps, double sig, double cutoff, double d, int n,
115 double k0);
116 double max_cutoff() const { return cut; }
117};
118
119/** Hertzian potential */
121 double eps = 0.0;
124 Hertzian_Parameters(double eps, double sig);
125 double max_cutoff() const { return sig; }
126};
127
128/** Gaussian potential */
130 double eps = 0.0;
131 double sig = 1.0;
134 Gaussian_Parameters(double eps, double sig, double cutoff);
135 double max_cutoff() const { return cut; }
136};
137
138/** BMHTF NaCl potential */
140 double A = 0.0;
141 double B = 0.0;
142 double C = 0.0;
143 double D = 0.0;
144 double sig = 0.0;
146 double computed_shift = 0.0;
147 BMHTF_Parameters() = default;
148 BMHTF_Parameters(double A, double B, double C, double D, double sig,
149 double cut);
150 double max_cutoff() const { return cut; }
151};
152
153/** Morse potential */
155 double eps = 0.;
160 Morse_Parameters() = default;
161 Morse_Parameters(double eps, double alpha, double rmin, double cutoff);
162 double max_cutoff() const { return cut; }
163};
164
165/** Buckingham potential */
167 double A = 0.0;
168 double B = 0.0;
169 double C = 0.0;
170 double D = 0.0;
172 double discont = 0.0;
173 double shift = 0.0;
174 double F1 = 0.0;
175 double F2 = 0.0;
177 Buckingham_Parameters(double a, double b, double c, double d, double cutoff,
178 double discont, double shift);
179 double max_cutoff() const { return cut; }
180};
181
182/** soft-sphere potential */
184 double a = 0.0;
185 double n = 0.0;
187 double offset = 0.0;
189 SoftSphere_Parameters(double a, double n, double cutoff, double offset);
190 double max_cutoff() const { return cut + offset; }
191};
192
193/** hat potential */
195 double Fmax = 0.0;
197 Hat_Parameters() = default;
198 Hat_Parameters(double F_max, double cutoff);
199 double max_cutoff() const { return r; }
200};
201
202/** Lennard-Jones+Cos potential */
204 double eps = 0.0;
205 double sig = 0.0;
207 double offset = 0.0;
208 double alfa = 0.0;
209 double beta = 0.0;
210 double rmin = 0.0;
211 LJcos_Parameters() = default;
212 LJcos_Parameters(double epsilon, double sigma, double cutoff, double offset);
213 double max_cutoff() const { return cut + offset; }
214};
215
216/** Lennard-Jones with a different Cos potential */
218 double eps = 0.0;
219 double sig = 0.0;
221 double offset = 0.0;
222 double w = 0.0;
223 double rchange = 0.0;
224 LJcos2_Parameters() = default;
225 LJcos2_Parameters(double epsilon, double sigma, double offset, double width);
226 double max_cutoff() const { return cut + offset; }
227};
228
229/** Gay-Berne potential */
231 double eps = 0.0;
232 double sig = 0.0;
234 double k1 = 0.0;
235 double k2 = 0.0;
236 double mu = 0.0;
237 double nu = 0.0;
238 double chi1 = 0.0;
239 double chi2 = 0.0;
241 GayBerne_Parameters(double eps, double sig, double cut, double k1, double k2,
242 double mu, double nu);
243 double max_cutoff() const { return cut; }
244};
245
246/** Thole potential */
248 double scaling_coeff = 0.; // inactive cutoff is 0
249 double q1q2 = 0.;
250 Thole_Parameters() = default;
253};
254
255/** DPD potential */
257 double gamma = 0.;
258 double k = 1.;
260 int wf = 0;
261 double pref = 0.0;
262};
263
267 DPD_Parameters() = default;
268 DPD_Parameters(double gamma, double k, double r_c, int wf, double tgamma,
269 double tr_c, int twf) {
270 radial = DPDParameters{gamma, k, r_c, wf, -1.};
271 trans = DPDParameters{tgamma, k, tr_c, twf, -1.};
272 }
273 double max_cutoff() const { return std::max(radial.cutoff, trans.cutoff); }
274};
275
276/** @brief Bit positions in IA_parameters::active_pair_mask.
277 *
278 * Each enumerator corresponds to one short-range pair potential
279 * (central-radial, orientation-dependent, or thermostat-coupled)
280 * configurable per type pair. A bit is set iff the potential's own
281 * cutoff / activation guard could possibly fire for this type pair
282 * (i.e. it is not in its default/inactive state). Populated
283 * exclusively by InteractionsNonBonded::recalc_maximal_cutoffs() —
284 * never set elsewhere, so it cannot drift from max_cut.
285 */
286enum class PairPotential : unsigned {
287 LennardJones = 0,
288 WCA,
291 Hertzian,
292 Gaussian,
293 BMHTF,
295 Morse,
297 Hat,
298 LJCos,
299 LJCos2,
300 Tabulated,
301 GayBerne,
302 DPD,
303};
304
305/** @brief Bitmask for a pair potential. */
307 return 1u << static_cast<unsigned>(p);
308}
309
310/** @brief Parameters for non-bonded interactions. */
312 /** maximal cutoff for this pair of particle types. This contains
313 * contributions from the short-ranged interactions, plus any
314 * cutoffs from global interactions like electrostatics.
315 */
317
318 /** Bitmask of pair potentials active for this type pair.
319 * See PairPotential. Derived, do not set directly.
320 */
321 unsigned active_pair_mask = 0u;
322
323#ifdef ESPRESSO_LENNARD_JONES
325#endif
326
327#ifdef ESPRESSO_WCA
329#endif
330
331#ifdef ESPRESSO_LENNARD_JONES_GENERIC
333#endif
334
335#ifdef ESPRESSO_SMOOTH_STEP
337#endif
338
339#ifdef ESPRESSO_HERTZIAN
341#endif
342
343#ifdef ESPRESSO_GAUSSIAN
345#endif
346
347#ifdef ESPRESSO_BMHTF_NACL
349#endif
350
351#ifdef ESPRESSO_MORSE
353#endif
354
355#ifdef ESPRESSO_BUCKINGHAM
357#endif
358
359#ifdef ESPRESSO_SOFT_SPHERE
361#endif
362
363#ifdef ESPRESSO_HAT
365#endif
366
367#ifdef ESPRESSO_LJCOS
369#endif
370
371#ifdef ESPRESSO_LJCOS2
373#endif
374
375#ifdef ESPRESSO_GAY_BERNE
377#endif
378
379#ifdef ESPRESSO_TABULATED
381#endif
382
383#ifdef ESPRESSO_DPD
385#endif
386
387#ifdef ESPRESSO_THOLE
389#endif
390};
391
392class InteractionsNonBonded : public System::Leaf<InteractionsNonBonded> {
393 /** @brief List of pairwise interactions. */
394 std::vector<std::shared_ptr<IA_parameters>> m_nonbonded_ia_params{};
395 /** @brief Maximal particle type seen so far. */
396 int max_seen_particle_type = -1;
397
398 void realloc_ia_params(int type) {
399 assert(type >= 0);
400 auto const old_size = m_nonbonded_ia_params.size();
401 m_nonbonded_ia_params.resize(Utils::lower_triangular(type, type) + 1);
402 auto const new_size = m_nonbonded_ia_params.size();
403 if (new_size > old_size) {
404 for (auto &data : m_nonbonded_ia_params) {
405 if (data == nullptr) {
406 data = std::make_shared<IA_parameters>();
407 }
408 }
409 }
410 }
411
412public:
414 /* make sure interaction 0<->0 always exists */
416 }
417
418 /**
419 * @brief Make sure the interaction parameter list is large enough to cover
420 * interactions for this particle type.
421 * New interactions are initialized with values such that no physical
422 * interaction occurs.
423 */
425 assert(type >= 0);
426 if (type > max_seen_particle_type) {
427 realloc_ia_params(type);
428 max_seen_particle_type = type;
429 }
430 }
431
432 auto get_ia_param_key(int i, int j) const {
433 assert(i >= 0 and i <= max_seen_particle_type);
434 assert(j >= 0 and j <= max_seen_particle_type);
435 auto const key = static_cast<unsigned int>(
436 Utils::lower_triangular(std::max(i, j), std::min(i, j)));
437 assert(key < m_nonbonded_ia_params.size());
438 return key;
439 }
440
441 /**
442 * @brief Get interaction parameters between particle types i and j
443 *
444 * This is symmetric, e.g. it holds that `get_ia_param(i, j)` and
445 * `get_ia_param(j, i)` point to the same data.
446 *
447 * @param i First type, must exist
448 * @param j Second type, must exist
449 *
450 * @return Reference to interaction parameters for the type pair.
451 */
452 auto &get_ia_param(int i, int j) {
453 return *m_nonbonded_ia_params[get_ia_param_key(i, j)];
454 }
455
456 auto const &get_ia_param(int i, int j) const {
457 return *m_nonbonded_ia_params[get_ia_param_key(i, j)];
458 }
459
460 auto get_ia_param_ref_counted(int i, int j) const {
461 return m_nonbonded_ia_params[get_ia_param_key(i, j)];
462 }
463
464 void set_ia_param(int i, int j, std::shared_ptr<IA_parameters> const &ia) {
465 m_nonbonded_ia_params[get_ia_param_key(i, j)] = ia;
466 }
467
468 auto get_max_seen_particle_type() const { return max_seen_particle_type; }
469
470 /** @brief Recalculate cutoff of each interaction struct. */
472
473 /** @brief Get maximal cutoff. */
474 double maximal_cutoff() const;
475
476 /** @brief Notify system that non-bonded interactions changed. */
477 void on_non_bonded_ia_change() const;
478
479#ifdef ESPRESSO_DPD
480 void dpd_init(double kT, double time_step);
481#endif
482};
auto get_ia_param_ref_counted(int i, int j) const
auto get_ia_param_key(int i, int j) const
void set_ia_param(int i, int j, std::shared_ptr< IA_parameters > const &ia)
auto const & get_ia_param(int i, int j) const
void dpd_init(double kT, double time_step)
Definition dpd.cpp:61
void recalc_maximal_cutoffs()
Recalculate cutoff of each interaction struct.
void on_non_bonded_ia_change() const
Notify system that non-bonded interactions changed.
double maximal_cutoff() const
Get maximal cutoff.
auto & get_ia_param(int i, int j)
Get interaction parameters between particle types i and j.
void make_particle_type_exist(int type)
Make sure the interaction parameter list is large enough to cover interactions for this particle type...
Abstract class that represents a component of the system.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
constexpr double inactive_cutoff
Special cutoff value for an inactive interaction.
Definition config.hpp:53
#define DEVICE_QUALIFIER
DEVICE_QUALIFIER T lower_triangular(T i, T j)
Linear index into a lower triangular matrix.
Definition index.hpp:86
PairPotential
Bit positions in IA_parameters::active_pair_mask.
constexpr DEVICE_QUALIFIER unsigned pair_potential_bit(PairPotential p)
Bitmask for a pair potential.
BMHTF_Parameters()=default
Buckingham_Parameters()=default
DPD_Parameters()=default
DPD_Parameters(double gamma, double k, double r_c, int wf, double tgamma, double tr_c, int twf)
Gaussian_Parameters()=default
GayBerne_Parameters()=default
Hat_Parameters()=default
Hertzian_Parameters()=default
Parameters for non-bonded interactions.
Gaussian_Parameters gaussian
double max_cut
maximal cutoff for this pair of particle types.
GayBerne_Parameters gay_berne
SoftSphere_Parameters soft_sphere
SmoothStep_Parameters smooth_step
unsigned active_pair_mask
Bitmask of pair potentials active for this type pair.
Hertzian_Parameters hertzian
Buckingham_Parameters buckingham
Generic Lennard-Jones with shift.
LJGen_Parameters()=default
Lennard-Jones with shift.
LJ_Parameters()=default
Lennard-Jones with a different Cos potential.
LJcos2_Parameters()=default
Lennard-Jones+Cos potential.
LJcos_Parameters()=default
Morse_Parameters()=default
SmoothStep_Parameters()=default
SoftSphere_Parameters()=default
Evaluate forces and energies using a custom potential profile.
Thole_Parameters()=default
Thole_Parameters(double scaling_coeff, double q1q2)
WCA_Parameters()=default