IMP logo
IMP Reference Guide  develop.31a501ea3f,2026/01/29
The Integrative Modeling Platform
atom/MolecularDynamics.h
Go to the documentation of this file.
1 /**
2  * \file IMP/atom/MolecularDynamics.h
3  * \brief Simple molecular dynamics optimizer.
4  *
5  * Copyright 2007-2025 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPATOM_MOLECULAR_DYNAMICS_H
10 #define IMPATOM_MOLECULAR_DYNAMICS_H
11 
12 #include <IMP/atom/atom_config.h>
13 #include "Simulator.h"
14 #include "atom_macros.h"
15 #include <IMP/Particle.h>
16 #include <IMP/Optimizer.h>
17 
18 IMPATOM_BEGIN_NAMESPACE
19 
20 //! A particle with linear (XYZ) velocity
21 /** Typically this is used in combination with the MolecularDynamics optimizer.
22  */
23 class IMPATOMEXPORT LinearVelocity : public Decorator {
24  static void do_setup_particle(Model *m, ParticleIndex pi,
25  const algebra::Vector3D v = algebra::Vector3D(0, 0, 0)) {
26  m->add_attribute(get_velocity_key(), pi, v);
27  }
28 
29 public:
30  static bool get_is_setup(Model *m, ParticleIndex pi) {
31  return m->get_has_attribute(get_velocity_key(), pi);
32  }
33 
34  /* Get the key used to store velocity */
35  static Vector3DKey get_velocity_key();
36 
40 
41  void set_velocity(const algebra::Vector3D &v) {
42  Model *m = get_model();
44  m->set_attribute(get_velocity_key(), pi, v);
45  }
46 
47  algebra::Vector3D get_velocity() const {
48  Model *m = get_model();
50  return m->get_attribute(get_velocity_key(), pi);
51  }
52 };
53 
54 //! A particle with angular velocity
55 /** Typically this is used for RigidBody particles in combination
56  with the MolecularDynamics optimizer. The velocity is stored as
57  a quaternion.
58  */
59 class IMPATOMEXPORT AngularVelocity : public Decorator {
60  static void do_setup_particle(Model *m, ParticleIndex pi,
61  const algebra::Vector4D v = algebra::Vector4D(0, 0, 0, 0)) {
62  m->add_attribute(get_velocities_key(), pi, v.get_coordinates());
63  }
64  static FloatsKey get_velocities_key() {
65  static const FloatsKey key("angvel");
66  return key;
67  }
68 
69 public:
70 
71  static bool get_is_setup(Model *m, ParticleIndex pi) {
72  return m->get_has_attribute(get_velocities_key(), pi);
73  }
74 
78 
79  void set_velocity(const algebra::Vector4D &v) {
80  Model *m = get_model();
82  m->set_attribute(get_velocities_key(), pi, v.get_coordinates());
83  }
84 
85  algebra::Vector4D get_velocity() const {
86  Model *m = get_model();
88  return algebra::Vector4D(m->get_attribute(get_velocities_key(), pi));
89  }
90 };
91 
92 //! Simple molecular dynamics simulator.
93 /**
94  The particles to be optimized must have optimizable x,y,z attributes
95  and a non-optimizable mass attribute; this optimizer assumes the score
96  to be energy in kcal/mol, the xyz coordinates to be in angstroms, and
97  the mass to be in AMU (g/mol).
98 
99  \note RigidBody particles are not handled properly.
100 
101  Particles without optimized x,y,z and nonoptimized mass are skipped.
102  \see VelocityScalingOptimizerState
103  \see LangevinThermostatOptimizerState
104  \see BerendsenThermostatOptimizerState
105  \see RemoveRigidMotionOptimizerState
106  */
107 class IMPATOMEXPORT MolecularDynamics : public Simulator {
108  public:
109  /** Score based on the provided model */
111 
112  //! Return the current kinetic energy of the system, in kcal/mol
113  virtual Float get_kinetic_energy() const;
114 
115  //! Return the current kinetic temperature of the system
116  /** \param[in] ekinetic kinetic energy, e.g. from get_kinetic_energy()
117  */
118  Float get_kinetic_temperature(Float ekinetic) const;
119 
120  //! Set maximum velocity in A/fs
121  /** At each dynamics time step, the absolute value of each velocity
122  component is capped at this value. This prevents spurious strong forces
123  (occasionally encountered with frustrated conformations) from causing
124  large oscillations in the system.
125  By default, velocities are not capped.
126 
127  \note The actual velocities that are capped are the half-step velocities
128  in the velocity Verlet algorithm.
129  */
130  void set_velocity_cap(Float velocity_cap) { velocity_cap_ = velocity_cap; }
131 
132  //! Get the current value of the velocity cap
133  /** If velocities are not capped, infinity is returned */
134  Float get_velocity_cap() const { return velocity_cap_; }
135 
136  //! Get number of degrees of freedom in the system
138  setup_degrees_of_freedom(get_simulation_particle_indexes());
139  return degrees_of_freedom_;
140  }
141 
142  //! Assign velocities representative of the given temperature
143  virtual void assign_velocities(Float temperature);
144  virtual void setup(const ParticleIndexes &ps) override;
145  virtual double do_step(const ParticleIndexes &sc,
146  double dt) override;
147  virtual bool get_is_simulation_particle(ParticleIndex p) const
148  override;
149 
151 
152  protected:
153  void initialize();
154 
155  virtual void setup_degrees_of_freedom(const ParticleIndexes &ps);
156 
157  //! First part of velocity Verlet (update coordinates and half-step velocity)
158  virtual void propagate_coordinates(const ParticleIndexes &ps,
159  double step_size);
160 
161  //! Second part of velocity Verlet (update velocity)
162  virtual void propagate_velocities(const ParticleIndexes &ps,
163  double step_size);
164 
165  //! Cap a velocity component to the maximum value.
166  inline void cap_velocity_component(Float &vel) {
167  if (vel >= 0.0) {
168  vel = std::min(vel, velocity_cap_);
169  } else {
170  vel = std::max(vel, -velocity_cap_);
171  }
172  }
173 
174  //! Number of degrees of freedom in the system
176 
177  //! Maximum absolute value of a single velocity component
179 };
180 
181 IMPATOM_END_NAMESPACE
182 
183 #endif /* IMPATOM_MOLECULAR_DYNAMICS_H */
A particle with angular velocity.
The base class for simulators.
Definition: Simulator.h:34
ParticleIndex get_particle_index() const
Returns the particle index decorated by this decorator.
Definition: Decorator.h:211
ParticleIndexes get_simulation_particle_indexes() const
#define IMP_DECORATOR_SETUP_1(Name, FirstArgumentType, first_argument_name)
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
Model * get_model() const
Returns the Model containing the particle.
Definition: Decorator.h:214
virtual bool get_is_simulation_particle(ParticleIndex p) const =0
Return true if the passed particle is appropriate for the simulation.
A particle with linear (XYZ) velocity.
Base class for all optimizers.
VectorD< 4 > Vector4D
Definition: VectorD.h:412
virtual double do_step(const ParticleIndexes &sc, double dt)=0
Perform a single time step.
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
virtual void setup(const ParticleIndexes &)
Definition: Simulator.h:178
void set_velocity_cap(Float velocity_cap)
Set maximum velocity in A/fs.
void add_attribute(TypeKey attribute_key, ParticleIndex particle, Type value)
add particle attribute with the specified key and initial value
Simple molecular dynamics simulator.
int degrees_of_freedom_
Number of degrees of freedom in the system.
void set_attribute(TypeKey attribute_key, ParticleIndex particle, Type value)
set the value of particle attribute with the specified key
A base class for Keys.
Definition: Key.h:45
Base class for "simulators", such as molecular dynamics.
#define IMP_DECORATOR_SETUP_0(Name)
Interface to specialized Particle types (e.g. atoms)
Definition: Decorator.h:119
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
void cap_velocity_component(Float &vel)
Cap a velocity component to the maximum value.
Macros for maintaining molecular hierarchies.
Float velocity_cap_
Maximum absolute value of a single velocity component.
int get_degrees_of_freedom()
Get number of degrees of freedom in the system.
#define IMP_DECORATOR_METHODS(Name, Parent)
VectorD< 3 > Vector3D
Definition: VectorD.h:408
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:19
bool get_has_attribute(TypeKey attribute_key, ParticleIndex particle) const
return true if particle has attribute with the specified key
Type get_attribute(TypeKey attribute_key, ParticleIndex particle)
get the value of the particle attribute with the specified key
Float get_velocity_cap() const
Get the current value of the velocity cap.