InnerProductCoupling¶
- class openxps.couplings.InnerProductCoupling(forces, dynamical_variables, functions=None, **parameters)[source]¶
Coupling defined by the inner product of two separable vector-valued functions.
Use this class if the coupling energy is the inner product of a vector-valued function \({\boldsymbol \lambda}\) of the extended dynamical variables \({\bf s}\) and a vector-valued function \({\bf u}\) of the physical coordinates \({\bf r}\), i.e.,
\[U = {\boldsymbol \lambda}({\bf s}) \cdot {\bf u}({\bf r}) = \sum_{i=1}^n \lambda_i({\bf s}) u_i({\bf r})\]where \(n\) is the dimensionality of the vector-valued functions.
The extension system receives the parameter derivatives \(u_i = \partial U / \partial \lambda_i\) evaluated in the physical context, so the forces on the dynamical variables follow the chain rule exactly. The extension potential energy equals the coupling energy only if \(U\) is linear in each \(\lambda_i\), which is also required for multiple time-step schemes such as
SplitIntegrator, where the derivatives are held fixed during the extension substeps.Functions receive the dynamical variables wrapped into their bounds, so periodic and reflective variables enter them with the same values reported by
ExtendedSpaceContext.getDynamicalVariableValues().Inner product couplings combined in a sum are merged into a single coupling, so forces from different couplings may share global parameters. Shared functions must have identical definitions. Forces outside the coupling must not depend on its parameters.
- Parameters:
forces (Iterable[Force]) – A sequence of openmm.Force objects whose sum depends linearly on a vector of \(n\) global context parameters.
dynamical_variables (Iterable[DynamicalVariable]) – The dynamical variables of the extended phase-space system.
functions (dict[str, str] | None) – A dictionary defining global context parameters (keys) as mathematical functions (values) of the dynamical variables. It is not necessary to include identity functions (i.e.,
key=value).**parameters (Quantity) – Named parameters that appear in the mathematical expressions.
Examples
>>> from copy import copy >>> from collections import namedtuple >>> import cvpack >>> import openxps as xps >>> from openmm import unit >>> from math import pi >>> import openmm as mm >>> from openmmtools import testsystems >>> model = testsystems.AlanineDipeptideVacuum()
A function to remove Coulomb interactions:
>>> Parameters = namedtuple( ... "Parameters", ... ["index", "charge", "sigma", "epsilon"], ... ) >>> def remove_coulomb_interaction( ... force: mm.NonbondedForce, p1: Parameters, p2: Parameters ... ) -> None: ... force.addException( ... p1.index, ... p2.index, ... 0.0, ... (p1.sigma + p2.sigma)/2, ... (p1.epsilon * p2.epsilon).sqrt(), ... )
Remove carbonyl oxygen <=> amide hydrogen interactions:
>>> nbforce = next( ... f for f in model.system.getForces() ... if isinstance(f, mm.NonbondedForce) ... ) >>> O1 = Parameters(5, *nbforce.getParticleParameters(5)) >>> H1 = Parameters(7, *nbforce.getParticleParameters(7)) >>> O2 = Parameters(15, *nbforce.getParticleParameters(15)) >>> H2 = Parameters(17, *nbforce.getParticleParameters(17)) >>> remove_coulomb_interaction(nbforce, O1, H2) >>> remove_coulomb_interaction(nbforce, O2, H1)
Add scaled Coulomb interactions:
>>> force = mm.CustomBondForce(f"scaling*chargeProd/r") >>> _ = force.addGlobalParameter("scaling", 1.0) >>> _ = force.addEnergyParameterDerivative("scaling") >>> _ = force.addPerBondParameter("chargeProd") >>> _ = force.addBond(O1.index, H2.index, [O1.charge*H2.charge]) >>> _ = force.addBond(O2.index, H1.index, [O2.charge*H1.charge])
Create a coupling between the dynamical variable and the nonbonded force:
>>> lambda_dv = xps.DynamicalVariable( ... name="lambda", ... unit=unit.dimensionless, ... mass=1.0 * unit.dalton * unit.nanometer**2, ... bounds=xps.ReflectiveBounds(0.0, 1.0, unit.dimensionless), ... ) >>> coupling = xps.InnerProductCoupling( ... [force], ... [lambda_dv], ... functions={"scaling": "(1-cos(alpha*lambda))/2"}, ... alpha=pi*unit.radian, ... ) >>> context = xps.ExtendedSpaceContext( ... xps.ExtendedSpaceSystem(model.system, coupling), ... xps.LockstepIntegrator(mm.VerletIntegrator(1.0 * mmunit.femtosecond)), ... mm.Platform.getPlatformByName("Reference"), ... ) >>> context.setPositions(model.positions) >>> context.setDynamicalVariableValues([1.0])
Methods
- addToPhysicalSystem(system)[source]¶
Add this coupling to an OpenMM system.
- Parameters:
system (System) – The system to which the coupling should be added.
- getForceGroups()[source]¶
Get the force groups of the coupling forces, which are empty until the coupling is added to a physical system.
- Return type:
set[int]
- classmethod merge(couplings)[source]¶
Merge inner product couplings into a single one.
A sum of inner product couplings whose forces share global parameters must be handled as a single coupling, so that the parameter derivatives of all forces are accumulated before reaching the extension system.
- Parameters:
couplings (Sequence[InnerProductCoupling]) – The inner product couplings to merge.
- Returns:
A coupling with all forces, dynamical variables, functions and parameters of the merged couplings.
- Return type:
- Raises:
ValueError – If two couplings define the same dynamical variable, function or parameter differently.
- updateExtensionContext(physical_context, extension_context)[source]¶
Update the extension context with the current physical parameters.
- Parameters:
physical_context (Context) – The physical context to get the physical parameters from.
extension_context (Context) – The extension context to update with the physical parameters.