Backend API Reference
The backend module provides interfaces for integrating GADES with different molecular dynamics engines.
Overview
GADES supports multiple simulation backends:
- OpenMMBackend: For OpenMM-based simulations
- ASEBackend: For ASE (Atomic Simulation Environment) based simulations
ASE Backend
The ASE backend allows GADES to work with any calculator supported by ASE, including LAMMPS, VASP, Quantum ESPRESSO, and many others.
Quick Start with with_gades Factory Method
The recommended way to create an ASE backend with GADES bias is using the with_gades factory method:
from GADES.backend import ASEBackend
from GADES.utils import compute_hessian_force_fd_richardson as hessian
backend = ASEBackend.with_gades(
atoms=atoms,
base_calc=lammps_calc,
bias_atom_indices=biasing_atom_ids,
hess_func=hessian,
clamp_magnitude=1000,
kappa=0.9,
interval=100,
stability_interval=1000,
)
# Attach integrator for step tracking
backend.integrator = dyn
# Access GADESBias if needed
print(backend.gades_bias.kappa)
Understanding the Architecture
The ASE integration involves three interconnected components:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ GADESBias │────▶│ GADESCalculator │────▶│ ASEBackend │
│ │◀────│ │◀────│ │
│ Computes bias │ │ Wraps base calc │ │ Manages │
│ forces along │ │ and adds GADES │ │ atoms and │
│ softest mode │ │ bias to forces │ │ state │
└─────────────────┘ └──────────────────┘ └─────────────┘
│ │
└───────────────────────────────────────────────┘
Circular reference
This creates a circular dependency at initialization time:
GADESBiasneeds aBackendto query forces and positionsGADESCalculatorneeds aGADESBiasto compute bias forcesASEBackendneeds aGADESCalculatorto wrap
The with_gades factory method solves this by handling the wiring internally.
API Reference
Backend
Backend()
A generic interface for the backends to be used with GADES.
Subclasses must implement all methods that raise NotImplementedError.
Methods with default implementations (is_stable, get_currentStep)
may be overridden if the backend provides more accurate information.
Source code in GADES/backend.py
40 41 | |
is_stable
is_stable()
Check if the simulation is numerically stable.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if stable. Default implementation always returns True. |
Source code in GADES/backend.py
43 44 45 46 47 48 49 50 | |
get_currentStep
get_currentStep()
Get the current simulation step number.
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
Current step count. Default implementation returns 0. |
Source code in GADES/backend.py
52 53 54 55 56 57 58 59 | |
get_atom_symbols
get_atom_symbols(bias_atom_indices)
Get the chemical symbols for the specified atoms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bias_atom_indices
|
Sequence[int]
|
Indices of atoms to get symbols for. |
required |
Returns:
| Type | Description |
|---|---|
List[str]
|
List[str]: Chemical symbols for each atom. |
Source code in GADES/backend.py
61 62 63 64 65 66 67 68 69 70 71 | |
get_positions
get_positions()
Retrieve the current atom positions.
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Positions array with shape |
Source code in GADES/backend.py
73 74 75 76 77 78 79 80 | |
get_current_state
get_current_state()
Get the current positions and forces.
Returns:
| Type | Description |
|---|---|
Tuple[ndarray, ndarray]
|
Tuple[np.ndarray, np.ndarray]: (positions, forces) arrays. |
Source code in GADES/backend.py
82 83 84 85 86 87 88 89 | |
get_forces
get_forces(positions)
Compute forces at the given positions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
positions
|
ndarray
|
Atom positions with shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Flattened forces array with shape |
Source code in GADES/backend.py
91 92 93 94 95 96 97 98 99 100 101 | |
apply_bias
apply_bias(bias_force_object, biased_force_values, bias_atom_indices)
Apply bias forces to the specified atoms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bias_force_object
|
Any
|
Backend-specific force object. |
required |
biased_force_values
|
ndarray
|
Bias force values with shape |
required |
bias_atom_indices
|
Sequence[int]
|
Indices of atoms to bias. |
required |
Source code in GADES/backend.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
remove_bias
remove_bias(bias_force_object, bias_atom_indices)
Remove bias forces from the specified atoms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bias_force_object
|
Any
|
Backend-specific force object. |
required |
bias_atom_indices
|
Sequence[int]
|
Indices of atoms to unbias. |
required |
Source code in GADES/backend.py
119 120 121 122 123 124 125 126 127 128 129 | |
OpenMMBackend
OpenMMBackend(simulation, target_temperature=None)
Bases: Backend
A wrapper for OpenMM to be used as a backend for GADES.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
simulation
|
Simulation
|
The OpenMM Simulation object. |
required |
target_temperature
|
Optional[float]
|
Target temperature in Kelvin for stability checking. If not provided, the backend will attempt to read it from the integrator (works for LangevinIntegrator, LangevinMiddleIntegrator, etc.). If neither is available, stability checking will be skipped with a warning. |
None
|
Raises:
| Type | Description |
|---|---|
ImportError
|
If OpenMM is not installed. |
Source code in GADES/backend.py
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | |
is_stable
is_stable()
Check if the simulation is stable by comparing instantaneous temperature to the target temperature.
This method estimates the instantaneous temperature from the system's
kinetic energy and compares it to the target temperature. If the deviation
exceeds the stability threshold (configurable via
defaults["stability_threshold_temp_diff"]), the system is considered unstable.
If no target temperature is available (not set explicitly and cannot be read from the integrator), a warning is issued once and the method returns True (stability check skipped).
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if stable or if stability check is skipped, False if unstable. |
Note
- For a small number of biased DOFs, this criterion might give false positives.
- The DOF calculation accounts for particles with mass, constraints, and
CMMotionRemover. It may be inaccurate for systems with virtual sites,
rigid bodies, barostats, or other motion removers. For such systems,
set
target_temperatureexplicitly in the constructor.
Source code in GADES/backend.py
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | |
get_positions
get_positions()
Retrieve the current atom positions from the OpenMM context.
Source code in GADES/backend.py
278 279 280 281 282 | |
get_forces
get_forces(positions)
Compute the original (unbiased) forces from an OpenMM context (internal use only).
This function updates the context with the provided positions, then retrieves
forces from force group 0 only. Group 0 is assumed to contain the system's
physical potential (e.g., the force field / PMF), while GADES bias forces are
assigned to a separate group (default: group 1, configurable via
defaults["gades_force_group"]).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
positions
|
ndarray
|
Atomic positions, shaped |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Flattened force vector of shape |
Notes
Original positions are restored after force computation.
Important
Force group 0 is hard-coded (see line with groups={0} below).
If your simulation has physical forces in other groups (e.g., groups 2, 3),
they will be excluded from Hessian and bias calculations. For most OpenMM
simulations this is not an issue since all forces default to group 0.
If you need to include forces from multiple groups, modify the
groups={0} parameter in this method to include all relevant groups,
excluding only the GADES force group.
Source code in GADES/backend.py
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | |
apply_bias
apply_bias(bias_force_object, biased_force_values, bias_atom_indices)
Apply the bias forces to the specified atoms in the OpenMM simulation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bias_force_object
|
CustomExternalForce
|
CustomExternalForce object. |
required |
biased_force_values
|
ndarray
|
Array of bias forces, shape |
required |
bias_atom_indices
|
Sequence[int]
|
List of atom indices to apply the bias to. |
required |
Source code in GADES/backend.py
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | |
remove_bias
remove_bias(bias_force_object, bias_atom_indices)
Remove the bias forces from the specified atoms in the OpenMM simulation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bias_force_object
|
CustomExternalForce
|
CustomExternalForce object. |
required |
bias_atom_indices
|
Sequence[int]
|
List of atom indices to remove the bias from. |
required |
Source code in GADES/backend.py
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | |
ASEBackend
ASEBackend(calculator, atoms, target_temperature=None)
Bases: Backend
A wrapper for ASE to be used as a backend for GADES.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
calculator
|
GADESCalculator
|
The custom ASE Calculator (i.e. GADESCalculator) that includes GADES bias forces. |
required |
atoms
|
Atoms
|
The ASE Atoms object. |
required |
target_temperature
|
Optional[float]
|
Target temperature in Kelvin for stability checking.
It is strongly recommended to set this explicitly. If not provided,
the backend will attempt to read it from the integrator (works for
|
None
|
Raises:
| Type | Description |
|---|---|
ImportError
|
If ASE is not installed. |
Source code in GADES/backend.py
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | |
get_atoms
get_atoms()
Return the list of atoms in the ASE Atoms object.
Each entry is an Atom object, e.g.
Atom('Ar', [0.0, 0.0, 0.0], index=0).
Source code in GADES/backend.py
601 602 603 604 605 606 607 608 | |
get_atom_symbols
get_atom_symbols(bias_atom_indices)
Return the atomic symbols for the specified atom indices.
Source code in GADES/backend.py
610 611 612 613 614 615 616 617 618 619 | |
get_currentStep
get_currentStep()
Return the current MD step from the integrator.
Returns:
| Type | Description |
|---|---|
int
|
Current step number, or -1 if there is no integrator associated |
int
|
with the backend. |
Source code in GADES/backend.py
621 622 623 624 625 626 627 628 629 630 631 632 633 | |
get_positions
get_positions()
Retrieve the current atom positions.
Source code in GADES/backend.py
635 636 637 | |
get_current_state
get_current_state()
Retrieve the current atom positions and total forces (including bias).
Returns:
| Type | Description |
|---|---|
Tuple[ndarray, ndarray]
|
Tuple of (positions, forces) arrays, both with shape |
Source code in GADES/backend.py
639 640 641 642 643 644 645 646 647 648 | |
get_forces
get_forces(positions)
Compute the original (unbiased) forces from the base calculator.
This function updates the base calculator with the provided positions, then retrieves forces. The forces are flattened into a 1D array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
positions
|
ndarray
|
Atomic positions, shaped |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Flattened force vector of shape |
Notes
Original positions are restored after force computation.
Source code in GADES/backend.py
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | |
is_stable
is_stable()
Check if the simulation is stable by comparing instantaneous temperature to the target temperature.
The system is considered unstable if the temperature deviates by more than
defaults["stability_threshold_temp_diff"] from the target. If no target
temperature is available (not set explicitly and cannot be read from the
integrator), a warning is issued once and the method returns True (stability
check skipped).
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if stable or if stability check is skipped, False if unstable. |
Source code in GADES/backend.py
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | |
apply_bias
apply_bias(bias_force_object, biased_force_values, bias_atom_indices)
Apply bias forces by storing them in GADESCalculator.
This method stores the bias values in the calculator's internal state, which will be added to forces during each calculate() call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bias_force_object
|
Any
|
Unused for ASE (exists for API compatibility). |
required |
biased_force_values
|
ndarray
|
Bias force values with shape |
required |
bias_atom_indices
|
Sequence[int]
|
Indices of atoms to bias. |
required |
Source code in GADES/backend.py
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | |
remove_bias
remove_bias(bias_force_object, bias_atom_indices)
Remove bias forces by clearing GADESCalculator's stored bias.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bias_force_object
|
Any
|
Unused for ASE (exists for API compatibility). |
required |
bias_atom_indices
|
Sequence[int]
|
Unused for ASE (exists for API compatibility). |
required |
Source code in GADES/backend.py
783 784 785 786 787 788 789 790 791 792 793 794 795 | |
with_gades
classmethod
with_gades(atoms, base_calc, bias_atom_indices, hess_func, clamp_magnitude, kappa, interval, stability_interval=None, logfile_prefix=None, eigensolver='numpy', lanczos_iterations=None, use_bofill_update=False, full_hessian_interval=None, hvp_epsilon=None, target_temperature=None)
Factory method to create an ASEBackend with GADES bias fully configured.
This method handles all the internal wiring between GADESBias, GADESCalculator, and ASEBackend, eliminating the need for manual post-initialization patching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
The ASE Atoms object. |
required |
base_calc
|
Calculator
|
The base ASE Calculator (e.g., LAMMPS, EMT). |
required |
bias_atom_indices
|
Sequence[int]
|
Indices of atoms that should receive the bias force. |
required |
hess_func
|
Callable
|
Function to compute the Hessian matrix. |
required |
clamp_magnitude
|
float
|
Maximum magnitude for bias force components. |
required |
kappa
|
float
|
Scaling factor (0 < κ < 1) for the bias force. |
required |
interval
|
int
|
Number of steps between bias force updates. |
required |
stability_interval
|
Optional[int]
|
Steps between stability checks (optional). |
None
|
logfile_prefix
|
Optional[str]
|
Prefix for log files (optional). |
None
|
eigensolver
|
str
|
Method for computing softest eigenmode ('numpy', 'lanczos', or 'lanczos_hvp'). |
'numpy'
|
lanczos_iterations
|
Optional[int]
|
Number of Lanczos iterations (if using 'lanczos' or 'lanczos_hvp'). |
None
|
use_bofill_update
|
bool
|
Whether to use Bofill Hessian updates. |
False
|
full_hessian_interval
|
Optional[int]
|
Steps between full Hessian recomputation (if using Bofill). |
None
|
hvp_epsilon
|
Optional[float]
|
Finite difference step size for HVP (if using 'lanczos_hvp'). |
None
|
target_temperature
|
Optional[float]
|
Target temperature in Kelvin for stability checking. It is strongly recommended to set this explicitly rather than relying on auto-detection from the integrator, which is fragile across different ASE integrator types. |
None
|
Returns:
| Type | Description |
|---|---|
ASEBackend
|
Fully configured ASEBackend with |
Example
from GADES.backend import ASEBackend from GADES.utils import compute_hessian_force_fd_richardson as hessian
backend = ASEBackend.with_gades( ... atoms=atoms, ... base_calc=lammps_calc, ... bias_atom_indices=biasing_atom_ids, ... hess_func=hessian, ... clamp_magnitude=1000, ... kappa=0.9, ... interval=100, ... stability_interval=1000, ... ) backend.integrator = dyn # Attach integrator for step tracking
Source code in GADES/backend.py
797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 | |
GADESCalculator
GADESCalculator(base_calc, gades_force_updater)
Bases: Calculator
ASE Calculator wrapper that adds GADES bias forces to an existing ASE Calculator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_calc
|
Calculator
|
The base ASE Calculator to which GADES bias forces will be added. |
required |
gades_force_updater
|
Any
|
The GADES force updater object responsible for computing and applying bias forces. |
required |
Raises:
| Type | Description |
|---|---|
ImportError
|
If ASE is not installed. |
Source code in GADES/backend.py
502 503 504 505 506 507 508 509 510 511 512 | |