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