ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
VerletCriterion.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#include <config/config.hpp>
25
26#include "Particle.hpp"
28#include "system/System.hpp"
29
30#include <utils/index.hpp>
31#include <utils/math/sqr.hpp>
32
33#include <algorithm>
34#include <cassert>
35#include <cstddef>
36#include <vector>
37
40 auto operator()(int type_i, int type_j) const {
41 return m_system.nonbonded_ias->get_ia_param(type_i, type_j).max_cut;
42 }
43
44private:
45 System::System const &m_system;
46};
47
48/** Returns true if the particles are to be considered for short range
49 * interactions.
50 *
51 * @tparam ShortRangeOnly When true, the electrostatics / dipolar / collision
52 * early-accept branches are compiled out of the call operator. Selected by
53 * `update_verlet_state` only when none of those cutoffs are active, so the
54 * removed branches would never have accepted a pair -- the result is
55 * unchanged, but the per-candidate build loop drops the dead comparisons.
56 */
57template <typename CutoffGetter = GetNonbondedCutoff,
58 bool ShortRangeOnly = false>
60 const double m_skin;
61 const double m_eff_max_cut2;
62 const double m_eff_coulomb_cut2 = 0.;
63 const double m_eff_dipolar_cut2 = 0.;
64 const double m_collision_cut2 = 0.;
65 double eff_cutoff_sqr(double x) const {
66 if (x == inactive_cutoff)
67 return inactive_cutoff;
68 return Utils::sqr(x + m_skin);
69 }
70 /** Dense row-major table of squared effective (cutoff + skin) values per
71 * type pair, @ref inactive_cutoff for inactive pairs. The per-type-pair
72 * cutoff query runs once per candidate pair in the Verlet-list build, so
73 * it must be a plain load instead of a walk through the
74 * @ref InteractionsNonBonded pointer table.
75 */
76 std::vector<double> m_eff_cut2_table;
77 int m_n_types;
78
79public:
80 VerletCriterion(System::System const &system, double skin, double max_cut,
81 double coulomb_cut = 0., double dipolar_cut = 0.,
83 : m_skin(skin), m_eff_max_cut2(eff_cutoff_sqr(max_cut)),
84 m_eff_coulomb_cut2(eff_cutoff_sqr(coulomb_cut)),
85 m_eff_dipolar_cut2(eff_cutoff_sqr(dipolar_cut)),
86 m_collision_cut2(eff_cutoff_sqr(collision_detection_cutoff)) {
88 auto const max_type = system.nonbonded_ias->get_max_seen_particle_type();
89 m_n_types = std::max(max_type + 1, 1);
90 m_eff_cut2_table.assign(static_cast<std::size_t>(m_n_types) *
91 static_cast<std::size_t>(m_n_types),
93 for (int type_i = 0; type_i <= max_type; ++type_i) {
94 for (int type_j = type_i; type_j <= max_type; ++type_j) {
95 auto const eff_cut2 =
96 eff_cutoff_sqr(get_nonbonded_cutoff(type_i, type_j));
97 m_eff_cut2_table[static_cast<std::size_t>(type_i) *
98 static_cast<std::size_t>(m_n_types) +
99 static_cast<std::size_t>(type_j)] = eff_cut2;
100 m_eff_cut2_table[static_cast<std::size_t>(type_j) *
101 static_cast<std::size_t>(m_n_types) +
102 static_cast<std::size_t>(type_i)] = eff_cut2;
103 }
104 }
105 }
106
107 bool operator()(const Particle &p1, const Particle &p2, double dist2) const {
108 if (dist2 > m_eff_max_cut2)
109 return false;
110
111 if constexpr (not ShortRangeOnly) {
112#ifdef ESPRESSO_ELECTROSTATICS
113 // Within real space cutoff of electrostatics and both are charged
114 if (dist2 <= m_eff_coulomb_cut2 and p1.q() != 0. and p2.q() != 0.)
115 return true;
116#endif
117
118#ifdef ESPRESSO_DIPOLES
119 // Within dipolar cutoff and both carry magnetic moments
120 if (dist2 <= m_eff_dipolar_cut2 and p1.dipm() != 0. and p2.dipm() != 0.)
121 return true;
122#endif
123
124#ifdef ESPRESSO_COLLISION_DETECTION
125 // Collision detection
126 if (dist2 <= m_collision_cut2)
127 return true;
128#endif
129 }
130
131 // Within short-range distance (including dpd and the like). Inactive
132 // pairs hold inactive_cutoff (negative) in the table, so the comparison
133 // rejects them without a separate activity check.
134 auto const type_i = p1.type();
135 auto const type_j = p2.type();
136 assert(type_i >= 0 and type_i < m_n_types);
137 assert(type_j >= 0 and type_j < m_n_types);
139 static_cast<std::size_t>(m_n_types) +
140 static_cast<std::size_t>(type_j)];
141 }
142};
Main system class.
std::shared_ptr< InteractionsNonBonded > nonbonded_ias
Returns true if the particles are to be considered for short range interactions.
VerletCriterion(System::System const &system, double skin, double max_cut, double coulomb_cut=0., double dipolar_cut=0., double collision_detection_cutoff=0.)
bool operator()(const Particle &p1, const Particle &p2, double dist2) const
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
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
Various procedures concerning interactions between particles.
auto operator()(int type_i, int type_j) const
GetNonbondedCutoff(System::System const &system)
Struct holding all information for one particle.
Definition Particle.hpp:436