ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
|
To add a new bonded interaction, the following steps are required:
src/core/bonded_interactions
.ScriptInterface
class of the new bond type, which serves as the connection between the C++ core and the Python representation of the bond.BondedInteraction
base classEvery interaction resides in its own source .hpp file. A simple example for a bonded interaction is the FENE bond in fene.hpp. Use this file as template for your new interaction.
The first step is to create a new struct
which represents your new bond type inside the .hpp file. It needs to have the following members:
cutoff()
should be as large as the interaction range of the new interaction. This is only relevant to pairwise bonds. In all other cases, the return value should be 0, namely angle bonds, dihedral bonds as well as other bonds that don't have an interaction range. The VirtualBond is the exception to this rule; its range is BONDED_INACTIVE_CUTOFF to ensure that it is always skipped by the short-range loop.std::tuple
with three or four force vectors has to be returned, respectively.std::optional
container if the bond is breakable. If the bond is broken, the returned object is empty; this will stop the integrator with a runtime error.dx
) pointing from particle 2 to particle 1, that takes periodic boundary conditions into account.In most cases, there are three files that need to be updated to integrate the new bond type into the core, namely
In some cases, you may also need to modify pressure_inline.hpp.
if
- else
chain, like in the following example if
- else
chain that corresponds to the correct number of bond partners.if
- else
chain, like in the following example Note that the force and energy functions cannot alter the particle states.
ScriptInterface
.YourNewBond
is the core type you defined.m_bonded_ia
shall be initialized using the parameters that are given in params
. Use the construct_bond()
method of FeneBond
as a template. An instance of the core type YourNewBond
should be initialized, which is then used to initialize a std::shared_ptr
to a Bonded_IA_Parameters, which is then assigned to m_bonded_ia
. The values of the parameters are extracted from params
using parameter_type
is the type of the parameter, e.g. double
or int
or even std::string
, and "parameter_name"
must be replaced by the name of the respective parameter. This name must be the same as in the Python interface, but may differ from the name in the core interaction type. It is, however, recommended to use the same names for both the Python interface and the ESPResSo core for consistency whenever possible.FeneBond
. All it needs to do is to register its parameters so they can be set from Python. For this purpose, call AutoParameter
(see AutoParameter.hpp). One of many ways to initialize these parameters is to pass the parameter name as a string, a custom setter and a custom getter function. The parameters are typically made read-only by passing AutoParameter::read_only
instead of a setter function. The getter function can be a lambda function, which is directly passed to the constructor.ScriptInterface
can find it by its name. In the function initialize
add a new line of the form YourNewBond
must be replaced by the name of your new bond type. The string is used to match the ScriptInterface
class with the Python class (see below).src/python/espressomd/interactions.py
:BONDED_IA
. The order of the enum values must match the order of types in Bonded_IA_Parameters exactly: YourNewBond
. This connects the ScriptInterface
class with the Python class. The type number is the new enum value from BONDED_IA
.testsuite/python/interactions_bonded_interface.py
:testsuite/python/interactions_bonded.py
or testsuite/python/interactions_bond_angle.py
or testsuite/python/interactions_dihedral.py
:This section uses the particle force expressions derived in [40].
The gradient of the potential at particle \( i \) is given by the chain rule in equation 6:
\begin{equation} \label{eq:Swope-eq-6} \nabla_i U(\theta_{ijk}) = \left( \frac{\mathrm{d}U(\theta_{ijk})}{\mathrm{d}\theta_{ijk}} \right) \left( \frac{\mathrm{d}\theta_{ijk}}{\mathrm{d}\cos(\theta_{ijk})} \right) \left( \nabla_i \cos(\theta_{ijk}) \right) \end{equation}
with
\[ \left( \frac{\mathrm{d}\theta_{ijk}}{\mathrm{d}\cos(\theta_{ijk})} \right) = \left( \frac{-1}{\sin(\theta_{ijk})} \right) \]
and \( \theta_{ijk} \) the angle formed by the three particles, \( U(\theta_{ijk}) \) the bond angle potential, \( \vec{r_{ij}} \) the vector from particle \( j \) to particle \( i \) and \( \nabla_i \) the gradient in the direction \( \vec{r_{ij}} \).
The expression for \( \cos(\theta_{ijk}) \) is given by equation 4:
\begin{equation} \label{eq:Swope-eq-4} \cos(\theta_{ijk}) = \frac{\vec{r_{ij}}\cdot\vec{r_{kj}}} {\left\|\vec{r_{ij}}\right\|\left\|\vec{r_{kj}}\right\|} \end{equation}
The expression for its gradient is given by equation 9:
\begin{equation} \label{eq:Swope-eq-9} \nabla_i \cos(\theta_{ijk}) = \vec{e_x}\frac{\partial\cos(\theta_{ijk})}{\partial x_{ij}} + \vec{e_y}\frac{\partial\cos(\theta_{ijk})}{\partial y_{ij}} + \vec{e_z}\frac{\partial\cos(\theta_{ijk})}{\partial z_{ij}} \end{equation}
with \( \left(\vec{e_x}, \vec{e_y}, \vec{e_z}\right) \) the unit vectors of the reference coordinate system and \( \vec{r_{ij}} = \left(x_{ij}, y_{ij}, z_{ij}\right) \).
Applying the quotient rule:
\[ \frac{\partial\cos(\theta_{ijk})}{\partial x_{ij}} = \frac{\partial}{\partial x_{ij}} \left( \frac{\vec{r_{ij}}\cdot\vec{r_{kj}}} {\left\|\vec{r_{ij}}\right\|\left\|\vec{r_{kj}}\right\|} \right) = \frac{\left\|\vec{r_{ij}}\right\|\left\|\vec{r_{kj}}\right\| \partial \left(\vec{r_{ij}}\cdot\vec{r_{kj}}\right) /\, \partial x_{ij} - \vec{r_{ij}}\cdot\vec{r_{kj}}\cdot \partial \left( \left\|\vec{r_{ij}}\right\|\left\|\vec{r_{kj}}\right\| \right) /\, \partial x_{ij}} {\left\|\vec{r_{ij}}\right\|^2\left\|\vec{r_{kj}}\right\|^2} \]
with
\[ \frac{\partial \left(\vec{r_{ij}}\cdot\vec{r_{kj}}\right)} {\partial x_{ij}} = \frac{\partial \left(x_{ij} \cdot x_{kj} + y_{ij} \cdot y_{kj} + z_{ij} \cdot z_{kj}\right)} {\partial x_{ij}} = x_{kj} \]
and
\[ \frac{\partial \left(\left\|\vec{r_{ij}}\right\|\left\|\vec{r_{kj}}\right\|\right)} {\partial x_{ij}} = \left\|\vec{r_{kj}}\right\| \frac{\partial}{\partial x_{ij}} \sqrt{x_{ij}^2 + y_{ij}^2 + z_{ij}^2} = \left\|\vec{r_{kj}}\right\| \frac{0.5 \cdot 2 \cdot x_{ij}} {\sqrt{x_{ij}^2 + y_{ij}^2 + z_{ij}^2}} = x_{ij} \frac{\left\|\vec{r_{kj}}\right\|} {\left\|\vec{r_{ij}}\right\|} \]
leading to equation 12:
\begin{align*} \label{eq:Swope-eq-12} \frac{\partial\cos(\theta_{ijk})}{\partial x_{ij}} &= \frac{\left\|\vec{r_{ij}}\right\|\left\|\vec{r_{kj}}\right\|x_{kj} - \vec{r_{ij}}\cdot\vec{r_{kj}}\cdot x_{ij} \left\|\vec{r_{kj}}\right\|\left\|\vec{r_{ij}}\right\|^{-1}} {\left\|\vec{r_{ij}}\right\|^2\left\|\vec{r_{kj}}\right\|^2} \\ &= \frac{x_{kj}} {\left\|\vec{r_{ij}}\right\|\left\|\vec{r_{kj}}\right\|} - \frac{\vec{r_{ij}}\cdot\vec{r_{kj}}\cdot x_{ij}} {\left\|\vec{r_{ij}}\right\|^3\left\|\vec{r_{kj}}\right\|} \\ &= \frac{1}{\left\|\vec{r_{ij}}\right\|} \left( \frac{x_{kj}}{\left\|\vec{r_{kj}}\right\|} - \frac{x_{ij}}{\left\|\vec{r_{ij}}\right\|} \cos(\theta_{ijk}) \right) \end{align*}
Applying these steps to equations 9-11 leads to the force equations for all three particles:
\begin{align*} \vec{F_i} &= - K(\theta_{ijk}) \frac{1}{\left\|\vec{r_{ij}}\right\|} \left( \frac{\vec{r_{kj}}}{\left\|\vec{r_{kj}}\right\|} - \frac{\vec{r_{ij}}}{\left\|\vec{r_{ij}}\right\|} \cos(\theta_{ijk}) \right) \\ \vec{F_k} &= - K(\theta_{ijk}) \frac{1}{\left\lVert\vec{r_{kj}}\right\rVert} \left( \frac{\vec{r_{ij}}}{\left\|\vec{r_{ij}}\right\|} - \frac{\vec{r_{kj}}}{\left\|\vec{r_{kj}}\right\|} \cos(\theta_{ijk}) \right) \\ \vec{F_j} &= -\left(\vec{F_i} + \vec{F_k}\right) \end{align*}
with \( K(\theta_{ijk}) \) the angle force term, which depends on the expression used for the angle potential. Forces \( \vec{F_i} \) and \( \vec{F_k} \) are perpendicular to the displacement vectors \( \vec{r_{ij}} \) resp. \( \vec{r_{kj}} \) and their magnitude are proportional to the potential gradient normalized by the displacement vectors:
\begin{align*} \left\|\vec{F_i}\right\| &= \left( \frac{\mathrm{d}U(\theta_{ijk})}{\mathrm{d}\theta_{ijk}} \right) \frac{1}{\left\|\vec{r_{ij}}\right\|} \\ \left\|\vec{F_k}\right\| &= \left( \frac{\mathrm{d}U(\theta_{ijk})}{\mathrm{d}\theta_{ijk}} \right) \frac{1}{\left\|\vec{r_{kj}}\right\|} \end{align*}
The harmonic angle potential takes the form:
\begin{equation} \label{eq:harmonic-angle-pot} U(\theta_{ijk}) = \frac{1}{2}k_{ijk}\left[\theta_{ijk} - \theta_{ijk}^0\right]^2 \end{equation}
with \( \theta_{ijk} \) the angle formed by the three particles, \( \theta_{ijk}^0 \) the equilibrium angle and \( k_{ijk} \) the bond angle force constant.
The derivative with respect to the angle is:
\[ \frac{\mathrm{d}U(\theta_{ijk})}{\mathrm{d}\theta_{ijk}} = k_{ijk}\left[\theta_{ijk} - \theta_{ijk}^0\right] \]
resulting in the following angle force term:
\begin{equation} \label{eq:harmonic-angle-pot-angle-term} K(\theta_{ijk}) = -k_{ijk}\frac{\theta_{ijk} - \theta_{ijk}^0} {\sin(\theta_{ijk})} \end{equation}
which can lead to numerical instability at \( \theta_{ijk} = 0 \) and \( \theta_{ijk} = \pi \).
The harmonic cosine potential takes the form:
\begin{equation} \label{eq:harmonic-cosine-pot} U(\theta_{ijk}) = \frac{1}{2} k_{ijk}\left[\cos(\theta_{ijk}) - \cos(\theta_{ijk}^0)\right]^2 \end{equation}
with \( \theta_{ijk} \) the angle formed by the three particles, \( \theta_{ijk}^0 \) the equilibrium angle and \( k_{ijk} \) the bond angle force constant.
The derivative with respect to the angle is:
\[ \frac{\mathrm{d}U(\theta_{ijk})}{\mathrm{d}\theta_{ijk}} = -k_{ijk}\sin(\theta_{ijk}) \left[\cos(\theta_{ijk}) - \cos(\theta_{ijk}^0)\right] \]
resulting in the following angle force term:
\begin{equation} \label{eq:harmonic-cosine-pot-angle-term} K(\theta_{ijk}) = k_{ijk}\left[\cos(\theta_{ijk}) - \cos(\theta_{ijk}^0)\right] \end{equation}
which does not suffer from numerical instability.
The cosine potential takes the form:
\begin{equation} \label{eq:cosine-pot} U(\theta_{ijk}) = k_{ijk}\left[1 - \cos(\theta_{ijk} - \theta_{ijk}^0)\right] \end{equation}
with \( \theta_{ijk} \) the angle formed by the three particles, \( \theta_{ijk}^0 \) the equilibrium angle and \( k_{ijk} \) the bond angle force constant.
The derivative with respect to the angle is:
\[ \frac{\mathrm{d}U(\theta_{ijk})}{\mathrm{d}\theta_{ijk}} = k_{ijk}\sin(\theta_{ijk} - \theta_{ijk}^0) \]
resulting in the following angle force term:
\begin{equation} \label{eq:cosine-pot-angle-term} K(\theta_{ijk}) = -k_{ijk}\frac{\sin(\theta_{ijk} - \theta_{ijk}^0)} {\sin(\theta_{ijk})} \end{equation}
which can lead to numerical instability at \( \theta_{ijk} = 0 \) and \( \theta_{ijk} = \pi \).
The tabulated potential and its derivative with respect to the angle are provided by the user. The angle force term takes the form:
\begin{equation} \label{eq:tabulated-pot-angle-term} K(\theta_{ijk}) = \frac{-1}{\sin(\theta_{ijk})} \left( \frac{\mathrm{d}U(\theta_{ijk})}{\mathrm{d}\theta_{ijk}} \right) \end{equation}
which can lead to numerical instability at \( \theta_{ijk} = 0 \) and \( \theta_{ijk} = \pi \).