30#include "accumulators/AutoUpdateAccumulators.hpp"
36#include "collision_detection/CollisionDetection.hpp"
37#include "communication.hpp"
48#include "thermostat.hpp"
55#include <boost/mpi/collectives/all_reduce.hpp>
70 auto handle = std::make_shared<System>(Private());
76 box_geo = std::make_shared<BoxGeometry>();
77 local_geo = std::make_shared<LocalBox>();
78 cell_structure = std::make_shared<CellStructure>(*box_geo);
81 gpu = std::make_shared<GpuParticleData>();
83 propagation = std::make_shared<Propagation>();
84 bonded_ias = std::make_shared<BondedInteractionsMap>();
85 thermostat = std::make_shared<Thermostat::Thermostat>();
86 nonbonded_ias = std::make_shared<InteractionsNonBonded>();
87 comfixed = std::make_shared<ComFixed>();
88 galilei = std::make_shared<Galilei>();
89 oif_global = std::make_shared<OifGlobal>();
90 immersed_boundaries = std::make_shared<ImmersedBoundaries>();
91#ifdef ESPRESSO_COLLISION_DETECTION
93 std::make_shared<CollisionDetection::CollisionDetection>();
95 bond_breakage = std::make_shared<BondBreakage::BondBreakage>();
96 lees_edwards = std::make_shared<LeesEdwards::LeesEdwards>();
97 auto_update_accumulators =
98 std::make_shared<Accumulators::AutoUpdateAccumulators>();
99 constraints = std::make_shared<Constraints::Constraints>();
100 steepest_descent = std::make_shared<SteepestDescent>();
101#ifdef ESPRESSO_STOKESIAN_DYNAMICS
102 stokesian_dynamics = std::make_shared<StokesianDynamics>();
105 nptiso = std::make_shared<NptIsoParameters>();
106 npt_inst_pressure = std::make_shared<InstantaneousPressure>();
108 reinit_thermo =
true;
115void System::initialize() {
116 auto handle = shared_from_this();
117 cell_structure->bind_system(handle);
118 lees_edwards->bind_system(handle);
119 bonded_ias->bind_system(handle);
120 thermostat->bind_system(handle);
121 nonbonded_ias->bind_system(handle);
122 oif_global->bind_system(handle);
123 immersed_boundaries->bind_system(handle);
124#ifdef ESPRESSO_COLLISION_DETECTION
125 collision_detection->bind_system(handle);
127 auto_update_accumulators->bind_system(handle);
128 constraints->bind_system(handle);
130 gpu->bind_system(handle);
133 lb.bind_system(handle);
134 ek.bind_system(handle);
146 assert(system !=
nullptr);
152 throw std::domain_error(
"time_step must be > 0.");
153 if (lb.is_solver_set()) {
154 lb.veto_time_step(value);
156 if (ek.is_solver_set()) {
157 ek.veto_time_step(value);
160 on_timestep_change();
164 if (lb.is_solver_set()) {
167 if (ek.is_solver_set()) {
174 propagation->recalc_forces =
true;
178 min_global_cut = value;
179 on_verlet_skin_change();
186 auto &old_regular_decomposition =
188 std::as_const(*cell_structure).decomposition());
189 cell_structure->set_regular_decomposition(
190 get_interaction_range(),
191 old_regular_decomposition.fully_connected_boundary());
193 cell_structure->set_regular_decomposition(get_interaction_range(), {});
196 cell_structure->set_atom_decomposition();
201 std::as_const(*cell_structure).decomposition());
202 cell_structure->set_hybrid_decomposition(
203 old_hybrid_decomposition.get_cutoff_regular(),
204 old_hybrid_decomposition.get_n_square_types());
209 set_cell_structure_topology(cell_structure->decomposition_type());
214 rebuild_cell_structure();
217 if (not skip_method_adaption) {
220#ifdef ESPRESSO_ELECTROSTATICS
221 coulomb.on_boxl_change();
223#ifdef ESPRESSO_DIPOLES
224 dipoles.on_boxl_change();
227 constraints->on_boxl_change();
231 if (not skip_particle_checks) {
232 auto const n_part = boost::mpi::all_reduce(
233 ::comm_cart, cell_structure->local_particles().size(), std::plus<>());
235 throw std::runtime_error(
236 "Cannot reset the box length when particles are present");
239 constraints->veto_boxl_change();
240 lb.veto_boxl_change();
241 ek.veto_boxl_change();
246 lb.on_node_grid_change();
247 ek.on_node_grid_change();
248#ifdef ESPRESSO_ELECTROSTATICS
249 coulomb.on_node_grid_change();
251#ifdef ESPRESSO_DIPOLES
252 dipoles.on_node_grid_change();
254 rebuild_cell_structure();
258#ifdef ESPRESSO_ELECTROSTATICS
259 coulomb.on_periodicity_change();
262#ifdef ESPRESSO_DIPOLES
263 dipoles.on_periodicity_change();
266#ifdef ESPRESSO_STOKESIAN_DYNAMICS
268 if (box_geo->periodic(0u) or box_geo->periodic(1u) or box_geo->periodic(2u))
270 <<
"(False, False, False)\n";
273 on_verlet_skin_change();
278 lb.on_cell_structure_change();
279 ek.on_cell_structure_change();
280#ifdef ESPRESSO_ELECTROSTATICS
281 coulomb.on_cell_structure_change();
283#ifdef ESPRESSO_DIPOLES
284 dipoles.on_cell_structure_change();
291 rebuild_cell_structure();
292#ifdef ESPRESSO_ELECTROSTATICS
293 coulomb.on_coulomb_change();
295#ifdef ESPRESSO_DIPOLES
296 dipoles.on_dipoles_change();
298 on_short_range_ia_change();
302 lb.on_temperature_change();
303 ek.on_temperature_change();
307 lb.on_timestep_change();
308 ek.on_timestep_change();
309 on_thermostat_param_change();
313 rebuild_cell_structure();
314 propagation->recalc_forces =
true;
318 nonbonded_ias->recalc_maximal_cutoffs();
319 rebuild_cell_structure();
320 on_thermostat_param_change();
321 propagation->recalc_forces =
true;
325#ifdef ESPRESSO_ELECTROSTATICS
326 coulomb.on_coulomb_change();
328 on_short_range_ia_change();
332#ifdef ESPRESSO_DIPOLES
333 dipoles.on_dipoles_change();
335 on_short_range_ia_change();
341 propagation->recalc_forces =
true;
345 cell_structure->update_ghosts_and_resort_particle(get_global_ghost_flags());
346 propagation->recalc_forces =
true;
347 propagation->recalc_used_propagations =
true;
356#ifdef ESPRESSO_ELECTROSTATICS
357 coulomb.on_particle_change();
359#ifdef ESPRESSO_DIPOLES
360 dipoles.on_particle_change();
362 propagation->recalc_forces =
true;
363 propagation->recalc_used_propagations =
true;
367 cell_structure->clear_local_properties();
371#ifdef ESPRESSO_ELECTROSTATICS
372 coulomb.on_particle_change();
377#ifdef ESPRESSO_VIRTUAL_SITES
378 if (propagation->recalc_used_propagations) {
379 update_used_propagations();
381#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
382 if (propagation->used_propagations &
388#ifdef ESPRESSO_VIRTUAL_SITES_CENTER_OF_MASS
389 if (propagation->used_propagations &
394 cell_structure->update_ghosts_and_resort_particle(get_global_ghost_flags());
397#ifdef ESPRESSO_ELECTROSTATICS
398 if (has_icc_enabled()) {
400 update_icc_particles();
407 immersed_boundaries->init_volume_conservation(*cell_structure);
413 cell_structure->update_ghosts_and_resort_particle(get_global_ghost_flags());
414 update_dependent_particles();
416#ifdef ESPRESSO_ELECTROSTATICS
417 coulomb.on_observable_calc();
420#ifdef ESPRESSO_DIPOLES
421 dipoles.on_observable_calc();
429#ifdef ESPRESSO_COLLISION_DETECTION
430 auto const collision_detection_cutoff = collision_detection->cutoff();
448 max_cut = std::max(max_cut, get_min_global_cut());
449 max_cut = std::max(max_cut, coulomb.cutoff());
450 max_cut = std::max(max_cut, dipoles.cutoff());
454 max_cut = std::max(max_cut, bonded_ias->maximal_cutoff());
456 max_cut = std::max(max_cut, nonbonded_ias->maximal_cutoff());
458#ifdef ESPRESSO_COLLISION_DETECTION
459 max_cut = std::max(max_cut, collision_detection->cutoff());
466#ifdef ESPRESSO_ELECTROSTATICS
467 coulomb.sanity_checks();
469#ifdef ESPRESSO_DIPOLES
470 dipoles.sanity_checks();
472 }
catch (std::runtime_error
const &err) {
480 auto const max_cut = maximal_cutoff();
481 auto const verlet_skin = cell_structure->get_verlet_skin();
487 box_geo->set_length(box_l);
493 integrator_sanity_checks();
494 long_range_interactions_sanity_checks();
501 npt_ensemble_init(propagation->recalc_forces);
507 thermostat->recalc_prefactors(time_step);
508 reinit_thermo =
false;
509 propagation->recalc_forces =
true;
513 cell_structure->clear_local_properties();
515#ifdef ESPRESSO_ADDITIONAL_CHECKS
519#ifdef ESPRESSO_ELECTROSTATICS
521 auto const &actor = coulomb.impl->solver;
527#ifdef ESPRESSO_DIPOLES
529 auto const &actor = dipoles.impl->solver;
537 on_observable_calc();
571#ifdef ESPRESSO_ROTATION
575 if (sys.propagation->used_propagations &
584 if (sys.propagation->used_propagations &
590#ifdef ESPRESSO_DIPOLES
593 if (sys.dipoles.impl && sys.dipoles.impl->solver) {
598#ifdef ESPRESSO_GAY_BERNE
606#ifdef ESPRESSO_ENGINE
609 if (sys.lb.is_solver_set()) {
614#ifdef ESPRESSO_THERMAL_STONER_WOHLFARTH
638 if (lb.is_solver_set())
649#ifdef ESPRESSO_COLLISION_DETECTION
650 if (not collision_detection->is_off()) {
655#ifdef ESPRESSO_ROTATION
666#ifdef ESPRESSO_ROTATION
683 if (has_npt_enabled()) {
684 return &npt_inst_pressure->p_vir;
690#ifdef ESPRESSO_COLLISION_DETECTION
692 return not collision_detection->is_off();
CellStructureType
Cell structure topology.
@ NSQUARE
Atom decomposition (N-square).
@ HYBRID
Hybrid decomposition.
@ REGULAR
Regular decomposition.
@ INTEG_METHOD_NPT_ISO_AND
@ INTEG_METHOD_NPT_ISO_MTK
Vector implementation and trait types for boost qvm interoperability.
Data structures for bonded interactions.
Hybrid decomposition cell system.
static LocalBox make_regular_decomposition(Utils::Vector3d const &box_l, Utils::Vector3i const &node_index, Utils::Vector3i const &node_grid)
void on_periodicity_change()
double get_interaction_range() const
Get the interaction range.
double maximal_cutoff() const
Calculate the maximal cutoff of all interactions.
void on_constraint_change()
Called every time a constraint is changed.
void on_cell_structure_change()
unsigned get_global_ghost_flags() const
Returns the ghost flags required for running pair kernels for the global state, e....
void on_boxl_change(bool skip_method_adaption=false)
Called when the box length has changed.
void set_box_l(Utils::Vector3d const &box_l)
Change the box dimensions.
void on_temperature_change()
void on_thermostat_param_change()
void on_lees_edwards_change()
void on_integration_start()
void set_force_cap(double value)
Set force_cap.
void on_non_bonded_ia_change()
void on_verlet_skin_change()
void update_dependent_particles()
Update particles with properties depending on other particles, namely virtual sites and ICC charges.
void on_lb_boundary_conditions_change()
Called when the LB boundary conditions change (geometry, slip velocity, or both).
void veto_boxl_change(bool skip_particle_checks=false) const
void set_time_step(double value)
Set time_step.
void on_particle_change()
Called every time a particle property changes.
bool long_range_interactions_sanity_checks() const
Check electrostatic and magnetostatic methods are properly initialized.
void on_node_grid_change()
void on_particle_charge_change()
Called every time a particle charge changes.
void on_particle_local_change()
Called every time a particle local property changes.
void on_observable_calc()
called before calculating observables, i.e.
void on_timestep_change()
void check_kT(double value) const
Veto temperature change.
static std::shared_ptr< System > create()
Utils::Vector3d * get_npt_virial() const
unsigned get_force_reduce_ghost_flags() const
Returns the ghost flags for the force-reduce step.
void set_min_global_cut(double value)
Set min_global_cut.
bool has_npt_enabled() const
void set_cell_structure_topology(CellStructureType topology)
Change cell structure topology.
void on_short_range_ia_change()
void rebuild_cell_structure()
Rebuild cell lists.
bool has_collision_detection_enabled() const
void vs_com_update_particles(CellStructure &cell_structure, BoxGeometry const &box_geo)
std::shared_ptr< KokkosHandle > kokkos_handle
Communicator communicator
boost::mpi::communicator comm_cart
The communicator.
constexpr double inactive_cutoff
Special cutoff value for an inactive interaction.
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
#define runtimeErrorMsg()
Ghost particles and particle exchange.
@ GHOSTTRANS_FORCE
transfer ParticleForce
@ GHOSTTRANS_TORQUE
transfer torque (reduced with force; runtime-conditional)
ICC is a method that allows to take into account the influence of arbitrarily shaped dielectric inter...
@ DATA_PART_MOMENTUM
Particle::m.
@ DATA_PART_PROPERTIES
Particle::p.
@ DATA_PART_BONDS
Particle::bonds.
@ DATA_PART_QUAT
orientation quaternion (pushed with position)
@ DATA_PART_POSITION
Particle::r.
@ TRANS_VS_CENTER_OF_MASS
static std::shared_ptr< System > instance
bool is_same_system(System const *const system)
void set_system(std::shared_ptr< System > new_instance)
static bool orientation_ghosts_needed(System const &sys)
Return true when any active physics requires orientation of ghost particles.
bool all_compare(boost::mpi::communicator const &comm, T const &value)
Compare values on all nodes.
Exports for the NpT code.
void invalidate_fetch_cache()
Invalidate the fetch cache for get_particle_data.
void clear_particle_node()
Invalidate particle_node.
Particles creation and deletion.
void vs_relative_update_particles(CellStructure &cell_structure, BoxGeometry const &box_geo)
See for the Stokesian dynamics method used here.
void update_verlet_state(System::System const &system, double const collision_cut)
Utils::Vector3i calc_node_index() const
Calculate the node index in the Cartesian topology.
Utils::Vector3i node_grid
Regular decomposition cell system.
Routines to thermalize the center of mass and distance of a particle pair.