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