Molecular dynamics¶
See also the tutorial for a worked NVE/NVT/NPT walkthrough.
vibeqc.md is a general, method-agnostic Born-Oppenheimer molecular
dynamics driver. It integrates Newton’s equations for any callable that
returns an energy and a nuclear gradient, so the same driver runs MD on the
MSINDO semiempirical surface or on any other vibe-qc potential-energy
surface, exactly the way run_neb drives a band over an
energy+gradient seam.
There are two APIs with similar names, and they are not the same thing:
vibeqc.md.run_md,vibeqc.md.run_nveandvibeqc.md.run_nvtare the general, method-agnostic driver described on this page. They take any(coords) -> (energy, gradient)callable and are production for every method that supplies forces.The top-level
vibeqc.run_md,vibeqc.run_nve,vibeqc.run_nvtandvibeqc.run_nptare the periodic GAPW helpers invibeqc.periodic_gapw_md: they attach theVibeqcGAPWASE calculator to anase.Atomsobject and drive ASE’sVelocityVerlet,LangevinandNPTBerendsenintegrators.
Status: experimental
The top-level vibeqc.run_md / run_nve / run_nvt / run_npt helpers
inherit the label of the GAPW route they run on. GAPW is an experimental
route: its drivers emit GAPWExperimentalWarning and the .out route line
says so. Their numbers are research output, not validated results, and they
are not part of the release gate. The general vibeqc.md driver on this page
carries no such label. The label vocabulary is defined in
Methods: theory and status.
The energy+gradient interface¶
The driver consumes a ForceProvider, a callable
force_fn(coords) -> (energy, gradient)
where coords is an (n_atoms, 3) array of positions in bohr, energy
is in Hartree, and gradient = dE/dR has the same shape as coords in
Ha/bohr (forces are -gradient; the driver negates internally, matching
the run_neb convention). Anything that can produce an energy and a gradient
a semiempirical engine, an SCF + analytic gradient, a model potential, plugs in through this one interface.
Everything is in atomic units: bohr, Hartree, electron masses, and atomic time units (ħ/E_h ≈ 0.0242 fs). The timestep and thermostat coupling time are given in femtoseconds and converted internally; trajectory velocities are stored in bohr / atomic-time-unit.
Theory¶
Born-Oppenheimer molecular dynamics integrates Newton’s equations for the nuclei, \(m_i\ddot{\mathbf r}_i = \mathbf F_i = -\nabla_i E(\mathbf R)\), on the electronic potential-energy surface that the force provider evaluates at every step. The driver uses the velocity-Verlet scheme (Swope, William C., Andersen, Hans C., et al. (1982). *A computer simulation method for the calculation of equilibrium constants for the formation of physical clusters of molecules: Application to small water clusters.* Journal of Chemical Physics, **76**(1), 637-649. doi:[10.1063/1.442716](https://doi.org/10.1063/1.442716)),
which needs one force evaluation per step, is time reversible and
symplectic, and therefore conserves a shadow Hamiltonian: the total energy
oscillates with an amplitude proportional to \(\Delta t^2\) but shows no
secular drift. That conservation is the consistency test between a method’s
energy and its gradient, and MDTrajectory.energy_drift() reports it. The
instantaneous temperature is defined from the kinetic energy,
\(T = 2K/(N_f k_B)\), with \(N_f\) the number of nuclear degrees of freedom the
driver counts after removing the centre-of-mass motion.
Two thermostats turn the microcanonical run into a canonical one. The Berendsen weak-coupling thermostat (Berendsen, Herman J. C., Postma, J. P. M., et al. (1984). *Molecular dynamics with coupling to an external bath.* Journal of Chemical Physics, **81**(8), 3684-3690. doi:[10.1063/1.448118](https://doi.org/10.1063/1.448118)) rescales the velocities after each step by
so the kinetic temperature relaxes exponentially towards the target \(T_0\)
with the time constant \(\tau_T\) (thermostat_tau_fs). It is robust and
quick to equilibrate, but it suppresses the kinetic-energy fluctuations of
the canonical ensemble and has no conserved quantity, so it is an
equilibration tool rather than a sampling one. The Nose-Hoover thermostat
(Nosé, Shuichi (1984). *A unified formulation of the constant temperature molecular dynamics methods.* Journal of Chemical Physics, **81**(1), 511-519. doi:[10.1063/1.447334](https://doi.org/10.1063/1.447334), Hoover, William G. (1985). *Canonical dynamics: Equilibrium phase-space distributions.* Physical Review A, **31**(3), 1695-1697. doi:[10.1103/PhysRevA.31.1695](https://doi.org/10.1103/PhysRevA.31.1695))
couples the system to one extended degree of freedom, a friction \(\zeta\)
with the thermostat mass \(Q\),
integrated as symmetric half-step brackets around the velocity-Verlet
update. For an ergodic system its trajectories sample the canonical
distribution (a single thermostat on a purely harmonic system is not
ergodic), and the extended energy
\(H_{\mathrm{NH}} = K + E + \tfrac12 Q\zeta^2 + N_f k_B T_0\,\eta\) with
\(\dot\eta = \zeta\) is conserved, which is what conserved_energy and
energy_drift() monitor under NVT. The general driver adds no
approximation of its own beyond the finite time step; what limits it in
practice is the cost of the force provider, which for MSINDO is a
finite-difference gradient.
Ensembles and thermostats¶
Ensemble |
|
Reference |
|---|---|---|
NVE (microcanonical) |
|
velocity Verlet (Swope 1982) |
NVT (canonical) |
|
Berendsen weak coupling (1984) |
NVT (canonical) |
|
Nosé 1984 / Hoover 1985 |
NVE uses the symplectic velocity-Verlet integrator, which conserves the total energy with no secular drift (the oscillation amplitude scales ∝ Δt²).
Berendsen rescales the velocities each step to relax the kinetic temperature toward the target with a coupling time
thermostat_tau_fs. It is robust and strongly damping but does not sample the exact canonical ensemble.Nosé-Hoover is a single extended-system thermostat with a genuine conserved quantity
H_NH = KE + PE + ½Qζ² + N k_B T η; it samples the true canonical distribution. (A single thermostat on purely harmonic modes is non-ergodic, Martyna-Klein-Tuckerman 1992, so realistic anharmonic systems sample best.)
Running MD on the MSINDO surface¶
run_msindo_md is the MSINDO-aware convenience wrapper. It takes the initial
geometry in Ångström, builds the MSINDO energy+gradient provider, and returns
an MDTrajectory:
import numpy as np
from vibeqc.semiempirical.methods.msindo import run_msindo_md
Z = [8, 1, 1] # H2O
xyz = np.array([[0.0, 0.0, 0.0],
[0.0, 0.7572, 0.5865],
[0.0, -0.7572, 0.5865]]) # Ångström
# Microcanonical (NVE): check energy conservation.
traj = run_msindo_md(Z, xyz, timestep_fs=0.3, n_steps=50,
temperature_K=300.0, thermostat=None, seed=1)
print("E drift:", traj.energy_drift(), "Ha")
# Canonical (NVT) with a Nose-Hoover thermostat.
traj = run_msindo_md(Z, xyz, timestep_fs=0.3, n_steps=200,
temperature_K=300.0, thermostat="nose_hoover",
thermostat_tau_fs=25.0, seed=1, output="h2o_md")
print("mean T:", traj.mean_temperature(), "K")
Warning
MSINDO exposes a finite-difference gradient, so every MD step costs
6N + 1 SCFs. This is fine for short trajectories on small molecules but is
not a production MD engine; keep n_steps modest.
MDTrajectory¶
run_md returns an MDTrajectory dataclass with one entry per recorded
frame (record_stride controls the recording cadence): times_fs,
positions, velocities, potential_energy, kinetic_energy,
total_energy, temperature, and conserved_energy (the total plus the
thermostat bath energy, for NVE this equals the total energy; for
Nosé-Hoover it is H_NH). Convenience methods:
energy_drift(), max deviation of the conserved quantity from its initial value (the NVE energy drift, or theH_NHdrift under Nosé-Hoover).mean_temperature(skip_fraction=0.5), mean temperature over the last portion of the run (discarding equilibration).
Driving any method¶
Because the driver only needs a (coords) -> (energy, gradient) callable, you
can wrap any vibe-qc potential. For MSINDO, msindo_force_provider builds the
callable directly:
from vibeqc.md import run_md, run_nvt
from vibeqc.semiempirical.methods.msindo import msindo_force_provider
provider = msindo_force_provider([8, 1, 1]) # -> fn(coords_bohr)
traj = run_nvt(provider, coords_bohr, atomic_numbers=[8, 1, 1],
temperature_K=300.0, thermostat="berendsen", n_steps=100)
Well-tempered metadynamics¶
vibeqc.metadynamics layers well-tempered metadynamics on the MD driver:
a history-dependent Gaussian bias is deposited on a small set of collective
variables (CVs), pushing the system out of free-energy minima it has already
visited so it explores rare events and reconstructs the free-energy surface.
Collective variables are interatomic DistanceCV(i, j) and AngleCV(i, j, k)
(each supplies its value and the Cartesian gradient ∂s/∂R); the bias is added
to the energy+gradient the MD driver integrates, and hills are deposited on a
fixed stride. In the well-tempered scheme (Barducci-Bussi-Parrinello 2008)
each hill’s height is damped by the bias already present, so the bias
converges and the free energy follows as
F(s) = −γ / (γ − 1) · V_bias(s) + const (γ = bias factor)
import numpy as np
from vibeqc.metadynamics import DistanceCV, run_metadynamics
# Bias the distance between atoms 0 and 1 (force_fn = any energy+gradient).
res = run_metadynamics(
force_fn, coords_bohr, [DistanceCV(0, 1)], atomic_numbers=[8, 1, 1],
bias_factor=8.0, hill_height=8e-4, hill_sigma=0.15,
deposition_stride=10, n_steps=16000, temperature_K=300.0,
thermostat="berendsen")
grid = np.linspace(1.9, 4.1, 221) # CV values to evaluate
fes = res.free_energy(grid) # reconstructed free energy (min 0)
run_metadynamics returns a MetadynamicsResult with the (biased) MD
trajectory, the cv_trajectory (CV values per frame), and the accumulated
bias; result.free_energy(grid) reconstructs the profile and
result.bias_potential(grid) returns the raw bias. Metadynamics runs NVT, so
a thermostat is required (default Nosé-Hoover).
On the MSINDO surface use run_msindo_metadynamics(Z, xyz_angstrom, cvs, ...)
(vibeqc.semiempirical.methods.msindo). Because each MD step costs 6N + 1
SCFs and filling a basin needs many steps, MSINDO metadynamics is for tiny
systems / short demonstrations; the headline free-energy recovery is validated
on an analytic double well in
examples/semiempirical/25_msindo_metadynamics.py.
Metadynamics and conical intersections¶
Both enhanced-sampling layers in vibe-qc are method-agnostic and sit on the same energy+gradient seam as the MD driver; neither is tied to MSINDO.
vibeqc.metadynamicsis a layer overvibeqc.md.run_md.run_metadynamics(force_fn, coords, cvs, ...)wraps any force provider, adds the bias energy and its chain-rule gradient through the collective variablesDistanceCV(i, j)andAngleCV(i, j, k), and deposits Gaussian hills on a fixed stride. In the well-tempered scheme (Laio, Alessandro and Parrinello, Michele (2002). *Escaping free-energy minima.* Proceedings of the National Academy of Sciences, **99**(20), 12562-12566. doi:[10.1073/pnas.202427399](https://doi.org/10.1073/pnas.202427399), Barducci, Alessandro, Bussi, Giovanni, and Parrinello, Michele (2008). *Well-tempered metadynamics: A smoothly converging and tunable free-energy method.* Physical Review Letters, **100**(2), 020603. doi:[10.1103/PhysRevLett.100.020603](https://doi.org/10.1103/PhysRevLett.100.020603)) the height of hill \(k\) is damped by the bias already present, \(w_k = w_0\exp[-V(s_k)/(k_B\,\Delta T)]\) with the bias factor \(\gamma = (T+\Delta T)/T\), so the bias converges and \(F(s) = -\tfrac{\gamma}{\gamma-1}V(s) + \mathrm{const}\).run_msindo_metadynamicsis only the MSINDO-specific convenience wrapper.vibeqc.conicallocates a minimum-energy conical intersection with the Levine-Coe-Martinez penalty function (Levine, Benjamin G., Coe, Joshua D., and Martínez, Todd J. (2008). *Optimizing conical intersections without derivative coupling vectors: Application to multistate multireference second-order perturbation theory (MS-CASPT2).* Journal of Physical Chemistry B, **112**(2), 405–413. doi:[10.1021/jp0761618](https://doi.org/10.1021/jp0761618)), \(F_\sigma = \tfrac12(E_I + E_J) + \sigma\,\Delta E^2/(\Delta E + \alpha)\), escalating \(\sigma\) until the gap closes. It needs only the two state energies and their gradients, no derivative coupling, sooptimize_conical_intersectionaccepts any two-state(E, gradient)callback:make_cis_meci_fnbuilds one from an HF-CIS energy function with finite-difference gradients (vibeqc.excited_gradient.make_hf_cis_energy_fn) or from MSINDO CIS (msindo_meci). The MSINDO guide shows a worked S1/S0 search.
Both layers share the MD driver’s status: they add no electronic approximation of their own, so the accuracy of a free-energy profile or a crossing geometry is that of the electronic method underneath, and the cost is that method’s gradient times the number of steps.
Citations¶
A run cites the velocity-Verlet integrator (Swope et al. 1982) and, when a
thermostat is used, the Berendsen (1984) or Nosé-Hoover (Nosé 1984 + Hoover
1985) papers, in addition to the underlying method (e.g. the MSINDO papers).
A metadynamics run additionally cites metadynamics (Laio-Parrinello 2002) and
the well-tempered variant (Barducci-Bussi-Parrinello 2008).
run_msindo_md(..., output="stem") / run_msindo_metadynamics(..., output=...)
write the stem.bibtex / stem.references sidecars; see
Citations.
See also¶
Geometry optimization and NEB, the other energy+gradient drivers.
Semiempirical methods and the MSINDO guide for the underlying engine.