ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
core/system/System.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014-2026 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#pragma once
21
22#include <config/config.hpp>
23
24#include "ResourceCleanup.hpp"
25
28
29#include "ek/Solver.hpp"
30#include "lb/Solver.hpp"
31
33
34#include <utils/Vector.hpp>
35
36#include <memory>
37#include <optional>
38#include <vector>
39
40class BoxGeometry;
41class LocalBox;
42class CellStructure;
43class Propagation;
46namespace Thermostat {
47class Thermostat;
48}
49class ComFixed;
50class Galilei;
51class Observable_stat;
52class OifGlobal;
54namespace CollisionDetection {
56}
57namespace BondBreakage {
58class BondBreakage;
59}
60namespace LeesEdwards {
61class LeesEdwards;
62}
63namespace Accumulators {
64class AutoUpdateAccumulators;
65}
66namespace Constraints {
67class Constraints;
68}
69struct SteepestDescent;
71struct NptIsoParameters;
73#ifdef ESPRESSO_CUDA
74class GpuParticleData;
75#endif
76struct EnergyObservable;
78
79namespace System {
80
81/**
82 * @brief Main system class.
83 *
84 * Most components follow the composite pattern and the opaque pointer pattern.
85 * See @ref SystemClassDesign for more details.
86 */
87class System : public std::enable_shared_from_this<System> {
88private:
89 struct Private {};
90 void initialize();
91
92public:
93 System(Private);
94
95 static std::shared_ptr<System> create();
96
97#ifdef ESPRESSO_CUDA
98 std::shared_ptr<GpuParticleData> gpu;
99#endif
101
102 /** @brief Get @ref time_step. */
103 auto get_time_step() const { return time_step; }
104
105 /** @brief Set @ref time_step. */
106 void set_time_step(double value);
107
108 /** @brief Get @ref sim_time. */
109 auto get_sim_time() const { return sim_time; }
110
111 /** @brief Set @ref sim_time. */
112 void set_sim_time(double value);
113
114 /** @brief Get @ref force_cap. */
115 auto get_force_cap() const { return force_cap; }
116
117 /** @brief Set @ref force_cap. */
118 void set_force_cap(double value);
119
120 /** @brief Get @ref min_global_cut. */
121 auto get_min_global_cut() const { return min_global_cut; }
122
123 /** @brief Set @ref min_global_cut. */
124 void set_min_global_cut(double value);
125
126 /** @brief Change the box dimensions. */
127 void set_box_l(Utils::Vector3d const &box_l);
128
129 /**
130 * @brief Tune the Verlet skin.
131 * Choose the optimal Verlet list skin between @p min_skin and @p max_skin
132 * by bisection to tolerance @p tol.
133 */
134 void tune_verlet_skin(double min_skin, double max_skin, double tol,
135 int int_steps, bool adjust_max_skin);
136
137 /** @brief Change cell structure topology. */
138 void set_cell_structure_topology(CellStructureType topology);
139
140 /** @brief Rebuild cell lists. Use e.g. after a skin change. */
141 void rebuild_cell_structure();
142 void rebuild_aosoa();
143
144 /** @brief Calculate the maximal cutoff of all interactions. */
145 double maximal_cutoff() const;
146
147 /** @brief Get the interaction range. */
148 double get_interaction_range() const;
149
150 unsigned get_global_ghost_flags() const;
151
152 /**
153 * @brief Returns the ghost flags for the force-reduce step.
154 *
155 * Always includes GHOSTTRANS_FORCE; adds GHOSTTRANS_TORQUE when orientation
156 * physics is active (same whitelist as get_global_ghost_flags for QUAT).
157 */
158 unsigned get_force_reduce_ghost_flags() const;
159
160 /** Check electrostatic and magnetostatic methods are properly initialized.
161 * @return true if sanity checks failed.
162 */
163 bool long_range_interactions_sanity_checks() const;
164
165 /** @brief Calculate the total energy. */
166 Observable_stat const &calculate_energy();
167
168 /** @brief Calculate the pressure from a virial expansion. */
169 Observable_stat const &calculate_pressure();
170
171#ifdef ESPRESSO_NPT
172 /** @brief Synchronize NpT state such as instantaneous and average pressure */
173 void synchronize_npt_state();
174 /** @brief Reinitialize the NpT state. */
175 void npt_ensemble_init(bool recalc_forces);
176 void npt_add_virial_contribution(double energy);
177 bool has_npt_enabled() const;
178#endif // ESPRESSO_NPT
179 Utils::Vector3d *get_npt_virial() const;
180
181 /** @brief Calculate all forces. */
182 void calculate_forces();
183
184#ifdef ESPRESSO_DIPOLE_FIELD_TRACKING
185 /** @brief Calculate dipole fields. */
187#endif
188
189#ifdef ESPRESSO_COLLISION_DETECTION
190 bool has_collision_detection_enabled() const;
191#endif
192
193 /**
194 * @brief Compute the short-range energy of a particle.
195 *
196 * Iterate through particles inside cell and neighboring cells and compute
197 * energy contribution for a specific particle.
198 *
199 * @param pid Particle id
200 * @return Non-bonded energy of the particle.
201 */
202 double particle_short_range_energy_contribution(int pid);
203 /**
204 * @brief Compute the energy of a given bond which has to exist on the given
205 * particle.
206 *
207 * Requires that bond partners are visible on the same MPI rank as the
208 * primary particle.
209 * Returns nothing if the primary particle is not owned by this MPI rank.
210 *
211 * @param pid Particle id
212 * @param bond_id Bond id
213 * @param partners Particle ids of the bond partners
214 *
215 * @return energy of the bond given the primary particle and bond partners
216 */
217 std::optional<double> particle_bond_energy(int pid, int bond_id,
218 std::vector<int> partners);
219
220 /** Integrate equations of motion
221 * @param n_steps Number of integration steps, can be zero
222 * @param reuse_forces Decide when to re-calculate forces
223 *
224 * @details This function calls two hooks for propagation kernels such as
225 * velocity Verlet, velocity Verlet + NpT, or steepest descent.
226 * One hook is called before and one after the force calculation.
227 * It is up to the propagation kernels to increment the simulation time.
228 *
229 * This function propagates the system according to the choice of integrator
230 * stored in @ref Propagation::integ_switch. The general structure is:
231 * - if reuse_forces is zero, recalculate the forces based on the current
232 * state of the system
233 * - Loop over the number of simulation steps:
234 * -# initialization (e.g., RATTLE)
235 * -# First hook for propagation kernels
236 * -# Update dependent particles and properties (RATTLE, virtual sites)
237 * -# Calculate forces for the current state of the system. This includes
238 * forces added by the Langevin thermostat and the
239 * Lattice-Boltzmann-particle coupling
240 * -# Second hook for propagation kernels
241 * -# Update dependent properties (Virtual sites, RATTLE)
242 * -# Run single step algorithms (Lattice-Boltzmann propagation, collision
243 * detection, NpT update)
244 * - Final update of dependent properties and statistics/counters
245 *
246 * High-level documentation of the integration and thermostatting schemes
247 * can be found in doc/sphinx/system_setup.rst and /doc/sphinx/running.rst
248 *
249 * @return number of steps that have been integrated, or a negative error
250 * code
251 */
252 int integrate(int n_steps, int reuse_forces);
253
254 int integrate_with_signal_handler(int n_steps, int reuse_forces,
255 bool update_accumulators);
256
257 /** @brief Calculate particle-lattice interactions. */
258 void lb_couple_particles();
259
260 /** \name Hook procedures
261 * These procedures are called if several significant changes to
262 * the system happen which may make a reinitialization of subsystems
263 * necessary.
264 */
265 /**@{*/
266 /**
267 * @brief Called when the box length has changed. This routine is relatively
268 * fast, and changing the box length every time step as for example necessary
269 * for NpT is more or less ok.
270 *
271 * @param skip_method_adaption skip the long-range methods adaptions
272 */
273 void on_boxl_change(bool skip_method_adaption = false);
274 void on_node_grid_change();
275 void on_periodicity_change();
276 void on_cell_structure_change();
277 void on_thermostat_param_change();
278 void on_temperature_change();
279 void on_verlet_skin_change();
280 void on_timestep_change();
281 void on_integration_start();
282 void on_short_range_ia_change();
283 void on_non_bonded_ia_change();
284 void on_coulomb_change();
285 void on_dipoles_change();
286 /** @brief Called every time a constraint is changed. */
287 void on_constraint_change();
288 /** @brief Called when the LB boundary conditions change
289 * (geometry, slip velocity, or both).
290 */
291 void on_lb_boundary_conditions_change();
292 /** @brief Called every time a particle local property changes. */
293 void on_particle_local_change();
294 /** @brief Called every time a particle property changes. */
295 void on_particle_change();
296 /** @brief Called every time a particle charge changes. */
297 void on_particle_charge_change();
298 /** called before calculating observables, i.e. energy, pressure or
299 * the integrator (forces). Initialize any methods here which are not
300 * initialized immediately (P3M etc.).
301 */
302 void on_observable_calc();
303 void on_lees_edwards_change();
304 void veto_boxl_change(bool skip_particle_checks = false) const;
305 /**@}*/
306
307 /**
308 * @brief Update particles with properties depending on other particles,
309 * namely virtual sites and ICC charges.
310 */
311 void update_dependent_particles();
312 /**
313 * @brief Update the global propagation bitmask.
314 */
315 void update_used_propagations();
316 /**
317 * @brief Veto temperature change.
318 */
319 void check_kT(double value) const;
320
325 std::shared_ptr<BoxGeometry> box_geo;
326 std::shared_ptr<LocalBox> local_geo;
327 std::shared_ptr<CellStructure> cell_structure;
328 std::shared_ptr<Propagation> propagation;
329 std::shared_ptr<BondedInteractionsMap> bonded_ias;
330 std::shared_ptr<InteractionsNonBonded> nonbonded_ias;
331 std::shared_ptr<Thermostat::Thermostat> thermostat;
332 std::shared_ptr<ComFixed> comfixed;
333 std::shared_ptr<Galilei> galilei;
334 std::shared_ptr<OifGlobal> oif_global;
335 std::shared_ptr<ImmersedBoundaries> immersed_boundaries;
336#ifdef ESPRESSO_COLLISION_DETECTION
337 std::shared_ptr<CollisionDetection::CollisionDetection> collision_detection;
338#endif
339 std::shared_ptr<BondBreakage::BondBreakage> bond_breakage;
340 std::shared_ptr<LeesEdwards::LeesEdwards> lees_edwards;
341 std::shared_ptr<Accumulators::AutoUpdateAccumulators>
343 std::shared_ptr<Constraints::Constraints> constraints;
344 std::shared_ptr<SteepestDescent> steepest_descent;
345#ifdef ESPRESSO_STOKESIAN_DYNAMICS
346 std::shared_ptr<StokesianDynamics> stokesian_dynamics;
347#endif
348#ifdef ESPRESSO_NPT
349 std::shared_ptr<NptIsoParameters> nptiso;
350 std::shared_ptr<InstantaneousPressure> npt_inst_pressure;
351#endif
352
353protected:
354 /** @brief Whether the thermostat has to be reinitialized before integration.
355 */
357 /** @brief Molecular dynamics integrator time step. */
358 double time_step;
359 /** @brief Molecular dynamics integrator simulation time. */
360 double sim_time;
361 /** @brief Molecular dynamics integrator force capping. */
362 double force_cap;
363 /**
364 * @brief Minimal global interaction cutoff.
365 * Particles with a distance smaller than this are guaranteed
366 * to be available on the same node (through ghosts).
367 */
369 std::shared_ptr<EnergyObservable> m_obs_energy;
370 std::shared_ptr<PressureObservable> m_obs_pressure;
371
372 void update_local_geo();
373#ifdef ESPRESSO_ELECTROSTATICS
374 void update_icc_particles();
375 bool has_icc_enabled() const;
376#endif // ESPRESSO_ELECTROSTATICS
377#ifdef ESPRESSO_THERMAL_STONER_WOHLFARTH
378 void integrate_magnetodynamics();
379#endif
380
381private:
382 /**
383 * @brief Check integrator parameters and incompatibilities between
384 * the integrator and the currently active thermostat(s).
385 */
386 void integrator_sanity_checks() const;
387};
388
390void set_system(std::shared_ptr<System> new_instance);
391void reset_system();
392bool is_same_system(System const *system);
393
394} // namespace System
CellStructureType
Cell structure topology.
Vector implementation and trait types for boost qvm interoperability.
container for bonded interactions.
Describes a cell structure / cell system.
Particle data communication manager for the GPU.
Observable for the pressure and energy.
Queue to deallocate resources before normal program termination.
std::shared_ptr< PressureObservable > m_obs_pressure
auto get_time_step() const
Get time_step.
std::shared_ptr< StokesianDynamics > stokesian_dynamics
std::shared_ptr< LeesEdwards::LeesEdwards > lees_edwards
double sim_time
Molecular dynamics integrator simulation time.
std::shared_ptr< LocalBox > local_geo
std::shared_ptr< BondedInteractionsMap > bonded_ias
double min_global_cut
Minimal global interaction cutoff.
auto get_min_global_cut() const
Get min_global_cut.
bool reinit_thermo
Whether the thermostat has to be reinitialized before integration.
std::shared_ptr< ImmersedBoundaries > immersed_boundaries
std::shared_ptr< Accumulators::AutoUpdateAccumulators > auto_update_accumulators
std::shared_ptr< ComFixed > comfixed
std::shared_ptr< BondBreakage::BondBreakage > bond_breakage
Dipoles::Solver dipoles
std::shared_ptr< CollisionDetection::CollisionDetection > collision_detection
std::shared_ptr< InstantaneousPressure > npt_inst_pressure
std::shared_ptr< OifGlobal > oif_global
std::shared_ptr< NptIsoParameters > nptiso
double force_cap
Molecular dynamics integrator force capping.
ResourceCleanup cleanup_queue
std::shared_ptr< Propagation > propagation
double time_step
Molecular dynamics integrator time step.
void calculate_long_range_fields()
Calculate dipole fields.
std::shared_ptr< SteepestDescent > steepest_descent
std::shared_ptr< GpuParticleData > gpu
std::shared_ptr< Thermostat::Thermostat > thermostat
std::shared_ptr< CellStructure > cell_structure
std::shared_ptr< Constraints::Constraints > constraints
std::shared_ptr< EnergyObservable > m_obs_energy
auto get_force_cap() const
Get force_cap.
auto get_sim_time() const
Get sim_time.
Coulomb::Solver coulomb
std::shared_ptr< BoxGeometry > box_geo
std::shared_ptr< Galilei > galilei
std::shared_ptr< InteractionsNonBonded > nonbonded_ias
System & get_system()
bool is_same_system(System const *const system)
void set_system(std::shared_ptr< System > new_instance)
Instantaneous pressure during force calculation for NPT integration.
Definition npt.hpp:92
Parameters of the isotropic NpT-integration scheme.
Definition npt.hpp:42
Steepest descent algorithm.