From b9386e07c0120733918cdce7aa76b3537fe5bad9 Mon Sep 17 00:00:00 2001 From: Roy Kid Date: Tue, 19 Apr 2022 00:12:45 +0800 Subject: [PATCH 1/8] checkout new branch for docs only --- docs/about.md | 3 + docs/admp/{README.md => readme.md} | 6 +- docs/admp/theory.md | 179 ++++++++++++++++++ docs/assets/arch.png | Bin 0 -> 120886 bytes docs/assets/generator.svg | 1 + docs/assets/opemm_workflow.svg | 1 + docs/dev_guide/arch.md | 288 +++++++++++++++++++++++++++++ docs/dev_guide/convention.md | 22 +++ docs/dev_guide/profile.md | 2 + docs/dev_guide/readme.md | 20 ++ docs/dev_guide/write_docs.md | 33 ++++ docs/index.md | 18 +- docs/user_guide/readme.md | 16 ++ docs/user_guide/tutorial.md | 7 + docs/user_guide/xml_spec.md | 207 +++++++++++++++++++++ 15 files changed, 786 insertions(+), 17 deletions(-) rename docs/admp/{README.md => readme.md} (95%) create mode 100644 docs/admp/theory.md create mode 100644 docs/assets/arch.png create mode 100644 docs/assets/generator.svg create mode 100644 docs/assets/opemm_workflow.svg create mode 100644 docs/dev_guide/arch.md create mode 100644 docs/dev_guide/convention.md create mode 100644 docs/dev_guide/profile.md create mode 100644 docs/dev_guide/readme.md create mode 100644 docs/dev_guide/write_docs.md create mode 100644 docs/user_guide/readme.md create mode 100644 docs/user_guide/xml_spec.md diff --git a/docs/about.md b/docs/about.md index e69de29bb..835deeb6f 100644 --- a/docs/about.md +++ b/docs/about.md @@ -0,0 +1,3 @@ +# Lisense + +# Contributor \ No newline at end of file diff --git a/docs/admp/README.md b/docs/admp/readme.md similarity index 95% rename from docs/admp/README.md rename to docs/admp/readme.md index 9ca538f1a..96bb4f0e6 100644 --- a/docs/admp/README.md +++ b/docs/admp/readme.md @@ -20,13 +20,13 @@ ADMP module depends on the following packages, install them before using ADMP: 1. Install [jax](https://github.com/google/jax) (pick the correct cuda version, see more details on their installation guide): - ```bash + ``` pip install jax[cuda11_cudnn82] -f https://storage.googleapis.com/jax-releases/jax_releases.html ``` 2. Install [jax-md](https://github.com/google/jax-md) : - ```bash + ``` pip install jax-md --upgrade ``` @@ -36,7 +36,7 @@ ADMP module depends on the following packages, install them before using ADMP: ADMP is a pure python module, just simply put it in your $PYTHONPATH. - ```bash + ``` export PYTHONPATH=$PYTHONPATH:/path/to/admp ``` diff --git a/docs/admp/theory.md b/docs/admp/theory.md new file mode 100644 index 000000000..a656e5f96 --- /dev/null +++ b/docs/admp/theory.md @@ -0,0 +1,179 @@ +# Theory background + +This project aims to implement an organic force field with a differentiable framework to automatically derivate atomic position, box shape, force field parameters, and other inputs. + +The ADMP force field module has the following interactions: + + +## Electrostatic term + +We can use multipole expansion with cutoff for electrostatic interaction between electron could of atoms. If only the charge (zero-moment) part is retained, it reduces to the point charge model in the classical force field: + +$$V=\sum_{ij} \frac{q_i q_j}{r_{ij}}$$ + +where $q_i$ is the charge number of the atom. + +More complex force field forms can be obtained by increasing truncation of the moment order. Some force fields, such as AMOEBA and MPID, use higher-order truncation. In DMFF, we have up to four moments: + +$$V=\sum_{tu} \hat{Q}_t^A T^{AB}_{tu} \hat{Q}_u^B$$ + +where $Q_t^A$ represents the t-component of multipole moment of atom A, there are two definitions: cartesian coordinates and spherical harmonics. In DMFF, we use spherical harmonics. The sequence is: + +$$0, 10, 1c, 1s, 20, 21c, 21s, 22c, 22s, ...$$ + +The $T_{tu}^{AB}$ represents the interaction tensor among multipoles, which mathematical expression can refer to Ref 1 appendix F. The conversion between different multipole moment definitions and rotation rules can refer to Ref 1 & 5. + +## Multipole moment coordinate system + +Different from charge, multipole moment definition depends on the coordinate system. What we use are mainly three: + + - global frame: coordinate system binds to the simulation box. It same for all atoms. We use this system to calculate charge density structure factor $$S(\vec{k})$$ in reciprocal space. + - local frame: this system defines each atom's coordinate by the positions of its peripheral atoms, and then multipole moment is given under this system. Generally, atomic multipole moments have considerable stability in the local frame, so it is more suitable as a force field parameter input. In DMFF, the definition of the local frame is the same as the AMOEBA plugin in OpenMM. The detail can refer to the following literatures: + * [OpenMM forcefield.py](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py#L4894), line 4894~4933 + * [J. Chem. Theory Comput. 2013, 9, 9, 4046–4063](https://pubs.acs.org/doi/abs/10.1021/ct4003702) + - quasi internal frame, aka. QI frame: a unique coordinate system to calculate the interaction between two sites in real space. Taking the connecting line of two sites as the Z-axis, the interaction tensor can be greatly simplified by using symmetry under this coordinate system to $$T_{tu}^{AB}$$. + +## Polarization term + +DMFF supports polarizable force fields, in which the dipole moment of the atom can respond to the change of the external electric field. We support that each atom not only has permanent multipoles $\hat{Q}_t$ but induced dipole $U_{ind}$. The interaction between induced-induced dipole and induced-permanent dipole needs damping, which mathematical expression is the same as MPID(Ref 6). Specifically, each atom needs a thole parameter ($$a_i$$). When calculating the interaction of polarizable sites, the damping function will be introduced. Take $$U_{ind}$$-permanent charge interaction as an example, the definition of damping function is: + +$$1-\left(1+a u+\frac{1}{2} a^{2} u^{2}\right) e^{-a u} \\ a=a_i + a_j \\ u=r_{ij}/\left(\alpha_i \alpha_j\right)^{1/6} $$ + +Other damping form between multipole moment can refer to Ref 6, table I. + +We solve $$U_{ind}$$ by minimizing electrostatic energy. The energy can be written as follows: + +$$V=V_{perm-perm}+V_{perm-ind}+V_{ind-ind}$$ + +the last two-termterms relate to $U_{ind}$. Without introducing the non-linear polarization term(e.g., some force fields introduce $$U^4$$ to avoid polarization catastrophe), the last two terms is quadratic function of $$U_{ind}$$: + +$$V_{perm-ind}+V_{ind-ind}=U^TKU-FU$$ + +where the off-diagonal term of $K$ matrix is induced-induced dipole interaction, the diagonal term is form energy of induced dipole($\sum_i \frac{U_i^2}{2\alpha_i}$); the $F$matrix represents permanent multipole - induced dipole interaction. We use the gradient descent method to optimize energy to get $U_{ind}$. + +In the current version, we temporarily assume that the polarizability is spherically symmetric; the polarizability $a_i$ is a scalar, not a tensor. It is relatively simple to relax this restriction; change the reciprocal of polarizability to the inverse of the matrix when calculating the diagonal term of the $K$ matrix. + +## Dispersion term + +We assume that the following expansion can describe the dispersion between atoms. + +$$V_{disp}=\sum_{ij}-\frac{C_{ij}^6}{r_{ij}^6}-\frac{C_{ij}^8}{r_{ij}^8}-\frac{C_{ij}^{10}}{r_{ij}^{10}}-...$$ + +where dispersion factor satisfies the following combination rule: + +$$C^n_{ij}=\sqrt{C_i^n C_j^n}$$ + +Note that the dispersion terms should be continuous even powers according to the perturbation theory, so the odd dispersion terms are not supported in DMFF. + +## Long-range interaction with PME + +The long-range interaction will be involved in treating electrostatic, polarization, and dispersion interactions. Take charge-charge interaction as an example. The interaction decays in the form of $O(\frac{1}{r})$, and its energy does not converge with the increase of cutoff distance. In calculating multipole and dispersion forces, the convergence speed of cutoff distance is also slow. We introduce Particle Meshed Ewald(PME) method to calculate those interactions. + +An example, as charge-charge interaction, we split the interaction tensor by long and short-range in PME: + +$$\frac{1}{r}=\frac{erfc(\kappa r)}{r}+\frac{erf(\kappa r)}{r}$$ + +The first term is a short-range term, which can be calculated directly by using a simple distance cutoff in real space. The second term is a long-range term, which needs to be calculated in reciprocal space by fast Fourier transform(FFT). The total energy of charge-charge interaction is: + +$$E_{real}=\sum_{ij}\frac{erfc(\kappa r_{ij})}{r_{ij}}\\E_{recip} = \sum_{\vec{k}\neq 0} {\frac{2\pi}{Vk^2}\exp\left[\frac{k^2}{4\kappa^2}\right]\left|S(\vec{k})\right|^2}\frac{1}{\left|\theta(\vec{k})\right|^2}\\E_{self}=-\frac{\kappa}{\sqrt{\pi}}\sum_i {q_i^2} \\E=E_{real}+E_{recip}+E_{self}$$ + +As for multipole PME and dispersion PME, the expression refer to Ref 2, Ref 3, and Ref 5. + +The key parameters in PME include: + + - $\kappa$: controls the separation degree of long-range and short-range. The greater $\kappa$, the faster decay of the real space, the smaller the cutoff distance that can be used in the real space, and the more difficult the convergence of the reciprocal space and the more k-points are required; + + - $ r_{c}$: cutoff distance in real space; + + - $ K_{max}$: controls the number of maximum k-points + + +In DMFF, we determine these parameters in the same way as the PME in [OpenMM](http://docs.openmm.org/latest/userguide/theory/02_standard_forces.html#coulomb-interaction-with-particle-mesh-ewald): + +$$\kappa=\sqrt{-\log (2 \delta)} / r_{c} \\ K_{max}=\frac{2 \kappa d}{3 d^{1 / 5}}$$ + +where the user needs to specify the cutoff distance $r_c$ when building the neighbor list, the width of the box in each dimension $d$, and the energy calculation accuracy $\delta$. + +In the current version, the parameter determination mechanism of multipole PME and dispersion PME is exactly the same as that of charge PME. + +## Short-range interaction + +Short distance pair interaction refers to all interactions with the following forms: + +$V=\sum_{ij}v(r_{ij})$ + +Some common short-range pair interactions include: + + - Buckingham or excluded part of LJ potential: + +$$v(r)=A\exp(-\beta r)\\v(r)=\frac{C^{12}}{r^{12}}$$ + + - Tang-Tonnies Damping: Damping function for short-range electrostatic and dispersive effects + 1. Combination Rule: + +For most traditional force fields, pairwise parameters in each pair of interactions are determined by atomic parameters. This mathematical relationship is called the combination rule. For example, in the calculation of LJ potential, the following combination rule may be used: + +$$v(r)=4\varepsilon\left[\left(\frac{\sigma}{r}\right)^{12}-\left(\frac{\sigma}{r}\right)^6\right]\\ \sigma=\frac{\sigma_i + \sigma_j}{2} \\ \varepsilon=\sqrt{\varepsilon_i \varepsilon_j}$$ + +DMFF does not make any assumptions about the specific mathematical forms of the combination rule and $v(r)$. Users need to write them in the definition of the pairwise kernel function. + +## Neighborlist + +The calculation of all real spaces depends on the construction of the neighborlist. Its purpose is to find the "nearest neighbor" within a certain distance of the central atom by using an efficient method and calculating its interaction. + +In DMFF, we use external code([jax-md](https://github.com/google/jax-md)) to build the nearest neighbor list. An external input argument named pairs is required in all real-space code, which contains the sequence numbers of all atomic pairs within a certain distance $r_c$. We assume that the pairs variable is in the form of `sparse` or `ordered sparse` in Jax-md. + +Because the nearest neighbor list only provides atom **id** information, it has nothing to do with the derivation chain. + +## Topological scaling + +In the organic molecular force field, in order to avoid double-counting with the bonding interaction term, we generally need to scale the non-bonding interaction between two atoms link to each other in topology. The specific scaling degree depends on the topological distance between the two atoms. We generally define two atoms with one bond as "1-2" interaction, and those separated by two bonds as "1-3" interaction, and so on. For example, in the OPLS-AA force field, all "1-2" non-bonding actions are turned off, while all "1-3" non-bonding actions are scaled to 50% of the normal non-bond actions. + +Important variables related to topological scaling in DMFF include: + + - `covalent_Map`: the format is $N*N$ matrix, which defines the topological spacing between any two atoms. If the matrix element is 0, it indicates that the **topological** distance between the two atoms is too far, so there is a complete non-bonding interaction between them. + + - `mScales`: The sequence of scaling factors is stored. The first element is 1-2 non-bond scaling, the second element is 1-3 non-bond scaling, and so on. The last number of the sequence **must be 1**, which represents the complete, unscaled non-bond interaction. + + - `pScales`/`dScales`: It is only related to calculating polarization energy, representing induced-perm and induced-induced, respectively. The format is the same as that of `mScales`. + + +## General multibody terms (such as ML force field) + + TODO: + +## Nonding interaction + +Intramolecular bonding interactions refer to all interactions that depend on internal coordinates(aka. IC), which mainly include bond, angle, dihedral, etc. + + * Harmonic Bonding Terms + The definition of binding term in DMFF is the same as that in OpenMM. For each key, we have: + $$E=\frac{1}{2}k(x-x_0)^2$$ + Note prefactor $1/2$ before force constant + + * Harmonic Angle Terms + we have: + $$E=\frac{1}{2} k\left(\theta-\theta_{0}\right)^{2}$$ + + * Dihedral Terms + 1. Proper dihedral + 2. Improper dihedral + + * Multi IC coupling term + +## Atomic classification + +Before energy calculation, atomic and IC parameters (such as charge, multipole moment, dispersion coefficient, polarizability, force constant of each bond and angle, etc.) need to be assigned. Generally speaking, these parameters should be related to each atom's specific environment and conformation or IC. However, in the traditional force field, in order to reduce the number of parameters, atoms and ICs are generally classified according to their topological environment, and atoms in the same class or ICs share parameters. Classifying each atom and IC and assigning its parameters is called typification. + +In DMFF, the input parameters that need to be optimized are called **force field parameters**, and the parameters of each atom and IC after typing are called **atomic parameters**. Note that in the new ideal force field, if we can directly predict atomic parameters using machine learning model, the process of typification is *not necessary*. Therefore, in the architecture design of DMFF, we decouple the relevant codes of the typification process as much as possible, so that the core computing code based on atomic parameters has its own independent API and can be called separately. + +The design of the typing module of DMFF is basically based on the existing framework of OpenMM. DMFF needs to keep the derivation chain uninterrupted when unfolding force field params into atomic params. Therefore, under the condition of maintaining the same call logic and process of OpenMM, it rewrites the typing code of OpenMM with Jax. Generally speaking, OpenMM/DMFF requires users to clearly define the category of each atom in each residue and the connection mode between atoms to form a residue definition template. Then the residue template is used to match the PDB file to typify the whole system. See the following [documents](../dev_guide/arch.MD) for details. + +## References: + +1. [Anthony's book](https://oxford.universitypressscholarship.com/view/10.1093/acprof:oso/9780199672394.001.0001/acprof-9780199672394) +2. [The Multipolar Ewald paper in JCTC: J. Chem. Theory Comput. 2015, 11, 2, 436–450](https://pubs.acs.org/doi/abs/10.1021/ct5007983) +3. [The dispersion Ewald/PME](https://aip.scitation.org/doi/pdf/10.1063/1.470117) +4. [Frenkel & Smit book](https://www.elsevier.com/books/understanding-molecular-simulation/frenkel/978-0-12-267351-1) +5. Note: multipole ewald.pdf +6. [MPID Reference](https://doi.org/10.1063/1.4984113) \ No newline at end of file diff --git a/docs/assets/arch.png b/docs/assets/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..f4003ef6a8b23c8e21b5efbe6fa9b324cc673bdc GIT binary patch literal 120886 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%0D|8egwzA^+iLN7VvQ1Q_VnO=R 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 Cg;M1J literal 0 HcmV?d00001 diff --git a/docs/assets/generator.svg b/docs/assets/generator.svg new file mode 100644 index 000000000..497df01ee --- /dev/null +++ b/docs/assets/generator.svg @@ -0,0 +1 @@ +

Hamiltonian


暴露给用户,继承自OpenMM Forcefield


+ _generators: dict


+ createPotential(topology, **args)

   读入OpenMM Topology,使用

   ResidueTemplate创建SystemData,

   而后构造势函数

Generator


存储力场参数,并负责从拓扑结构生成

整体的势函数


+ param: jax array

   力场参数信息

+ meta: dict

    势函数构建所需信息


+ __init__()

+ parseElement(xml node)

   从xml node中读取参数

+ createForce(SystemData)

   使用拓扑信息创建JAX势函数

+ renderXML()

   使用XML结构化存储力场参数

\ No newline at end of file diff --git a/docs/assets/opemm_workflow.svg b/docs/assets/opemm_workflow.svg new file mode 100644 index 000000000..17e41aabc --- /dev/null +++ b/docs/assets/opemm_workflow.svg @@ -0,0 +1 @@ +
创建app.forcefield.parser字典
将所有Generator的parseElement方法注册到app.forcefield.parser中
初始化Residue Template部分
调用parser字典中所有的parseElement方法解析XML
将每个调用到的Generator注册到ff object中
用Residue Template对topology进行匹配以分配AtomType
调用所有已注册的Generator的createForce方法来创建对应topology的势函数
import openmm.app as app
ff = app.ForceField("forcefield.xml")
system = ff.createSystem(topology, args)
流程结束
\ No newline at end of file diff --git a/docs/dev_guide/arch.md b/docs/dev_guide/arch.md new file mode 100644 index 000000000..9b6fe35cb --- /dev/null +++ b/docs/dev_guide/arch.md @@ -0,0 +1,288 @@ +# Architecture of DMFF + +![arch](../assets/arch.png) + +The overall framework of DMFF can be divided into two parts: parser & typing and calculators. We usually refer to the former as the *frontend* and the latter as the *backend* for ease of description. + +DMFF introduces different forms of force fields in a modular way. For any form of force field, it is divided into frontend modules and backend modules. The frontend module is responsible for input file parsing, molecular topology construction, atomic typification, and unfolding from the forcefield parameter layer to the atomic parameter layer; The backend module is the calculation core, which calculates the energy & force of the system at a time by particle positions and system properties. + +In the design of the front-end module, DMFF reuses the frontend parser module from OpenMM and realizes the functions of topology analysis. All frontend modules are stored in `api.py` and called by the Hamiltonian class. + +The backend module is usually an automatically differentiable computing module built with Jax. + +The structure of frontend and backend modules will be introduced in detail in the following documents. + +## How Frontend Works + +Frontend modules are stored in `api.py`. `Hamiltonian` class is the top-level class exposed to users by DMFF. `Hamiltonian` class reads the path of the XML file, parses the XML file, and calls different frontend modules according to the XML tags. The frontend module has the same form as OpenMM's generator [forcefield.py](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py). The `Generator` class takes the XML tag in and parse the parameters, initialize the backend calculator and provide the interface of energy calculation method. + +When users use the DMFF, the only thing need to do is initilize the the `Hamiltonian` class. In this process, `Hmiltonian` will automatically parse and initialize the corresponding potential function according to the tags in XML. The call logic is shown in the following chart. The box represents the command executed in Python script, and the rounded box represents the internal operation logic of OpenMM when executing the command. + +![openmm_workflow](../assets/opemm_workflow.svg) + +### Hamiltonian Class + +Hamiltonian class is the top-level frontend module, which inherits from the [forcefield class](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py) of OpenMM. It is responsible for parsing XML force field files and generating potential functions to calculate system energy for given topology information. First, the usage of Hamiltonian class is given: + + +```python +H = Hamiltonian('forcefield.xml') +app.Topology.loadBondDefinitions("residues.xml") +pdb = app.PDBFile("waterbox_31ang.pdb") +rc = 4.0 +# generator stores all force field parameters +generator = H.getGenerators() +disp_generator = generator[0] +pme_generator = generator[1] + +pme_generator.lpol = True # debug +pme_generator.ref_dip = 'dipole_1024' +potentials = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom) +# pot_fn is the actual energy calculator +pot_disp = potentials[0] +pot_pme = potentials[1] +``` + +`Hamiltonian` class performs the following operations during instantiation: + +* read Residue tag in XML, generate Residue template; +* read AtomTypes tag, store AtomType of each atom; +* for each Force tag, call corresponding `parseElement` method in `app.forcefield.parser` to parse itself, and register `generator`. + +`app.forcefield.parser` is a `dict`, the keys are Force tag names, and the values are `parseElement` method of `generator`. The Hamiltonian parse XML file will use the tag name to look up the corresponding `parseElement` method—the `generator` instance stores raw data from the XML file. You can use generators by `getGenerators()` in Hamiltonian. + +### Generator Class + + +The generator class in charge of input file analysis, molecular topology construction, atomic classification, and expansion from force field parameter layer to atomic parameter layer. It is a middle layer link `Hamiltonian` and backend. See the following documents for the specific design logic: + +![generator](../assets/generator.svg) + +The custom generator must define those methods: + + +* @staticmethod parseElement(element, hamiltonian): OpenMM use `element.etree` parse tag in XML file, and `element` is `Element` object. For instance, if there were a section in XML file that defines bond potential: + +```xml + + + + +``` + +will activate `HarmonicBondJaxGenerator.parseElement` method which is the value of key `app.forcefield.parsers["HarmonicBondForce"]`. You can use `element.findall("Bond")` to get a iterator of the `Element` object of tage. For `Element` object, you can use `.attrib` to get {'type1': 'ow} properties in `dict` format. + +What `parseElement` does is parse the `Element` object and initialize the generator itself. The parameters in generators can be classified into two categories. Those differentiable should store in a `dict` named `dict`, and non-differentiable static parameters can simply be set as the generator's attribute. Jax support `pytree` nested container, and `params` can be directly grad. + + +* `createForce(self, system, data, nonbondedMethod, *args)` pre-process XML parameters, initialize calculator. `System` and `data` are given by OpenMM's forcefield class, which store topology/atomType information (For now you need to use debug tool to access). To avoid break the differentiate chain, from XML raw data to per-atom properties, we should use `data` to construct per-atom info directly. Here is an example: + +```python +map_atomtype = np.zeros(n_atoms, dtype=int) + +for i in range(n_atoms): + atype = data.atomType[data.atoms[i]] + map_atomtype[i] = np.where(self.types == atype)[0][0] +``` + +Finally, we need to bind the calculator's compute function to `self._jaxPotential` + + +```python + +def potential_fn(positions, box, pairs, params): + return bforce.get_energy( + positions, box, pairs, params["k"], params["length"] + ) + +self._jaxPotential = potential_fn +``` + +All parameters accepted by `potential_fn` should be differentiable. Non differentiable parameters are passed into it by closure (see code convention section). Meanwhile, if the generator need to initialize multiple calculators (e.g. `NonBondedJaxGenerator` will call `LJ` and `PME` two kinds of calculators), `potential_fn` will return the summation of two potential energy. + +Here is a pseudo-code of the frontend module, demonstrating basic API and method + +```python +from openmm import app + +class SimpleJAXGenerator: + + def __init__(self, hamiltonian): + self.ff = hamiltonian + self.params = None + self._jaxPotential = None + init_other_attributes_if_needed + + @staticmethod + def parseElement(element, hamiltonian): + parse_xml_element + generator = SimpleGenerator(hamiltonian, args_from_xml) + hamiltonian.registerGenerator(generator) + + def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args): + generate_constraints_if_needed + # Create JAX energy function from system information + create_jax_potential + self._jaxPotential = jaxPotential + + def getJaxPotential(self, data, **args): + return self._jaxPotential + + def renderXML(self): + render_xml_forcefield_from_params + + +app.parsers["SimpleJAXForce"] = SimpleJAXGenerator.parseElement + +class Hamiltonian(app.ForceField): + + def __init__(self, **args): + super(app.ForceField, self).__init__(self, **args) + self._potentials = [] + + def createPotential(self, topology, **args): + system = self.createSystem(topology, **args) + load_constraints_from_system_if_needed + # create potentials + for generator in self._generators: + potentialImpl = generator.getJaxPotential(data) + self._potentials.append(potentialImpl) + return [p for p in self._potentials] +``` + +And here is a HarmonicBond potential implement: + +```python +class HarmonicBondJaxGenerator: + def __init__(self, hamiltonian): + self.ff = hamiltonian + self.params = {"k": [], "length": []} + self._jaxPotential = None + self.types = [] + + def registerBondType(self, bond): + + types = self.ff._findAtomTypes(bond, 2) + # self.ff._findAtomTypes is a function implemented in OpenMM to patch + # atom types. The first argument is xml element. The second argument is + # the number of types needed to be patched. + # The return of this function is: + # [[atype1, atype2, ...], [atype3, atype4, ...], ...] + # When patching by atom types, the function would return a list with + # patched atom types. When patching by atom classes, the function would + # return a list with all the atom types patched to the class. + + self.types.append(types) + self.params["k"].append(float(bond["k"])) + self.params["length"].append(float(bond["length"])) # length := r0 + + @staticmethod + def parseElement(element, hamiltonian): + # Work with xml tree. Element is the node of forcefield. + # Use element.findall and element.attrib to get the + # children nodes and attributes in the node. + + generator = HarmonicBondJaxGenerator(hamiltonian) + hamiltonian.registerGenerator(generator) + for bondtype in element.findall("Bond"): + generator.registerBondType(bondtype.attrib) + + def createForce(self, system, data, nonbondedMethod, nonbondedCutoff, args): + # jax it! + for k in self.params.keys(): + self.params[k] = jnp.array(self.params[k]) + self.types = np.array(self.types) + + n_bonds = len(data.bonds) + # data is the data structure built by OpenMM, saving topology information of the system. + # The object maintains all the bonds, angles, dihedrals and impropers. + # And it also maintains the atomtype of each particle. + # Use data.atoms, data.bonds, data.angles, data.dihedrals, data.impropers + # to get the atom types. + map_atom1 = np.zeros(n_bonds, dtype=int) + map_atom2 = np.zeros(n_bonds, dtype=int) + map_param = np.zeros(n_bonds, dtype=int) + for i in range(n_bonds): + idx1 = data.bonds[i].atom1 + idx2 = data.bonds[i].atom2 + type1 = data.atomType[data.atoms[idx1]] + type2 = data.atomType[data.atoms[idx2]] + ifFound = False + for ii in range(len(self.types)): + if (type1 in self.types[ii][0] and type2 in self.types[ii][1]) or ( + type1 in self.types[ii][1] and type2 in self.types[ii][0] + ): + map_atom1[i] = idx1 + map_atom2[i] = idx2 + map_param[i] = ii + ifFound = True + break + if not ifFound: + raise BaseException("No parameter for bond %i - %i" % (idx1, idx2)) + + # HarmonicBondJaxForce is the backend class to build potential function + bforce = HarmonicBondJaxForce(map_atom1, map_atom2, map_param) + + # potential_fn is the function to call potential, in which the dict self.params + # is fed to harmonic bond potential function + + def potential_fn(positions, box, pairs, params): + return bforce.get_energy( + positions, box, pairs, params["k"], params["length"] + ) + + self._jaxPotential = potential_fn + # self._top_data = data + + def getJaxPotential(self): + return self._jaxPotential + +# register all parsers +app.forcefield.parsers["HarmonicBondForce"] = HarmonicBondJaxGenerator.parseElement +``` + +## How Backend Works + +### Force Class + +Force class is the module to build potential function. It does not require OpenMM and can +be very flexible. For instance, the Force class of harmonic bond potential is shown below +as an example of jax potential function. + +```python +def distance(p1v, p2v): + return jnp.sqrt(jnp.sum(jnp.power(p1v - p2v, 2), axis=1)) + + +class HarmonicBondJaxForce: + def __init__(self, p1idx, p2idx, prmidx): + self.p1idx = p1idx + self.p2idx = p2idx + self.prmidx = prmidx + self.refresh_calculators() + + def generate_get_energy(self): + def get_energy(positions, box, pairs, k, length): + p1 = positions[self.p1idx] + p2 = positions[self.p2idx] + kprm = k[self.prmidx] + b0prm = length[self.prmidx] + dist = distance(p1, p2) + return jnp.sum(0.5 * kprm * jnp.power(dist - b0prm, 2)) + + return get_energy + + def update_env(self, attr, val): + """ + Update the environment of the calculator + """ + setattr(self, attr, val) + self.refresh_calculators() + + def refresh_calculators(self): + """ + refresh the energy and force calculators according to the current environment + """ + self.get_energy = self.generate_get_energy() + self.get_forces = value_and_grad(self.get_energy) +``` diff --git a/docs/dev_guide/convention.md b/docs/dev_guide/convention.md new file mode 100644 index 000000000..d6d238664 --- /dev/null +++ b/docs/dev_guide/convention.md @@ -0,0 +1,22 @@ +# Code Convention + +In this section, you will learn: + - How is DMFF organized + - + +## code organization + +The root directory of DMFF has following sub-directory: + + - `dmff`: source code of project + - `docs`: documents in markdown + - `examples`: examples can be run independently + - `tests`: unit and integration tests + +Under the `dmff`, there are several files and sub-directory: + + - `api.py`: store all the frontend modules + - `settings.py`: global settings + - `utils.py`: helper functions + — each sub-directory represents a set of potential form, e.g. `admp` is Automatic Differentiable Multipolar Polarizable, `classical` is differentiable GAFF forcefield. + diff --git a/docs/dev_guide/profile.md b/docs/dev_guide/profile.md new file mode 100644 index 000000000..14a981b77 --- /dev/null +++ b/docs/dev_guide/profile.md @@ -0,0 +1,2 @@ +# How to profile + diff --git a/docs/dev_guide/readme.md b/docs/dev_guide/readme.md new file mode 100644 index 000000000..4eeb960f1 --- /dev/null +++ b/docs/dev_guide/readme.md @@ -0,0 +1,20 @@ +# About development guide + +In this section, you will learn: + - Architecture of DMFF + - Code convention + - Easily expand a new form + - Write related docs + - Checklist before PR + +DMFF aims to establish a force field calculation and parameter fitting framework supporting automatic differentiation. In order to meet various forms of force field, DMFF calculates energy and force parameters through different force field sub-modules. DMFF ensures sufficient decoupling and modularization at the beginning of the design and can easily add new modules. + +In the *Architecture of DMFF* section, the design of DMFF will be introduced carefully. we will talk about how the parameters are loaded from the XML file and how to organize them for the following calculation and gradient. This work is mainly in charge by a class called `Generator`. Then the calculation code will be explained, which is the bearer of energy and force called `calculation kernel`, a pure function that takes particles' properties and positions and returns the energy. + +Some programming styles and standards should obey in the *Code convention* section. Those conventions will help developers write the code quickly; on the other hand, make the code reviewer and other maintainers easier to modify. + +In the *easily expand new form* section, finally, we can write the calculation part of energy and force. However, before you turn your equation to the code to be consistent with other force field sub-modules, this section will introduce the spec that your calculation kernel should follow. + +In the *Write related docs* section, we will talk about how to write the manual. Duo to the DMFF is a collection of force field module, each force field has it unique parameters and usage. To make it clear to use and easy to maintain, you should write down the theroy behind the code and the meaning of parameters. + +In the *Checklist before PR* section is what you should do before you publish your work to the Github. In this section, you will know how to write unit test, format checking and proper comment. diff --git a/docs/dev_guide/write_docs.md b/docs/dev_guide/write_docs.md new file mode 100644 index 000000000..3c6019c1d --- /dev/null +++ b/docs/dev_guide/write_docs.md @@ -0,0 +1,33 @@ +# Write related docs + +The most important thing after you implement your code in DMFF is to write the docs. Good documentation can help users use your module correctly and allow other maintainers to improve functions better. + +The documentation of DMFF use [MKDocs](https://www.mkdocs.org/) framework. + +## install MKDocs + +Before we start to write our docs, run the following command in termianl to install MKDocs: + +``` +pip install mkdocs +``` + +To support latex rendering, we also need markdown extension: + +``` +pip install pymdown-extensions +``` + +## Write your docs + +According to the existing document architecture, create a new markdown file in the appropriate directory. Write it! If you need to insert picture, upload the picture in `assets` directory, and use `![_placeholder](relative/path/to/this/file)` syntax to insert picture. + +## Preview you docs + +MkDocs comes with a built-in dev-server that lets you preview your documentation as you work on it. Make sure you're in the same directory as the `mkdocs.yml` configuration file, and then start the server by running the mkdocs serve command: + +``` +mkdocs serve +``` + +Open up http://127.0.0.1:8000/ in your browser, and you'll see the default home page being displayed. The dev-server also supports auto-reloading, and will rebuild your documentation whenever anything in the configuration file, documentation directory, or theme directory changes. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 000ea3455..74f1ed22e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,7 @@ -# Welcome to MkDocs +# Welcome to DMFF -For full documentation visit [mkdocs.org](https://www.mkdocs.org). +This project aims to establish a general extensible framework to support the development of organic molecular force field and the fitting of parameters in the force field. The main target of the project include: biological macromolecules (peptides, proteins, nucleic acids, etc.), organic macromolecules, organic small molecules (including organic electrolyte, small molecule drugs), etc. -## Commands +There are many factors involved in organic molecular interactions, and the behavior of organic molecular systems (such as protein folding, polymer structure, etc.) often depends on the joint influence of various interactions. The existing general organic molecular force fields (such as OPLS and amber) are mainly empirical fitting, and their portability and prediction ability are insufficient. When extended to new molecules, the parameter fitting process is cumbersome and strongly depends on error cancellation under manual intervention. -* `mkdocs new [dir-name]` - Create a new project. -* `mkdocs serve` - Start the live-reloading docs server. -* `mkdocs build` - Build the documentation site. -* `mkdocs -h` - Print help message and exit. - -## Project layout - - mkdocs.yml # The configuration file. - docs/ - index.md # The documentation homepage. - ... # Other markdown pages, images and other files. +In order to accurately describe organic molecular systems, we need to accurately model various interactions within and between molecules (including long-range and short-range). Therefore, it is necessary to realize a closer combination of traditional force field and AI method, and apply AI tools to short-range potential energy surface fitting, traditional force field parameter optimization and so on. We will use the automatic differential programming framework to develop the tool chain from force field calculation to molecular mechanics simulation, so as to realize the complex functions such as traditional force field / machine learning hybrid model and parameter optimization based on molecular mechanics trajectory. Based on this project, a new generation of general organic force field database is developing, and a more automatic force field development process is established. \ No newline at end of file diff --git a/docs/user_guide/readme.md b/docs/user_guide/readme.md new file mode 100644 index 000000000..c1960e7d5 --- /dev/null +++ b/docs/user_guide/readme.md @@ -0,0 +1,16 @@ +# About user guide section + +In this section, you will learn: + + - Installation of DMFF + - Computation of energy and force + - Auto differentiate alone computation path + - Couple DMFF with MD engine + +The first thing you should know is that DMFF is not exactly a force field in the traditional sense: there is no module called *DMFF*, but a collection of potential forms. There is several forms of support in the DMFF package: + + - Automatic Differentiable Multipolar Polarizable (ADMP) + - Classical force field derived from GAFF + - SGNN + +Those modules can easily be combined with a specific research topic to create a force field. Each module has its usage and required parameters, and provide them in a specified XML file and then use them under a Python program. With DMFF, one can calculate the energy and force of a molecular mechanics system and even get the parameters' gradient. \ No newline at end of file diff --git a/docs/user_guide/tutorial.md b/docs/user_guide/tutorial.md index e69de29bb..c48fab261 100644 --- a/docs/user_guide/tutorial.md +++ b/docs/user_guide/tutorial.md @@ -0,0 +1,7 @@ +# Tutorial + +## install DMFF + +## compute energy and force + +## auto differentiation \ No newline at end of file diff --git a/docs/user_guide/xml_spec.md b/docs/user_guide/xml_spec.md new file mode 100644 index 000000000..24142c6f4 --- /dev/null +++ b/docs/user_guide/xml_spec.md @@ -0,0 +1,207 @@ +# How to write XML file + +The force field file design of openmm is quite modular and has high convenience. Unfortunately, there are few existing introductions and the documents are not clear enough. Now the format and meaning of OpenMM XML file are sorted as follows. + +## Topology file + +Topology file is used to describe the bonding information of residues. For molecules with residue name matching, the topology module of openmm will add keys for atoms according to the information in the XML file. + +Examples of XML files are as follows: +```xml + + + + + + + + + + + + + + + + + + + +``` + +Where "- C" indicates the connection with the "C" atom in the **previous** residue. During typification, all atoms in the residue with the same name will try to match. Once the typification is successful, it will be bonded, and if the matching fails, it will be skipped. Therefore, the actual number of bonds can be less than the number set in the template. + +The XML file registration method is as follows: + +``` python +try: + import openmm.app as app +except: + import simtk.openmm.app as app + +app.Topology.loadBondDefinations("residues.xml") # register residue topology + +# Create topology and add atoms and residues to it, which is automatically performed when reading PDB +top = app.Topology() +... +top.createStandardBonds() # Connect keys according to template files +``` + +It should be noted that disulfide bond is not completed in this step. The OpenMM topology class will look for SG atoms in Cys that are not connected to Hg, and connect atom pairs less than 0.3nm as disulfide bonds. + +## Force field parameter file + +The force field parameter file is as follows: +``` xml + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` +This document can be divided into residue part and force field part. + +### residue part +``` xml + + + + + + + + + + + + ... + +``` +The `` node of the residue part defines the atomtype of each atom in the residue and some parameter information of per atom, which can be called by the force field part on demand. The `` node defines the bonding information of residues. The information contained in this part is different from that in the topology file above. Take ALA as an example. For ALA, we usually need to define at least three state, N-end, C-end and in-chain. The template in the force field is as follows: + +``` xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +In this example, the atom number and bonding relationship of ALA, CALA and NALA are different. When matching each ALA, OpenMM will try to match CALA, NALA and ALA, and finally select the template with the same number of atoms, element composition and bonding relationship as the residue to define the force field parameters for each atom. + +### forcefield part + + + ... + + + + + + + + + + + + + + + + + +The `` node defines many atomic types. The `type` label of each atom in the residue part will match the `name` label of each child node of ``. For each atom type, it also defines a `class` tag for different matching scenarios. The `name` of different `` child nodes must be different, but the `class` can be the same. + +The `<*force>` node defines the matching rule of a potential function. For example, `` defines harmonic bond, and the `` node defines intermolecular interaction. You can view the document for specific parameter [details](http://docs.openmm.org/latest/userguide/application/05_creating_ffs.html#writing-the-xml-file) + +In the matching process, OpenMM will iterate all atom, bond, angle, dihedral and improver, and add all matching entries to the total potential function. Matching can be carried out according to the `type` tag, corresponding to the `name` of each atom in ``; It can also be based on the `class` tag, corresponding to the `class` of each atom in ``. This design is applicable to the situation that there are many types of atoms but they are roughly the same. For example, there are few kinds of LJ parameters in small molecular force field, but there are many kinds of intramolecular force parameters. We can even create a separate type for a specific small molecule to define the intra molecular interaction, but it belongs to the same class on LJ, so as to achieve the effect that the small molecule parameters can be tuned and do not affect each other. \ No newline at end of file From d3a1d560938f4fc79334e0433544696a4bf11922 Mon Sep 17 00:00:00 2001 From: Roy Kid Date: Tue, 19 Apr 2022 00:24:37 +0800 Subject: [PATCH 2/8] move installation to index page --- docs/admp/readme.md | 26 ------------------ docs/index.md | 65 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/docs/admp/readme.md b/docs/admp/readme.md index 96bb4f0e6..64ef7453a 100644 --- a/docs/admp/readme.md +++ b/docs/admp/readme.md @@ -12,33 +12,7 @@ The module is based on [JAX](https://github.com/google/jax) and [JAX-MD](https:/ -## Installation -### Dependencies - -ADMP module depends on the following packages, install them before using ADMP: - -1. Install [jax](https://github.com/google/jax) (pick the correct cuda version, see more details on their installation guide): - - ``` - pip install jax[cuda11_cudnn82] -f https://storage.googleapis.com/jax-releases/jax_releases.html - ``` - -2. Install [jax-md](https://github.com/google/jax-md) : - - ``` - pip install jax-md --upgrade - ``` - - ADMP currently relies on the space and partition modules to provide neighbor list - -3. Install ADMP: - - ADMP is a pure python module, just simply put it in your $PYTHONPATH. - - ``` - export PYTHONPATH=$PYTHONPATH:/path/to/admp - ``` diff --git a/docs/index.md b/docs/index.md index 74f1ed22e..1b6a8003a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,4 +4,67 @@ This project aims to establish a general extensible framework to support the dev There are many factors involved in organic molecular interactions, and the behavior of organic molecular systems (such as protein folding, polymer structure, etc.) often depends on the joint influence of various interactions. The existing general organic molecular force fields (such as OPLS and amber) are mainly empirical fitting, and their portability and prediction ability are insufficient. When extended to new molecules, the parameter fitting process is cumbersome and strongly depends on error cancellation under manual intervention. -In order to accurately describe organic molecular systems, we need to accurately model various interactions within and between molecules (including long-range and short-range). Therefore, it is necessary to realize a closer combination of traditional force field and AI method, and apply AI tools to short-range potential energy surface fitting, traditional force field parameter optimization and so on. We will use the automatic differential programming framework to develop the tool chain from force field calculation to molecular mechanics simulation, so as to realize the complex functions such as traditional force field / machine learning hybrid model and parameter optimization based on molecular mechanics trajectory. Based on this project, a new generation of general organic force field database is developing, and a more automatic force field development process is established. \ No newline at end of file +In order to accurately describe organic molecular systems, we need to accurately model various interactions within and between molecules (including long-range and short-range). Therefore, it is necessary to realize a closer combination of traditional force field and AI method, and apply AI tools to short-range potential energy surface fitting, traditional force field parameter optimization and so on. We will use the automatic differential programming framework to develop the tool chain from force field calculation to molecular mechanics simulation, so as to realize the complex functions such as traditional force field / machine learning hybrid model and parameter optimization based on molecular mechanics trajectory. Based on this project, a new generation of general organic force field database is developing, and a more automatic force field development process is established. + +## Resources + +[Reference Documentation](): Examples, tutorials, topic guides, and package Python APIs. +[Installation Guide](): Instructions for installing and compiling freud. + +[GitHub repository](): Download the freud source code. + +[Issue tracker](): Report issues or request features. + +## Citation + +TODO: + +## Installation + +### Prerequsite + +DMFF depends on several packages: + +* [jax]() +* [jax-md]() +* [OpenMM]() + +### step-by-step + +1. Install [jax](https://github.com/google/jax) (pick the correct cuda version, see more details on their installation guide): + + ``` + pip install jax[cuda11_cudnn82] -f https://storage.googleapis.com/jax-releases/jax_releases.html + ``` + +2. Install [jax-md](https://github.com/google/jax-md) : + + ``` + pip install jax-md --upgrade + ``` + + ADMP currently relies on the space and partition modules to provide neighbor list + +3. Install [OpenMM](https://openmm.org/) + + ``` + conda install -c conda-forge openmm cudatoolkit=10.0 + ``` + +## Example + +We provide a MPID 1024 water box example. In water_1024 and water_pol_1024, we show both the nonpolarizable and the polarizable cases. + +```bash +cd ./examples/water_1024 +./run_admp.py + +cd ./examples/water_pol_1024 +./run_admp.py +``` + +if `DO_JIT = True`, then the first run would be a bit slow, since it tries to do the jit compilation. Further executions of `get_forces` or `get_energy` should be much faster. + +## Support and Contribution + +Please visit our repository on [GitHub](https://github.com/deepmodeling/DMFF) for the library source code. Any issues or bugs may be reported at our issue tracker. All contributions to DMFF are welcomed via pull requests! \ No newline at end of file From c36bf57a35de7599610b36e930f66c5e46eb1b99 Mon Sep 17 00:00:00 2001 From: Yingze Wang Date: Mon, 25 Apr 2022 01:12:10 +0800 Subject: [PATCH 3/8] refactor(doc): make the doc structure clearer --- docs/dev_guide/{readme.md => introduction.md} | 15 ++-- docs/index.md | 69 ++++--------------- docs/user_guide/installation.md | 41 +++++++++++ docs/user_guide/introduction.md | 16 +++++ docs/user_guide/readme.md | 16 ----- mkdocs.yml | 33 +++++++-- 6 files changed, 105 insertions(+), 85 deletions(-) rename docs/dev_guide/{readme.md => introduction.md} (90%) create mode 100644 docs/user_guide/installation.md create mode 100644 docs/user_guide/introduction.md delete mode 100644 docs/user_guide/readme.md diff --git a/docs/dev_guide/readme.md b/docs/dev_guide/introduction.md similarity index 90% rename from docs/dev_guide/readme.md rename to docs/dev_guide/introduction.md index 4eeb960f1..13679bc91 100644 --- a/docs/dev_guide/readme.md +++ b/docs/dev_guide/introduction.md @@ -1,11 +1,12 @@ -# About development guide +# 1. Introduction -In this section, you will learn: - - Architecture of DMFF - - Code convention - - Easily expand a new form - - Write related docs - - Checklist before PR +In the developer guide, you will learn: + ++ Architecture of DMFF ++ Code convention ++ Easily expand a new form ++ Write related docs ++ Checklist before PR DMFF aims to establish a force field calculation and parameter fitting framework supporting automatic differentiation. In order to meet various forms of force field, DMFF calculates energy and force parameters through different force field sub-modules. DMFF ensures sufficient decoupling and modularization at the beginning of the design and can easily add new modules. diff --git a/docs/index.md b/docs/index.md index 1b6a8003a..933705046 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,69 +1,26 @@ -# Welcome to DMFF +# DMFF's documentation -This project aims to establish a general extensible framework to support the development of organic molecular force field and the fitting of parameters in the force field. The main target of the project include: biological macromolecules (peptides, proteins, nucleic acids, etc.), organic macromolecules, organic small molecules (including organic electrolyte, small molecule drugs), etc. +**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a package written in Python, designed to implement differentiable molecular force field calculations. This project aims to establish a general extensible framework to support the development of force fields by minimizing the effort required during the parameters fitting process. Currently, the project mainly focuses on development of force fields that describe the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers (PEG) and small organic molecules (organic electrolyte, drug-like molecules). There are many factors involved in organic molecular interactions, and the behavior of organic molecular systems (such as protein folding, polymer structure, etc.) often depends on the joint influence of various interactions. The existing general organic molecular force fields (such as OPLS and amber) are mainly empirical fitting, and their portability and prediction ability are insufficient. When extended to new molecules, the parameter fitting process is cumbersome and strongly depends on error cancellation under manual intervention. In order to accurately describe organic molecular systems, we need to accurately model various interactions within and between molecules (including long-range and short-range). Therefore, it is necessary to realize a closer combination of traditional force field and AI method, and apply AI tools to short-range potential energy surface fitting, traditional force field parameter optimization and so on. We will use the automatic differential programming framework to develop the tool chain from force field calculation to molecular mechanics simulation, so as to realize the complex functions such as traditional force field / machine learning hybrid model and parameter optimization based on molecular mechanics trajectory. Based on this project, a new generation of general organic force field database is developing, and a more automatic force field development process is established. -## Resources +## User Guide -[Reference Documentation](): Examples, tutorials, topic guides, and package Python APIs. -[Installation Guide](): Instructions for installing and compiling freud. ++ [1. Introduction](user_guide/introduction.md) ++ [2. Installation](user_guide/installation.md) ++ [3. Compute energy and forces](user_guide/compute.md) ++ [4. Compute gradients with auto differentiable framework](user_guide/auto_diff.md) -[GitHub repository](): Download the freud source code. +## Developer Guide ++ [1. Introduction](dev_guide/introduction.md) ++ [2. Architecture](dev_guide/arch.md) ++ [3. Convention](dev_guide/convention.md) -[Issue tracker](): Report issues or request features. +## Modules ++ [1. ADMP](modules/admp.md) -## Citation - -TODO: - -## Installation - -### Prerequsite - -DMFF depends on several packages: - -* [jax]() -* [jax-md]() -* [OpenMM]() - -### step-by-step - -1. Install [jax](https://github.com/google/jax) (pick the correct cuda version, see more details on their installation guide): - - ``` - pip install jax[cuda11_cudnn82] -f https://storage.googleapis.com/jax-releases/jax_releases.html - ``` - -2. Install [jax-md](https://github.com/google/jax-md) : - - ``` - pip install jax-md --upgrade - ``` - - ADMP currently relies on the space and partition modules to provide neighbor list - -3. Install [OpenMM](https://openmm.org/) - - ``` - conda install -c conda-forge openmm cudatoolkit=10.0 - ``` - -## Example - -We provide a MPID 1024 water box example. In water_1024 and water_pol_1024, we show both the nonpolarizable and the polarizable cases. - -```bash -cd ./examples/water_1024 -./run_admp.py - -cd ./examples/water_pol_1024 -./run_admp.py -``` - -if `DO_JIT = True`, then the first run would be a bit slow, since it tries to do the jit compilation. Further executions of `get_forces` or `get_energy` should be much faster. ## Support and Contribution diff --git a/docs/user_guide/installation.md b/docs/user_guide/installation.md new file mode 100644 index 000000000..20ced0df3 --- /dev/null +++ b/docs/user_guide/installation.md @@ -0,0 +1,41 @@ +# 2. Installation +## 2.1 Install dependencies ++ Install [jax](https://github.com/google/jax) (pick the correct cuda version, see more details on their installation guide): +```bash +pip install jax[cuda11_cudnn82] -f https://storage.googleapis.com/jax-releases/jax_releases.html +``` ++ Install [jax-md](https://github.com/google/jax-md): +```bash +pip install jax-md +``` ++ Install [OpenMM](https://openmm.org/): +```bash +conda install -c conda-forge openmm +``` +## 2.2 Install DMFF from source code +One can download the source code of DMFF by +```bash +git clone https://github.com/deepmodeling/DMFF.git +``` +then you may install DMFF easily by: +```bash +cd dmff +pip install . --user +``` + +## 2.3 Test installation +To test if the DMFF is correctly installed, you can run the following commands in a Python interpreter: +```python +>>> import dmff +>>> import dmff.admp +``` + +You can also run the example scripts to test whether DMFF is installed correctly. +```bash +cd ./examples/water_1024 +python ./run_admp.py + +cd ./examples/water_pol_1024 +python ./run_admp.py +``` +Note that the first run of the scripts will be a little bit slow if `DO_JIT = True` in `dmff/settings.py`. This is because the programm will try to do the jit compilation. \ No newline at end of file diff --git a/docs/user_guide/introduction.md b/docs/user_guide/introduction.md new file mode 100644 index 000000000..f07e768e7 --- /dev/null +++ b/docs/user_guide/introduction.md @@ -0,0 +1,16 @@ +# 1. Introduction + +In this user guide, you will learn: + +- Installation of DMFF +- Computation of energy and force +- Auto differentiate alone computation path +- Couple DMFF with MD engine + +The first thing you should know is that DMFF is not an actual force field (such as OPLS or AMBER), but a collection of various force field (or called "potential") forms: + +- Automatic Differentiable Multipolar Polarizable (ADMP) +- Classical force field derived from GAFF +- SGNN + +Those modules can easily be combined with a specific research topic to create a force field. Each module has its usage and required parameters, and provide them in a specified XML file and then use them under a Python program. With DMFF, one can calculate the energy and force of a molecular mechanics system and even get the parameters' gradient. \ No newline at end of file diff --git a/docs/user_guide/readme.md b/docs/user_guide/readme.md deleted file mode 100644 index c1960e7d5..000000000 --- a/docs/user_guide/readme.md +++ /dev/null @@ -1,16 +0,0 @@ -# About user guide section - -In this section, you will learn: - - - Installation of DMFF - - Computation of energy and force - - Auto differentiate alone computation path - - Couple DMFF with MD engine - -The first thing you should know is that DMFF is not exactly a force field in the traditional sense: there is no module called *DMFF*, but a collection of potential forms. There is several forms of support in the DMFF package: - - - Automatic Differentiable Multipolar Polarizable (ADMP) - - Classical force field derived from GAFF - - SGNN - -Those modules can easily be combined with a specific research topic to create a force field. Each module has its usage and required parameters, and provide them in a specified XML file and then use them under a Python program. With DMFF, one can calculate the energy and force of a molecular mechanics system and even get the parameters' gradient. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 14a7a7497..6472d1086 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,9 +1,30 @@ site_name: DMFF nav: - - Home: 'index.md' - - About: 'about.md' - - 'User Guide': - - 'tutorial': 'tutorial.md' - - 'Modules': - - 'ADMP': + - Home: index.md + - User Guide: + - 1. Introduction: user_guide/introduction.md + - 2. Installation: user_guide/installation.md + - 3. Compute energy and force: user_guide/compute.md + - 4. Auto-diff: user_guide/auto_diff.md + - 5. couple with MD: user_guide/couple.md + + - Developer Guide: + - 1. Introduction: dev_guide/introduction.md + - 2. Architecture: dev_guide/arch.md + - 3. Convention: dev_guide/convention.md + - Modules: + - ADMP: + - Introduction: admp/readme.md + - Theory: admp/theory.md + - About: about.md + theme: readthedocs + +markdown_extensions: + - pymdownx.arithmatex: + generic: true + +extra_javascript: + - javascripts/mathjax.js + - https://polyfill.io/v3/polyfill.min.js?features=es6 + - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js From e55b7d67f13b324608fffb4af38eaa4fd2de93a2 Mon Sep 17 00:00:00 2001 From: Yingze Wang Date: Mon, 25 Apr 2022 01:15:59 +0800 Subject: [PATCH 4/8] change(doc): "documentation" -> "Manual" --- README.md | 29 +++++++++++++++++++++++++++-- docs/index.md | 2 +- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 09ce92a12..8ecd3198f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,27 @@ -# DMFF -Differentiable Molecular Force Field +# DMFF's Manual + +**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a package written in Python, designed to implement differentiable molecular force field calculations. This project aims to establish a general extensible framework to support the development of force fields by minimizing the effort required during the parameters fitting process. Currently, the project mainly focuses on development of force fields that describe the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers (PEG) and small organic molecules (organic electrolyte, drug-like molecules). + +There are many factors involved in organic molecular interactions, and the behavior of organic molecular systems (such as protein folding, polymer structure, etc.) often depends on the joint influence of various interactions. The existing general organic molecular force fields (such as OPLS and amber) are mainly empirical fitting, and their portability and prediction ability are insufficient. When extended to new molecules, the parameter fitting process is cumbersome and strongly depends on error cancellation under manual intervention. + +In order to accurately describe organic molecular systems, we need to accurately model various interactions within and between molecules (including long-range and short-range). Therefore, it is necessary to realize a closer combination of traditional force field and AI method, and apply AI tools to short-range potential energy surface fitting, traditional force field parameter optimization and so on. We will use the automatic differential programming framework to develop the tool chain from force field calculation to molecular mechanics simulation, so as to realize the complex functions such as traditional force field / machine learning hybrid model and parameter optimization based on molecular mechanics trajectory. Based on this project, a new generation of general organic force field database is developing, and a more automatic force field development process is established. + +## User Guide + ++ [1. Introduction](user_guide/introduction.md) ++ [2. Installation](user_guide/installation.md) ++ [3. Compute energy and forces](user_guide/compute.md) ++ [4. Compute gradients with auto differentiable framework](user_guide/auto_diff.md) + +## Developer Guide ++ [1. Introduction](dev_guide/introduction.md) ++ [2. Architecture](dev_guide/arch.md) ++ [3. Convention](dev_guide/convention.md) + +## Modules ++ [1. ADMP](modules/admp.md) + + +## Support and Contribution + +Please visit our repository on [GitHub](https://github.com/deepmodeling/DMFF) for the library source code. Any issues or bugs may be reported at our issue tracker. All contributions to DMFF are welcomed via pull requests! \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 933705046..8ecd3198f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,4 @@ -# DMFF's documentation +# DMFF's Manual **DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a package written in Python, designed to implement differentiable molecular force field calculations. This project aims to establish a general extensible framework to support the development of force fields by minimizing the effort required during the parameters fitting process. Currently, the project mainly focuses on development of force fields that describe the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers (PEG) and small organic molecules (organic electrolyte, drug-like molecules). From 369f39162c1ab422c9980a868c4c0790af2111a9 Mon Sep 17 00:00:00 2001 From: Kuang Yu Date: Mon, 2 May 2022 10:28:41 +0800 Subject: [PATCH 5/8] Update README.md README.md improved. --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8ecd3198f..87e559477 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ # DMFF's Manual -**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a package written in Python, designed to implement differentiable molecular force field calculations. This project aims to establish a general extensible framework to support the development of force fields by minimizing the effort required during the parameters fitting process. Currently, the project mainly focuses on development of force fields that describe the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers (PEG) and small organic molecules (organic electrolyte, drug-like molecules). +**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a python-based package that provides a full differentiable implementation of molecular force field calculations. This project aims to establish an extensible framework to minimize the efforts in force field parameter fitting, and to support an easy evaluation of forces and virial tensors for complicated advanced potentials (such as polarizable models with geometry-dependent atomic parameters). Currently, this project mainly focuses on the force fields of the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers, and small organic molecules (organic electrolyte, drug-like molecules) etc. And we support both the conventional point charge models (OPLS and AMBER like) and multpolar polarizable models (AMOEBA and MPID like). -There are many factors involved in organic molecular interactions, and the behavior of organic molecular systems (such as protein folding, polymer structure, etc.) often depends on the joint influence of various interactions. The existing general organic molecular force fields (such as OPLS and amber) are mainly empirical fitting, and their portability and prediction ability are insufficient. When extended to new molecules, the parameter fitting process is cumbersome and strongly depends on error cancellation under manual intervention. - -In order to accurately describe organic molecular systems, we need to accurately model various interactions within and between molecules (including long-range and short-range). Therefore, it is necessary to realize a closer combination of traditional force field and AI method, and apply AI tools to short-range potential energy surface fitting, traditional force field parameter optimization and so on. We will use the automatic differential programming framework to develop the tool chain from force field calculation to molecular mechanics simulation, so as to realize the complex functions such as traditional force field / machine learning hybrid model and parameter optimization based on molecular mechanics trajectory. Based on this project, a new generation of general organic force field database is developing, and a more automatic force field development process is established. +The behavior of organic molecular systems (e.g., protein folding, polymer structure, etc.) is often determined by a complex effect of many different types of interactions. The existing organic molecular force fields are mainly empirically fitted and their performance relies heavily on error cancellation. Therefore, the transferrabilities and the prediction powers of these force fields are insufficient. For new molecules, the parameter fitting process requires heavy load of manual intervention and can be quite cubersome. In order to automize the parametrization process and increase the robustness of the model, it is necessary to combine modern AI techniques with conventional force field development. This project serves for this purpose by utilizing the automatic differential programming framework to develop a toolchain, leading to many advanced functions such as: hybrid force field / machine learning models and parameter optimization based on molecular mechanics trajectory. ## User Guide @@ -24,4 +22,4 @@ In order to accurately describe organic molecular systems, we need to accurately ## Support and Contribution -Please visit our repository on [GitHub](https://github.com/deepmodeling/DMFF) for the library source code. Any issues or bugs may be reported at our issue tracker. All contributions to DMFF are welcomed via pull requests! \ No newline at end of file +Please visit our repository on [GitHub](https://github.com/deepmodeling/DMFF) for the library source code. Any issues or bugs may be reported at our issue tracker. All contributions to DMFF are welcomed via pull requests! From 29cdd6804ebd55df49ca2589198f239a58e2d4bd Mon Sep 17 00:00:00 2001 From: Kuang Yu Date: Mon, 2 May 2022 16:55:14 +0800 Subject: [PATCH 6/8] Update theory.md theory.md editted --- docs/admp/theory.md | 193 +++++++++++++++++++++++++++----------------- 1 file changed, 119 insertions(+), 74 deletions(-) diff --git a/docs/admp/theory.md b/docs/admp/theory.md index a656e5f96..1f92df0f3 100644 --- a/docs/admp/theory.md +++ b/docs/admp/theory.md @@ -1,155 +1,198 @@ # Theory background -This project aims to implement an organic force field with a differentiable framework to automatically derivate atomic position, box shape, force field parameters, and other inputs. +DMFF project aims to implement organic molecular force fields using a differentiable programming framework, such that derivatives with respect to atomic positions, box shape, and force field parameters can be easily computed. It contains different modules, dealing with different types of force field terms. Currently, there are two primary modules: -The ADMP force field module has the following interactions: +1. ADMP (**A**utomatic **D**ifferentiable **M**ultipolar **P**olarizable Potential) module + ADMP mainly deals with multipolar polarizable models. Its core function is very similar to the MPID plugin in OpenMM, implementing PME calculators for multipolar polarizable electrostatic interactions and long-range dispersion interactions (with the shape of $c_i c_j/r^p$). It also devises a user-defined real-space pairwise interaction calculator based on cutoff scheme. + +2. Classical module + The classical module implements conventional (AMBER and OPLS like) force fields. For long-range interactions, it invokes the ADMP PME kernel, but wrapps it in a more "classical" way. It also incoporates the classical intramolecular terms: bonds, angles, proper and improper dihedrals etc. +All interations involved in DMFF are briefly introduced below and the users are encouraged to read the references for more mathematical details: -## Electrostatic term +## Electrostatic Interaction -We can use multipole expansion with cutoff for electrostatic interaction between electron could of atoms. If only the charge (zero-moment) part is retained, it reduces to the point charge model in the classical force field: +The electrostatic interaction between two atoms can be described using multipole expansion, in which the electron cloud of an atom can be expanded as a series of multipole moments including charges, dipoles, quadrupoles, and octupoles etc. If only the charges (zero-moment) are considered, it is reduced to the point charge model in classical force fields: -$$V=\sum_{ij} \frac{q_i q_j}{r_{ij}}$$ +$$ +V=\sum_{ij} \frac{q_i q_j}{r_{ij}} +$$ -where $q_i$ is the charge number of the atom. +where $q_i$ is the charge of atom $i$. -More complex force field forms can be obtained by increasing truncation of the moment order. Some force fields, such as AMOEBA and MPID, use higher-order truncation. In DMFF, we have up to four moments: +More complex (and supposedly more accurate) force field can be obtained by including more multipoles with higher orders. Some force fields, such as MPID, goes as high as octupoles. Currently in DMFF, we support up to quadrupoles: -$$V=\sum_{tu} \hat{Q}_t^A T^{AB}_{tu} \hat{Q}_u^B$$ +$$ +V=\sum_{tu} \hat{Q}_t^A T^{AB}_{tu} \hat{Q}_u^B +$$ -where $Q_t^A$ represents the t-component of multipole moment of atom A, there are two definitions: cartesian coordinates and spherical harmonics. In DMFF, we use spherical harmonics. The sequence is: +where $Q_t^A$ represents the t-component of the multipole moment of atom A. Note there are two (equivalent) ways to define multipole moments: cartesian and spherical harmonics. Cartesian representation is over-complete but with a simpler definition, while spherical harmonics are easier to use in real calculations. In the user API, we use cartesian representation, in consistent with the AMOEBA and the MPID plugins in OpenMM. However, spherical harmonics are always used in the computation kernel, and we assume all components are arranged in the following order: $$0, 10, 1c, 1s, 20, 21c, 21s, 22c, 22s, ...$$ -The $T_{tu}^{AB}$ represents the interaction tensor among multipoles, which mathematical expression can refer to Ref 1 appendix F. The conversion between different multipole moment definitions and rotation rules can refer to Ref 1 & 5. +The $$T_{tu}^{AB}$$ represents the interaction tensor between multipoles. The mathematical expression of these tensors can be found in the appendix F of Ref 1. The user can also find the conversion rule between different representations in Ref 1 & 5. + -## Multipole moment coordinate system +## Coordinate System for Multipoles -Different from charge, multipole moment definition depends on the coordinate system. What we use are mainly three: +Different to charges, the definition of multipole moments depends on the coordinate system. The exact value of the moment tensor will be rotated in accord to different coordinate systems. There are three types of frames involved in DMFF, each used in a different scenario: - - global frame: coordinate system binds to the simulation box. It same for all atoms. We use this system to calculate charge density structure factor $$S(\vec{k})$$ in reciprocal space. - - local frame: this system defines each atom's coordinate by the positions of its peripheral atoms, and then multipole moment is given under this system. Generally, atomic multipole moments have considerable stability in the local frame, so it is more suitable as a force field parameter input. In DMFF, the definition of the local frame is the same as the AMOEBA plugin in OpenMM. The detail can refer to the following literatures: + - Global frame: coordinate system binds to the simulation box. It is same for all the atoms. We use this frame to calculate the charge density structure factor $$S(\vec{k})$$ in reciprocal space. + - Local frame: this frame is defined differently on each atom, determined by the positions of its peripheral atoms. Normally, atomic multipole moments are most stable in the local frame, so it is the most suitable frame for force field input. In DMFF API, the local frames are defined using the same way as the AMOEBA plugin in OpenMM. The details can found in the following references: * [OpenMM forcefield.py](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py#L4894), line 4894~4933 * [J. Chem. Theory Comput. 2013, 9, 9, 4046–4063](https://pubs.acs.org/doi/abs/10.1021/ct4003702) - - quasi internal frame, aka. QI frame: a unique coordinate system to calculate the interaction between two sites in real space. Taking the connecting line of two sites as the Z-axis, the interaction tensor can be greatly simplified by using symmetry under this coordinate system to $$T_{tu}^{AB}$$. + - Quasi internal frame, aka. QI frame: this frame is defined for each pair of interaction sites, in which the z-axis is pointing from one site to another. In this frame, the real-space interaction tensor ($$T_{tu}^{AB}$$) can be greatly simplified due to symmetry. We thus use this frame in the real space calculation of PME. + + +## Polarization Interaction + +DMFF supports polarizable force fields, in which the dipole moment of the atom can respond to the change of the external electric field. In practice, each atom has not only permanent multipoles $\hat{Q}_t$, but also induced dipoles $U_{ind}$. The induced dipole-induced dipole and induced dipole-permanent multipole interactions needs to be damped at short-range to avoid polarization catastrophe. In DMFF, we use the Thole damping scheme identical to MPID (ref 6), which introduces a damping width ($$a_i$$) for each atom $$i$$. The damping function is then computed and applied to the corresponding interaction tensor. Taking $$U_{ind}$$-permanent charge interaction as an example, the definition of damping function is: -## Polarization term +$$ +1-\left(1+a u+\frac{1}{2} a^{2} u^{2}\right) e^{-a u} \\ a=a_i + a_j \\ u=r_{ij}/\left(\alpha_i \alpha_j\right)^{1/6} +$$ -DMFF supports polarizable force fields, in which the dipole moment of the atom can respond to the change of the external electric field. We support that each atom not only has permanent multipoles $\hat{Q}_t$ but induced dipole $U_{ind}$. The interaction between induced-induced dipole and induced-permanent dipole needs damping, which mathematical expression is the same as MPID(Ref 6). Specifically, each atom needs a thole parameter ($$a_i$$). When calculating the interaction of polarizable sites, the damping function will be introduced. Take $$U_{ind}$$-permanent charge interaction as an example, the definition of damping function is: +Other damping functions between multipole moments can be found in Ref 6, table I. -$$1-\left(1+a u+\frac{1}{2} a^{2} u^{2}\right) e^{-a u} \\ a=a_i + a_j \\ u=r_{ij}/\left(\alpha_i \alpha_j\right)^{1/6} $$ +It is noted that the atomic damping parameter $$a=a_i+a_j$$ is only effective on topological neighboring pairs (with $$pscale = 0$$), while a default value of $$a_{default}$$ is set for all other pairs. In DMFF, the atomic $$a_i$$ is specified via the xml API, while $$a_{default}$$ is controlled by the `dmff.admp.pme.DEFAULT_THOLE_WIDTH` variable, which is set to 5.0 by default. -Other damping form between multipole moment can refer to Ref 6, table I. +We solve $$U_{ind}$$ by minimizing the electrostatic energy: -We solve $$U_{ind}$$ by minimizing electrostatic energy. The energy can be written as follows: +$$ +V=V_{perm-perm}+V_{perm-ind}+V_{ind-ind} +$$ -$$V=V_{perm-perm}+V_{perm-ind}+V_{ind-ind}$$ +The last two terms are related to $U_{ind}$. Without introducing the nonlinear polarization terms (e.g., some force fields introduce $$U^4$$ to avoid polarization catastrophe), the last two terms are quadratic to $$U_{ind}$$: -the last two-termterms relate to $U_{ind}$. Without introducing the non-linear polarization term(e.g., some force fields introduce $$U^4$$ to avoid polarization catastrophe), the last two terms is quadratic function of $$U_{ind}$$: +$$ +V_{perm-ind}+V_{ind-ind}=U^TKU-FU +$$ -$$V_{perm-ind}+V_{ind-ind}=U^TKU-FU$$ +where the off-diagonal term of $K$ matrix is induced-induced dipole interaction, the diagonal term is formation energy of the induced dipoles ($\sum_i \frac{U_i^2}{2\alpha_i}$); the $F$ matrix represents permanent multipole - induced dipole interaction. We use the gradient descent method to optimize energy to get $U_{ind}$. -where the off-diagonal term of $K$ matrix is induced-induced dipole interaction, the diagonal term is form energy of induced dipole($\sum_i \frac{U_i^2}{2\alpha_i}$); the $F$matrix represents permanent multipole - induced dipole interaction. We use the gradient descent method to optimize energy to get $U_{ind}$. +In the current version, we temporarily assume that the polarizability is spherically symmetric, thus the polarizability $\alpha_i$ is a scalar, not a tensor. **Thus the inputs (`polarizabilityXX, polarizabilityYY, polarizabilityZZ`) in the xml API is averaged internally**. In future, it is relatively simple to relax this restriction: simply change the reciprocal of the polarizability to the inverse of the matrix when calculating the diagonal terms of the $K$ matrix. -In the current version, we temporarily assume that the polarizability is spherically symmetric; the polarizability $a_i$ is a scalar, not a tensor. It is relatively simple to relax this restriction; change the reciprocal of polarizability to the inverse of the matrix when calculating the diagonal term of the $K$ matrix. +## Dispersion Interaction -## Dispersion term +In ADMP, we assume that the following expansion is used for the long-range dispersion interaction: -We assume that the following expansion can describe the dispersion between atoms. +$$ +V_{disp}=\sum_{ij}-\frac{C_{ij}^6}{r_{ij}^6}-\frac{C_{ij}^8}{r_{ij}^8}-\frac{C_{ij}^{10}}{r_{ij}^{10}}-... +$$ -$$V_{disp}=\sum_{ij}-\frac{C_{ij}^6}{r_{ij}^6}-\frac{C_{ij}^8}{r_{ij}^8}-\frac{C_{ij}^{10}}{r_{ij}^{10}}-...$$ +where the dispersion coefficients are determined by the following combination rule: -where dispersion factor satisfies the following combination rule: +$$ +C^n_{ij}=\sqrt{C_i^n C_j^n} +$$ -$$C^n_{ij}=\sqrt{C_i^n C_j^n}$$ +Note that the dispersion terms should be consecutive even powers according to the perturbation theory, so the odd dispersion terms are not supported in ADMP. -Note that the dispersion terms should be continuous even powers according to the perturbation theory, so the odd dispersion terms are not supported in DMFF. +In ADMP, this long-range dispersion is computed using PME (*vida infra*), just as electrostatic terms. -## Long-range interaction with PME +In the classical module, dispersions are treated as short-range interactions using standard cutoff scheme. -The long-range interaction will be involved in treating electrostatic, polarization, and dispersion interactions. Take charge-charge interaction as an example. The interaction decays in the form of $O(\frac{1}{r})$, and its energy does not converge with the increase of cutoff distance. In calculating multipole and dispersion forces, the convergence speed of cutoff distance is also slow. We introduce Particle Meshed Ewald(PME) method to calculate those interactions. +## Long-Range Interaction with PME -An example, as charge-charge interaction, we split the interaction tensor by long and short-range in PME: +The long-range potential includes electrostatic, polarization, and dispersion (in ADMP) interactions. Taking charge-charge interaction as example, the interaction decays in the form of $O(\frac{1}{r})$, and its energy does not converge with the increase of cutoff distance. The multipole electrostatics and dispersion interactions also converge slow with respect to cutoff distance. We therefore use Particle Meshed Ewald(PME) method to calculate these interactions. -$$\frac{1}{r}=\frac{erfc(\kappa r)}{r}+\frac{erf(\kappa r)}{r}$$ +In PME, the interaction tensor is splitted into the short-range part and the long-range part, which are tackled in real space and reciprocal space, respectively. For example, the Coulomb interaction is decomposed as: -The first term is a short-range term, which can be calculated directly by using a simple distance cutoff in real space. The second term is a long-range term, which needs to be calculated in reciprocal space by fast Fourier transform(FFT). The total energy of charge-charge interaction is: +$$ +\frac{1}{r}=\frac{erfc(\kappa r)}{r}+\frac{erf(\kappa r)}{r} +$$ -$$E_{real}=\sum_{ij}\frac{erfc(\kappa r_{ij})}{r_{ij}}\\E_{recip} = \sum_{\vec{k}\neq 0} {\frac{2\pi}{Vk^2}\exp\left[\frac{k^2}{4\kappa^2}\right]\left|S(\vec{k})\right|^2}\frac{1}{\left|\theta(\vec{k})\right|^2}\\E_{self}=-\frac{\kappa}{\sqrt{\pi}}\sum_i {q_i^2} \\E=E_{real}+E_{recip}+E_{self}$$ +The first term is a short-range term, which can be calculated directly by using a simple distance cutoff in real space. The second term is a long-range term, which needs to be calculated in reciprocal space by fast Fourier transform(FFT). The total energy of charge-charge interaction is computed as: -As for multipole PME and dispersion PME, the expression refer to Ref 2, Ref 3, and Ref 5. +$$ +E_{real}=\sum_{ij}\frac{erfc(\kappa r_{ij})}{r_{ij}}\\E_{recip} = \sum_{\vec{k}\neq 0} {\frac{2\pi}{Vk^2}\exp\left[\frac{k^2}{4\kappa^2}\right]\left|S(\vec{k})\right|^2}\frac{1}{\left|\theta(\vec{k})\right|^2}\\E_{self}=-\frac{\kappa}{\sqrt{\pi}}\sum_i {q_i^2} \\E=E_{real}+E_{recip}+E_{self} +$$ + +As for multipolar PME and dispersion PME, the users and developers are referred to Ref 2, 3, and 5 for mathematical details. The key parameters in PME include: - - $\kappa$: controls the separation degree of long-range and short-range. The greater $\kappa$, the faster decay of the real space, the smaller the cutoff distance that can be used in the real space, and the more difficult the convergence of the reciprocal space and the more k-points are required; + - $\kappa$: controls the separation of the long-range and the short-range. The larger $\kappa$ is, the faster the real space energy decays, the smaller the cutoff distance can be used in the real space, and more difficult it is to converge the reciprocal energy and the larger $$K_{max}$$ it needs; - $ r_{c}$: cutoff distance in real space; - - $ K_{max}$: controls the number of maximum k-points + - $ K_{max}$: controls the number of maximum k-points in all three dimensions -In DMFF, we determine these parameters in the same way as the PME in [OpenMM](http://docs.openmm.org/latest/userguide/theory/02_standard_forces.html#coulomb-interaction-with-particle-mesh-ewald): +In DMFF, we determine these parameters in the same way as in [OpenMM](http://docs.openmm.org/latest/userguide/theory/02_standard_forces.html#coulomb-interaction-with-particle-mesh-ewald): -$$\kappa=\sqrt{-\log (2 \delta)} / r_{c} \\ K_{max}=\frac{2 \kappa d}{3 d^{1 / 5}}$$ +$$ +\kappa=\sqrt{-\log (2 \delta)} / r_{c} \\ K_{max}=\frac{2 \kappa d}{3 d^{1 / 5}} +$$ -where the user needs to specify the cutoff distance $r_c$ when building the neighbor list, the width of the box in each dimension $d$, and the energy calculation accuracy $\delta$. +where the user needs to specify the cutoff distance $r_c$ when building the neighbor list, the width of the box in each dimension $d$ (determined from the input box matrix), and the energy accuracy $\delta$. -In the current version, the parameter determination mechanism of multipole PME and dispersion PME is exactly the same as that of charge PME. +In the current version, the dispersion PME calculator uses the same parameters as in electrostatic PME. -## Short-range interaction +## Short-range Interaction -Short distance pair interaction refers to all interactions with the following forms: +Short-range pair interaction refers to all interactions with the following form: -$V=\sum_{ij}v(r_{ij})$ +$$ +V=\sum_{ij}v(r_{ij}) +$$ Some common short-range pair interactions include: - - Buckingham or excluded part of LJ potential: + - The repulsive part of the Buckingham or the Lennard-Jones potential: -$$v(r)=A\exp(-\beta r)\\v(r)=\frac{C^{12}}{r^{12}}$$ +$$ +v(r)=A\exp(-\beta r)\\v(r)=\frac{C^{12}}{r^{12}} +$$ - - Tang-Tonnies Damping: Damping function for short-range electrostatic and dispersive effects - 1. Combination Rule: + - Tang-Tonnies Damping: damping function for short-range electrostatic and dispersion energies. +$$ + f_n(r, \beta) = 1 - e^{-\beta r}\sum_{k=0}^n {\frac{(\beta r)^k}{k!}} +$$ -For most traditional force fields, pairwise parameters in each pair of interactions are determined by atomic parameters. This mathematical relationship is called the combination rule. For example, in the calculation of LJ potential, the following combination rule may be used: +In ADMP, the user can define a pairwise kernel function $$f(dr)=f(dr, m, a_i,a_j,b_i,b_j,\dots)$$ ($a_i, b_i$ are atomic parameters), then use `generate_pairwise_interaction` to raise the kernel function into an energy calculator (see details in ADMP manual). -$$v(r)=4\varepsilon\left[\left(\frac{\sigma}{r}\right)^{12}-\left(\frac{\sigma}{r}\right)^6\right]\\ \sigma=\frac{\sigma_i + \sigma_j}{2} \\ \varepsilon=\sqrt{\varepsilon_i \varepsilon_j}$$ +## Combination Rule: -DMFF does not make any assumptions about the specific mathematical forms of the combination rule and $v(r)$. Users need to write them in the definition of the pairwise kernel function. +For most traditional force fields, pairwise parameters between interacting particles are determined by atomic parameters. This mathematical relationship is called the combination rule. For example, in the calculation of LJ potential, the following combination rule may be used: -## Neighborlist +$$ +v(r)=4\varepsilon\left[\left(\frac{\sigma}{r}\right)^{12}-\left(\frac{\sigma}{r}\right)^6\right]\\ \sigma=\frac{\sigma_i + \sigma_j}{2} \\ \varepsilon=\sqrt{\varepsilon_i \varepsilon_j} +$$ -The calculation of all real spaces depends on the construction of the neighborlist. Its purpose is to find the "nearest neighbor" within a certain distance of the central atom by using an efficient method and calculating its interaction. +In ADMP module, we do not make any assumptions about the specific mathematical forms of the combination rule and $v(r)$. Users need to write them in the definition of the pairwise kernel function. -In DMFF, we use external code([jax-md](https://github.com/google/jax-md)) to build the nearest neighbor list. An external input argument named pairs is required in all real-space code, which contains the sequence numbers of all atomic pairs within a certain distance $r_c$. We assume that the pairs variable is in the form of `sparse` or `ordered sparse` in Jax-md. +## Neighbor List -Because the nearest neighbor list only provides atom **id** information, it has nothing to do with the derivation chain. +All DMFF real space calculations depends on neighbor list (or "pair list" as we sometimes call in DMFF). Its purpose is to keep a record of all the "neighbors" within a certain distance of the central atom, thus avoiding to go over all pairs explicitly. -## Topological scaling +In DMFF, we use external code ([jax-md](https://github.com/google/jax-md)) to build such neighbor list. An input argument named `pairs` is required in all real-space calculators, which contains the indices of all "interacting pairs" (i.e., pairs within a certain distance $r_c$). We assume that the `pairs` variable is in `sparse` or `ordered sparse` format in Jax-md. That is, a $N_p\times2$ index array with $N_p$ being the number of interacting pairs. It is noted that change of $N_p$ leads to recompilation of the code and significantly slows down the calculation. Therefore, jax-md usually buffers the list such that $N_p$ remains a constant in the simulation. DMFF expects the buffer part of the neighbor list is filled with $N+1$, with $N$ being the total number of atoms in the system. -In the organic molecular force field, in order to avoid double-counting with the bonding interaction term, we generally need to scale the non-bonding interaction between two atoms link to each other in topology. The specific scaling degree depends on the topological distance between the two atoms. We generally define two atoms with one bond as "1-2" interaction, and those separated by two bonds as "1-3" interaction, and so on. For example, in the OPLS-AA force field, all "1-2" non-bonding actions are turned off, while all "1-3" non-bonding actions are scaled to 50% of the normal non-bond actions. +Since the pair list only provides atom **id** information, it does not take part in the differentiation process, so it can be fed in as a normal numpy array (instead of a jax numpy array). -Important variables related to topological scaling in DMFF include: +## Topological scaling - - `covalent_Map`: the format is $N*N$ matrix, which defines the topological spacing between any two atoms. If the matrix element is 0, it indicates that the **topological** distance between the two atoms is too far, so there is a complete non-bonding interaction between them. +In order to avoid double-counting with the bonding term, we often need to scale the non-bonding interactions between two atoms that are topologically connected. The scaling factor depends on the topological distance between the two atoms. We define two atoms separated by one bond as "1-2" interaction, and those separated by two bonds as "1-3" interaction, and so on. For example, in the OPLS-AA force field, all "1-2" nonbonding interactions are turned off completely, while all "1-3" non-bonding interactions are scaled by 50%. DMFF supports such feature, and important variables related to topological scaling include: - - `mScales`: The sequence of scaling factors is stored. The first element is 1-2 non-bond scaling, the second element is 1-3 non-bond scaling, and so on. The last number of the sequence **must be 1**, which represents the complete, unscaled non-bond interaction. + - `covalent_Map`: a $N\times N$ matrix, which defines the topological spacings between atoms. If the matrix element is 0, it indicates that the **topological** distance between the two atoms is too far (or the two atoms are not connected), so the nonbonding interaction is fully turned on between them. - - `pScales`/`dScales`: It is only related to calculating polarization energy, representing induced-perm and induced-induced, respectively. The format is the same as that of `mScales`. + - `mScales`: The list of scaling factors. The first element is the scaling factor for all 1-2 nonbonding interaction, the second element is the scaling for 1-3 interactions, and so on. The list can be of any length, but the last number of the list **must be 1**, which represents the complete, unscaled nonbonding interaction. + - `pScales`/`dScales`: similar to `mScales`, but only related to polarizable calculations. They are scaling factors for induced-perm and induced-induced interactions, respectively. -## General multibody terms (such as ML force field) + +## General Many-Body Interactions (such as ML force field) TODO: -## Nonding interaction +## Bonding Interaction -Intramolecular bonding interactions refer to all interactions that depend on internal coordinates(aka. IC), which mainly include bond, angle, dihedral, etc. +Intramolecular bonding interactions refer to all interactions that depend on internal coordinates (IC), such as bonds, angles, and dihedrals, etc. * Harmonic Bonding Terms - The definition of binding term in DMFF is the same as that in OpenMM. For each key, we have: + The definition of the bonding term in DMFF is the same as in OpenMM. For each bond, we have: $$E=\frac{1}{2}k(x-x_0)^2$$ - Note prefactor $1/2$ before force constant + Note prefactor $1/2$ before the force constant. * Harmonic Angle Terms we have: @@ -161,13 +204,15 @@ Intramolecular bonding interactions refer to all interactions that depend on int * Multi IC coupling term -## Atomic classification +## Typification + +Before energy calculation, atomic and IC parameters (such as charge, multipole moment, dispersion coefficient, polarizability, force constant of each bond and angle, etc.) need to be assigned first. -Before energy calculation, atomic and IC parameters (such as charge, multipole moment, dispersion coefficient, polarizability, force constant of each bond and angle, etc.) need to be assigned. Generally speaking, these parameters should be related to each atom's specific environment and conformation or IC. However, in the traditional force field, in order to reduce the number of parameters, atoms and ICs are generally classified according to their topological environment, and atoms in the same class or ICs share parameters. Classifying each atom and IC and assigning its parameters is called typification. +Generally, these parameters should be dependent on the chemical and geometric environment of each atom and IC. However, in conventional force field, in order to reduce the number of parameters, atoms and ICs are classified according to their topological environment, and atoms/ICS in the same class would share parameters. The process of classifying each atom and IC and assigning the corresponding parameters according to their class is called typification. -In DMFF, the input parameters that need to be optimized are called **force field parameters**, and the parameters of each atom and IC after typing are called **atomic parameters**. Note that in the new ideal force field, if we can directly predict atomic parameters using machine learning model, the process of typification is *not necessary*. Therefore, in the architecture design of DMFF, we decouple the relevant codes of the typification process as much as possible, so that the core computing code based on atomic parameters has its own independent API and can be called separately. +In DMFF, the input parameters that need to be optimized are called **force field parameters**, and the parameters of each atom and IC after typification are called **atomic parameters**. Note that in an ideal force field, if we can directly predict atomic parameters using machine learning model, the process of typification is *not necessary*. Therefore, in DMFF, we decouple the typification code with the computation kernels, so that the core calculators based on atomic parameters has their own API and can be invoked independently. The typification code, in combination with the xml/pdb input parsers, composes the high-level API (the `dmff.api` module). -The design of the typing module of DMFF is basically based on the existing framework of OpenMM. DMFF needs to keep the derivation chain uninterrupted when unfolding force field params into atomic params. Therefore, under the condition of maintaining the same call logic and process of OpenMM, it rewrites the typing code of OpenMM with Jax. Generally speaking, OpenMM/DMFF requires users to clearly define the category of each atom in each residue and the connection mode between atoms to form a residue definition template. Then the residue template is used to match the PDB file to typify the whole system. See the following [documents](../dev_guide/arch.MD) for details. +The design of the high-level DMFF API is based on the existing framework of OpenMM. DMFF needs to keep the derivation chain uninterrupted when dispatching the force field params into atomic params. Therefore, maintaining the basic design logic of OpenMM, we rewrite the typification part of OpenMM using Jax. Briefly speaking, OpenMM/DMFF requires the users to clearly define the type of each atom in each residue and the connection mode between atoms in residue templates. Then the residue templates are used to match the PDB file to typify the whole system. See the following [documents](../dev_guide/arch.MD) for details. ## References: @@ -176,4 +221,4 @@ The design of the typing module of DMFF is basically based on the existing frame 3. [The dispersion Ewald/PME](https://aip.scitation.org/doi/pdf/10.1063/1.470117) 4. [Frenkel & Smit book](https://www.elsevier.com/books/understanding-molecular-simulation/frenkel/978-0-12-267351-1) 5. Note: multipole ewald.pdf -6. [MPID Reference](https://doi.org/10.1063/1.4984113) \ No newline at end of file +6. [MPID Reference](https://doi.org/10.1063/1.4984113) From 696629051297173035635000b2bc0b30d1524480 Mon Sep 17 00:00:00 2001 From: KuangYu Date: Wed, 4 May 2022 17:14:02 +0800 Subject: [PATCH 7/8] Went over docs, first pass --- docs/admp/frontend.md | 85 ++++ docs/admp/readme.md | 238 ++++++++++- docs/assets/DMFF_arch.md | 73 ++++ docs/assets/arch.png | Bin 120886 -> 72522 bytes docs/dev_guide/arch.md | 118 ++++-- docs/dev_guide/convention.md | 2 +- docs/dev_guide/introduction.md | 18 +- docs/index.md | 10 +- docs/modules/admp.md | 5 + docs/user_guide/installation.md | 16 +- docs/user_guide/introduction.md | 19 +- docs/user_guide/multipole_pme.md | 605 ++++++++++++++++++++++++++++ docs/{admp => user_guide}/theory.md | 69 ++-- docs/user_guide/xml_spec.md | 45 ++- mkdocs.yml | 6 +- 15 files changed, 1199 insertions(+), 110 deletions(-) create mode 100644 docs/admp/frontend.md create mode 100644 docs/assets/DMFF_arch.md create mode 100644 docs/modules/admp.md create mode 100644 docs/user_guide/multipole_pme.md rename docs/{admp => user_guide}/theory.md (84%) diff --git a/docs/admp/frontend.md b/docs/admp/frontend.md new file mode 100644 index 000000000..fa456fb73 --- /dev/null +++ b/docs/admp/frontend.md @@ -0,0 +1,85 @@ +# Implemented Short-Range Potentials in DMFF + +DMFF already provides the frontends for many frequently-used short-range potentials. +We document them in this page: + +## SlaterExForce + +Slater-type short-range repulsive force +Ref: jctc 12 3851 + +Example: +```xml + + + + + + + +``` + +Formula: + +$$ +\displaylines{ +E = \sum_{ij} {A_{ij}P(B_{ij}, r)\exp(-B_{ij}r)} \\ +P(B_{ij}, r) = \frac{1}{3}B_{ij}^2 r^2 + B_{ij} r + 1 \\ +A_{ij} = A_i A_j \\ +B_{ij} = \sqrt{B_i B_j} +} +$$ + +## QqTtDampingForce + +Charge-Charge Tang-Tonnies damping force, used in combination with normal PME + +Example: +```xml + + + + + + + +``` + +Formula: + +$$ +\displaylines{ +E = \sum_{ij} {- e^{-B_{ij} r} (1 + B_{ij}r) \frac{q_i q_j}{r}} \\ +B_{ij} = \sqrt{B_i B_j} +} +$$ + +## SlaterDampingForce + +Slater-type damping function for dispersion. Used in combination with the normal dispersion PME +Ref: jctc 12 3851 + +Example: +```xml + + + + + + + +``` + +Formula: + +$$ +\displaylines{ +E = -\sum_{n=6,8,10} {\sum_{ij} {f_n(x)\frac{\sqrt{C_i^n C_j^n}}{r^n}}} \\ +f_n(x) = - e^{-B_{ij} x}\sum_{k=0}^n {\frac{(B_{ij} x)^k}{k!}} \\ +x = B_{ij}r - \frac{2(B_{ij}r)^2 + 3B_{ij}r}{(B_{ij}r)^2 + 3B_{ij}r + 3} \\ +B_{ij} = \sqrt{B_i B_j} +} +$$ diff --git a/docs/admp/readme.md b/docs/admp/readme.md index 64ef7453a..b0e157372 100644 --- a/docs/admp/readme.md +++ b/docs/admp/readme.md @@ -11,11 +11,6 @@ This module provides an auto-differentiable implementation of multipolar polariz The module is based on [JAX](https://github.com/google/jax) and [JAX-MD](https://github.com/google/jax-md) projects. - - - - - ## Settings In `admp/settings.py`, you can modify some global settings, including: @@ -24,19 +19,240 @@ In `admp/settings.py`, you can modify some global settings, including: **DO_JIT**: whether do jit or not. +In admp/pme.py, you can also modify the `DEFAULT_THOLE_WIDTH` variable +(You can directly set `dmff.admp.pme.DEFAULT_THOLE_WIDTH` in your code) ## Example -We provide a MPID 1024 water box example. In water_1024 and water_pol_1024, we show both the nonpolarizable and the polarizable cases. +We provide a polarizable 1024 water box example in the water_fullpol folder: ```bash -cd ./examples/water_1024 -./run_admp.py - -cd ./examples/water_pol_1024 -./run_admp.py +cd ./examples/water_fullpol +./run.py ``` if `DO_JIT = True`, then the first run would be a bit slow, since it tries to do the jit compilation. Further executions of `get_forces` or `get_energy` should be much faster. +Following this example, we will introduce the frontend and the backend of the ADMP module. + +## Frontend + +In the `forcefield.xml` file, you can find the frontends of two force field components: + +### ADMPDispForce + +The corresponding XML node is like: + +```xml + + + + +``` + +It computes the following function: + +$$ +\displaylines{ +E = \sum_{i + + + + + + +``` + +In here, the `mScales`, `pScales`, and `dScales` are explained in the [theory](../user_guide/theory.md) page. `lmax` specifies +the highest order of multipoles (`lmax=2` means up to quadrupole). All input parameters that follows are in `nm` and `kJ/mol`. +Currently, we only support the isotropic polarizabilities, meaning the `XX`, `YY`, and `ZZ` components will be averaged. + +The multipole moments are specified in local frames with Cartesian representations. One needs to be careful about the convention +of the Cartesian tensor: in the frontend of ADMP, we adopt the openmm convention, the quadrupole value of which is 3 times smaller +than the convention adopted in Anthony's book. + +In `run.py`, when creating the potential function, several key parameters are noted: +```python +potentials = H.createPotential(pdb.topology, nonbondedCutoff=rc*angstrom, nonbondedMethod=CutoffPeriodic, ethresh=1e-4) +``` +* `ethresh`: this is the energy threshold for PME +* `rc`: the cutoff distance. `rc`, `ethresh`, and `box` together, determine the $K_{max}$ and $\kappa$ + (please see [theory](../user_guide/theory.md)). + Note that the `rc` variable in here is only used to determine the PME settings. The user has to make sure the `rc` + value used in here is the same as the one used in neighbor list construction. +* `nonbondedMethod`: Currently two methods are supported: `CutoffPeriodic` and `PME` (default). When `CutoffPeriodic` + is used, PME is turned off by setting $\kappa=0$ and removing the reciprocal space contribution. + + +## Backend + +The backend of ADMP can be invoked independently without the frontend API, which is much more flexible. +It can be utilized to implement fancy force fields with fluctuating atomic parameters. +***Note that all backend functions are assuming `angstrom` unit, instead of `nm`.*** This is different to the frontend! + +The examples for backend are: examples/water_1024 and examples/water_pol_1024 + +There are mainly three calculators implemented in ADMP backend: + +### ADMPPmeForce + +The `ADMPPmeForce` is initialized as: + +```python +pme_force = ADMPPmeForce(box, axis_type, axis_indices, covalent_map, rc, ethresh, lmax, lpol=True, lpme=True, steps_pol=None) +``` + +The inputs are: + +* `box`: the 3*3 box matrix. Vectors are arranged in rows, in angstrom. + +* `axis_type`: the axis type for the local frame definition for each atom: +```python +ZThenX = 0 +Bisector = 1 +ZBisect = 2 +ThreeFold = 3 +ZOnly = 4 +NoAxisType = 5 +LastAxisTypeIndex = 6 +``` + +* `axis_indices`: indices for local axis definitions, see introduction to local frame in [theory](../user_guide/theory.md) + +* `covalent_map`: a $N\times N$ ($N$ being the number of atoms) matrix of covalent spacings between atoms. + $n$ means the two atoms are $n$ bonds away, and 0 means the two atoms are considered as not bonded topologically. + +* `rc`: cutoff distance in real space. Only used to determine the PME settings. + +* `ethresh`: energy threshold for PME. + +* `lmax`: max L for multipoles. + +* `lpol`: whether turn on polarization? + +* `lpme`: wether turn on PME? + +* `steps_pol`: specifies number of SCF steps when solving induced dipoles. If set to None, then the SCF iteration will stop + when the field is less than `dmff.admp.settings.POL_CONV`. Otherwise, exact `steps_pol` number of iterations will be performed. + ***This tag is important, and needs to be set if you want to jit the function externally.*** + +Once the `pme_force` is initialized, the differentiable calculator can be called as: + +```python +# if lpol = False +E = pme_force.get_energy(positions, box, pairs, Q_local, pol, tholes, mScales, pScales, dScales, U_init=U) +# if lpol = True +E = pme_force.get_energy(positions, box, pairs, Q_local, mScales) +``` + +Important inputs include: + +* `Q_local`: spherical harmonic multipole moments in local frame (in Angstrom). + +* `pol`: polarizability for each atom + +* `tholes`: thole width for each atom + +* `mScales`, `pScales`, `dScales`: topological scaling factors + +* `U_init`: initial values for induced dipoles. + + +### ADMPDispPmeForce + +This force computes the long range dispersion interactions with C6, C8, and C10 terms. +It is initialized and called as: + +```python +disp_force = ADMPDispPmeForce(box, covalent_map, rc, ethresh, pmax, lpme=True) +E = disp_force.get_energy(positions, box, pairs, c_list, mScales) +``` + +Most parameters are similar to the PME force, several other important parameters include: + +* `pmax`: maximum power of dispersion, usually 10. + +* `c_list`: the ***square root*** of dispersion coefficients. (N*3) array, that is, + sqrt(C6), sqrt(C8), and sqrt(C10) of each atom. + + +### Short-Range Pairwise Force + +DMFF provides a simple approach to raise a distance-dependent pair interaction kernel into +a many-body potential function. Suppose you want to implement a function looks like this: + +$$ +E = \sum_{ij} {f(r_{ij}; a_i, a_j, b_i, b_j, c_i, c_j)} +$$ + +Where $a,b,c$ are atomic parameters. + +Then you need to define a pairwise kernel looks like: + +```python +from jax import vmap, jit + +def f_kernel(r, m, a_i, a_j, b_i, b_j, c_i, c_j): + # do calculations, get E + return E * m + +f_kernel = vmap(jit(f_kernel)) +``` + +Then raise it to a many-body potential for a particular system: + +```python +potential_fn = generate_pairwise_interaction(f_kernel, covalent_map) +# a_list, b_list, c_list are atomic parameter lists +E = potential_fn(positions, box, pairs, mScales, a_list, b_list, c_list) +``` + +The resulted `potential_fn` function will take care the following business for you: + +1. Topological scaling based on `covalent_map` and `mScales`; + +2. Assign parameters for each interacting pair; + +We can use this to immplement short-range repulsion and short-range damping quite easily. + + + + + diff --git a/docs/assets/DMFF_arch.md b/docs/assets/DMFF_arch.md new file mode 100644 index 000000000..e0bd17511 --- /dev/null +++ b/docs/assets/DMFF_arch.md @@ -0,0 +1,73 @@ +```mermaid +flowchart TB +E(["atomic & topological params"]) +subgraph G1["Parser & Typification"] +A["force field xml"] --> B(["parseElement"]) +B --> C[Generators with forcefield params] +C --> D(["createPotential"]) +D --> E +end +subgraph G2["ADMP Calculators"] +E --> |init|F(["General Pairwise Calculator"]) +E --> |init|G(["Multipole PME Caculator"]) +E --> |init|H(["Dispersion PME Calculator"]) +end +subgraph G3["Classical Calculators"] +E --> |init|K["Intramol Calculators"] +E --> |init|L["Intermol Calculators"] +end +J["pairs (neighbor list from jax-md)"] --> |input|I +F --> |return|I(["potential(pos, box, pairs, params)"]) +G --> |return|I +H --> |return|I +K --> |return|I +L --> |return|I +C --> |differentiable generator.params|I +``` + + + +```mermaid +graph +A("kernel(dr, m, p0i, p0j, p1i, p1j, ...)") --> D([generate_pairwise_interaction]) +B[covalent_map] --> D +C[static variables] --> D +D --> E(["pair_energy(pos, box, pairs, p0list, p1list, ...)"]) +``` + +```mermaid +classDiagram + class ADMPPmeForce + ADMPPmeForce : +axis_type + ADMPPmeForce : +axis_indices + ADMPPmeForce : +rc + ADMPPmeForce : +ethresh + ADMPPmeForce : +kappa, K1, K2, K3 + ADMPPmeForce : +pme_order + ADMPPmeForce : +covalent_map + ADMPPmeForce : +lpol + ADMPPmeForce : +n_atoms + ADMPPmeForce : +__init__(self, box, axis_type, axis_indices, covalent_map, rc, ethresh, lmax, lpol=False) + ADMPPmeForce : +update_env(attr, val) + ADMPPmeForce : +get_energy(pos, box, pairs, Q_local, pol, tholes, mScales, pScales, dScales) + +``` + + + +``` Mermaid +classDiagram + class ADMPDispPmeForce + ADMPDispPmeForce : +kappa, K1, K2, K3 + ADMPDispPmeForce : +pme_order + ADMPDispPmeForce : +rc + ADMPDispPmeForce : +ethresh + ADMPDispPmeForce : +pmax + ADMPDispPmeForce : +covalent_map + ADMPDispPmeForce : +__init__(self, box, covalent_map, rc, ethresh, pmax) + ADMPDispPmeForce : +update_env(attr, val) + ADMPDispPmeForce : +get_energy(positions, box, pairs, c_list, mScales) +``` + + + diff --git a/docs/assets/arch.png b/docs/assets/arch.png index f4003ef6a8b23c8e21b5efbe6fa9b324cc673bdc..4d4a39c08a014e30cd6acd2fe69b84a8657db013 100644 GIT binary patch literal 72522 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 literal 120886 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%0D|8egwzA^+iLN7VvQ1Q_VnO=R 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 Cg;M1J diff --git a/docs/dev_guide/arch.md b/docs/dev_guide/arch.md index 9b6fe35cb..0204000df 100644 --- a/docs/dev_guide/arch.md +++ b/docs/dev_guide/arch.md @@ -2,27 +2,48 @@ ![arch](../assets/arch.png) -The overall framework of DMFF can be divided into two parts: parser & typing and calculators. We usually refer to the former as the *frontend* and the latter as the *backend* for ease of description. +The overall architechture of DMFF can be divided into two parts: 1. parser & typing and 2. calculators. +We usually refer to the former as the *frontend* and the latter as the *backend* for ease of description. -DMFF introduces different forms of force fields in a modular way. For any form of force field, it is divided into frontend modules and backend modules. The frontend module is responsible for input file parsing, molecular topology construction, atomic typification, and unfolding from the forcefield parameter layer to the atomic parameter layer; The backend module is the calculation core, which calculates the energy & force of the system at a time by particle positions and system properties. +DMFF introduces different forms of force fields in a modular way. For each force field form +(in OpenMM, each form is also called a `Force`), there is a frontend module and a backend module. +The frontend module is responsible for input file parsing, molecular topology construction, atom typification, +and dispatching the forcefield parameters into the atomic parameter; The backend module is the calculation kernel, +which calculates the energy & force of the system, using particle positions and atomic parameters as inputs. -In the design of the front-end module, DMFF reuses the frontend parser module from OpenMM and realizes the functions of topology analysis. All frontend modules are stored in `api.py` and called by the Hamiltonian class. +In the design of the frontend modules, DMFF reuses the frontend parser from OpenMM for topology analysis. +The core class in frontend is the `Generator` class, which should be defined for each force field form. +All frontend `Generators` are currently put in `api.py` and are called by the top-level `Hamiltonian` class. -The backend module is usually an automatically differentiable computing module built with Jax. +The backend module is usually an automatically differentiable calculator built with Jax. -The structure of frontend and backend modules will be introduced in detail in the following documents. +The structures of the frontend and the backend modules will be introduced in detail in below. ## How Frontend Works -Frontend modules are stored in `api.py`. `Hamiltonian` class is the top-level class exposed to users by DMFF. `Hamiltonian` class reads the path of the XML file, parses the XML file, and calls different frontend modules according to the XML tags. The frontend module has the same form as OpenMM's generator [forcefield.py](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py). The `Generator` class takes the XML tag in and parse the parameters, initialize the backend calculator and provide the interface of energy calculation method. - -When users use the DMFF, the only thing need to do is initilize the the `Hamiltonian` class. In this process, `Hmiltonian` will automatically parse and initialize the corresponding potential function according to the tags in XML. The call logic is shown in the following chart. The box represents the command executed in Python script, and the rounded box represents the internal operation logic of OpenMM when executing the command. +Frontend modules are stored in `api.py`. `Hamiltonian` class is the top-level class exposed to users by DMFF. +`Hamiltonian` class reads the path of the XML file, parses the XML file, and calls different frontend modules +according to the `*Force` tags found in XML. The frontend generator has the same form as the OpenMM's generators +[forcefield.py](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py). +The `Generator` class parses the corresponding XML tag to obtain the force field parameters, +then use the parameters to initialize the backend calculator. +It also provides the interface to wrap the backend calculators into potential functions, +which are eventually returned to the users. + +When users use DMFF, the only thing they need to do is to initilize the the `Hamiltonian` class. +In this process, `Hamiltonian` will automatically parse and initialize the corresponding potential function +according to the tags in XML. The call logic is shown in the following chart. +The box represents the command executed in Python script, +and the rounded box represents the internal operation logic of OpenMM when executing the command. ![openmm_workflow](../assets/opemm_workflow.svg) ### Hamiltonian Class -Hamiltonian class is the top-level frontend module, which inherits from the [forcefield class](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py) of OpenMM. It is responsible for parsing XML force field files and generating potential functions to calculate system energy for given topology information. First, the usage of Hamiltonian class is given: +The `Hamiltonian` class is the top-level frontend module, which inherits the +[forcefield class](https://github.com/openmm/openmm/blob/master/wrappers/python/openmm/app/forcefield.py) in OpenMM. +It is responsible for parsing the XML force field files and generating potential functions to calculate system energy +with the given topology information. First, the usage of the `Hamiltonian` class is given: ```python @@ -31,12 +52,10 @@ app.Topology.loadBondDefinitions("residues.xml") pdb = app.PDBFile("waterbox_31ang.pdb") rc = 4.0 # generator stores all force field parameters -generator = H.getGenerators() -disp_generator = generator[0] -pme_generator = generator[1] +generators = H.getGenerators() +disp_generator = generators[0] +pme_generator = generators[1] -pme_generator.lpol = True # debug -pme_generator.ref_dip = 'dipole_1024' potentials = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom) # pot_fn is the actual energy calculator pot_disp = potentials[0] @@ -49,19 +68,27 @@ pot_pme = potentials[1] * read AtomTypes tag, store AtomType of each atom; * for each Force tag, call corresponding `parseElement` method in `app.forcefield.parser` to parse itself, and register `generator`. -`app.forcefield.parser` is a `dict`, the keys are Force tag names, and the values are `parseElement` method of `generator`. The Hamiltonian parse XML file will use the tag name to look up the corresponding `parseElement` method—the `generator` instance stores raw data from the XML file. You can use generators by `getGenerators()` in Hamiltonian. +`app.forcefield.parser` is a `dict`, the keys are Force tag names, and the values are the `parseElement` method +of the corresponding `generator`. When `Hamiltonian` parses the XML file, it will use the tag name to look up the +corresponding `parseElement` method, then calls it to initialize the `generator` instance, which stores the raw +parameters from the XML file. You can access all the generators by the `getGenerators()` method in Hamiltonian. + ### Generator Class -The generator class in charge of input file analysis, molecular topology construction, atomic classification, and expansion from force field parameter layer to atomic parameter layer. It is a middle layer link `Hamiltonian` and backend. See the following documents for the specific design logic: +The generator class is in charge of input file analysis, molecular topology construction, atom classification, +and expanding force field parameters to atomic parameters. It is a middle layerthat links `Hamiltonian` with the backend. +See the following chart for its design logic: ![generator](../assets/generator.svg) -The custom generator must define those methods: +In a custom generator one must define the following methods: -* @staticmethod parseElement(element, hamiltonian): OpenMM use `element.etree` parse tag in XML file, and `element` is `Element` object. For instance, if there were a section in XML file that defines bond potential: +* @staticmethod parseElement(element, hamiltonian): OpenMM uses `element.etree` to parse tags in XML file, +and the first argument `element` is an `Element` object. For instance, if there were a section in XML file +that defines a harmonic bond stretching potential: ```xml @@ -70,12 +97,30 @@ The custom generator must define those methods: ``` -will activate `HarmonicBondJaxGenerator.parseElement` method which is the value of key `app.forcefield.parsers["HarmonicBondForce"]`. You can use `element.findall("Bond")` to get a iterator of the `Element` object of tage. For `Element` object, you can use `.attrib` to get {'type1': 'ow} properties in `dict` format. - -What `parseElement` does is parse the `Element` object and initialize the generator itself. The parameters in generators can be classified into two categories. Those differentiable should store in a `dict` named `dict`, and non-differentiable static parameters can simply be set as the generator's attribute. Jax support `pytree` nested container, and `params` can be directly grad. +This input will be converted into an `Element` object first and be passed to the `HarmonicBondJaxGenerator.parseElement` +method, which should have been registered in `app.forcefield.parsers["HarmonicBondForce"]`. +The developer needs to define the `parseElement` method to parse the input `Element` object and to initialize the generator itself. +For example, in this case, you can use `element.findall("Bond")` to get an iterator that iterates over all the tags. +Then you can use `.attrib` to access all the properties (`type1`, `type2`, `length`, and `k`) within each tag in `dict` format. +These properties, as force field parameters, can be classified into two categories. The first category is differentiable parameters +(such as `length` and `k`), which may be subject to further optimization. By design, these parameters should be fed into the potential +function as explicit input arguments. Therefore, these parameters should be gathered in a `dict` object named `params`, which is then +saved as an attribute of the `generator`. The second category is non-differentiable variables (such as `type1` and `type2`): it is +unlikely that you are going to optimize them, so they are also called *static* variables. These variables will be used by the potential +function implicitly and not be exposed to the users. Therefore, you may save them in `generator` at will, as long as they can be +accessed by the potential function later. -* `createForce(self, system, data, nonbondedMethod, *args)` pre-process XML parameters, initialize calculator. `System` and `data` are given by OpenMM's forcefield class, which store topology/atomType information (For now you need to use debug tool to access). To avoid break the differentiate chain, from XML raw data to per-atom properties, we should use `data` to construct per-atom info directly. Here is an example: +* `createForce(self, system, data, nonbondedMethod, *args)` pre-process the force field parameters from XML, and use them to initialize +the backend calculators, then wrap the calculators using a potential function and returns it. +`System` and `data` are given by OpenMM's forcefield class, which store topology/atomType information (for now you need to use +debug tool to access). Bear in mind that we should not break the derivative chain from the XML raw data (force field parameters) +to the per-atom properties (atomic parameters). So we should do the parameter dispatch (i.e., dispatching force field parameters to +each atom) within the returned potential function. Therefore, in `createForce`, we usually only construct the atomtype index map using +the information in `data`, but do not dispatch parameters! The atomtype map will be used in potential function implicitly, to dispatch +parameters. + +Here is an example: ```python map_atomtype = np.zeros(n_atoms, dtype=int) @@ -85,7 +130,8 @@ for i in range(n_atoms): map_atomtype[i] = np.where(self.types == atype)[0][0] ``` -Finally, we need to bind the calculator's compute function to `self._jaxPotential` +Finally, we need to bind the calculator's compute function to `self._jaxPotential`, which is the final potential function (`potential_fn`) +returned to users: ```python @@ -98,7 +144,10 @@ def potential_fn(positions, box, pairs, params): self._jaxPotential = potential_fn ``` -All parameters accepted by `potential_fn` should be differentiable. Non differentiable parameters are passed into it by closure (see code convention section). Meanwhile, if the generator need to initialize multiple calculators (e.g. `NonBondedJaxGenerator` will call `LJ` and `PME` two kinds of calculators), `potential_fn` will return the summation of two potential energy. +The `potential_fn` function only takes `(positions, box, pairs, params)` as explicit input arguments. All these arguments except +`pairs` (neighbor list) should be differentiable. Non differentiable parameters are passed into it by closure (see code convention section). +Meanwhile, if the generator needs to initialize multiple calculators (e.g. `NonBondedJaxGenerator` will call both `LJ` and `PME` calculators), +`potential_fn` should return the summation of the results of all calculators. Here is a pseudo-code of the frontend module, demonstrating basic API and method @@ -245,9 +294,9 @@ app.forcefield.parsers["HarmonicBondForce"] = HarmonicBondJaxGenerator.parseElem ### Force Class -Force class is the module to build potential function. It does not require OpenMM and can -be very flexible. For instance, the Force class of harmonic bond potential is shown below -as an example of jax potential function. +Force class is the backend module that wraps the calculator function. +It does not rely on OpenMM and can be very flexible. For instance, +the Force class of harmonic bond potential is shown below as an example. ```python def distance(p1v, p2v): @@ -286,3 +335,18 @@ class HarmonicBondJaxForce: self.get_energy = self.generate_get_energy() self.get_forces = value_and_grad(self.get_energy) ``` + +The design logic for the `Force` class is: it saves the *static* variables inside the class as +the *environment* of the real calculators. Examples of the static environment variables include: +the $\kappa$ and $K_{max}$ in PME calculators, the covalent_map in real-space calculators etc. +For a typical `Force` class, one needs to define the following methods: + +* `__init__`: The initializer, saves all the *static* variables. +* `update_env(self, attr, val)`: updates the saved *static* variables, and refresh the calculators +* `generate_get_energy(self)`: generate a potential calculator named `get_energy` using the current + environment. +* `refresh_calculators(self)`: refresh all calculators if environment is updated. + +In ADMP, all backend calculators only take atomic parameters as input, so they can be invoked +independently in hybrid ML/force field models. The dispatch of force field parameters is done +in the `potential_fn` function defined in the frontend. diff --git a/docs/dev_guide/convention.md b/docs/dev_guide/convention.md index d6d238664..6aa83f78a 100644 --- a/docs/dev_guide/convention.md +++ b/docs/dev_guide/convention.md @@ -6,7 +6,7 @@ In this section, you will learn: ## code organization -The root directory of DMFF has following sub-directory: +The root directory of DMFF has following sub-directories: - `dmff`: source code of project - `docs`: documents in markdown diff --git a/docs/dev_guide/introduction.md b/docs/dev_guide/introduction.md index 13679bc91..864be0e1e 100644 --- a/docs/dev_guide/introduction.md +++ b/docs/dev_guide/introduction.md @@ -1,21 +1,21 @@ # 1. Introduction -In the developer guide, you will learn: +In the developer's guide, you will learn: + Architecture of DMFF + Code convention -+ Easily expand a new form -+ Write related docs ++ Implement a new function form ++ Write docs + Checklist before PR -DMFF aims to establish a force field calculation and parameter fitting framework supporting automatic differentiation. In order to meet various forms of force field, DMFF calculates energy and force parameters through different force field sub-modules. DMFF ensures sufficient decoupling and modularization at the beginning of the design and can easily add new modules. +DMFF aims to establish a force field calculation and parameter fitting framework based on the automatic differentiation technique. For different forms of force field, DMFF calculates energy and energy gradients through different sub-modules. DMFF ensures sufficient decoupling and modularization at the beginning of the design so new modules can be added easily. -In the *Architecture of DMFF* section, the design of DMFF will be introduced carefully. we will talk about how the parameters are loaded from the XML file and how to organize them for the following calculation and gradient. This work is mainly in charge by a class called `Generator`. Then the calculation code will be explained, which is the bearer of energy and force called `calculation kernel`, a pure function that takes particles' properties and positions and returns the energy. +In the *Architecture of DMFF* section, the overall design of DMFF will be introduced carefully. We will talk about how the parameters are loaded from the XML file and how they are organized for the following energy and gradient calculations. This work is primarily carried out by the `Generator` class. Then we will explain the heavy-lifting `calculators`, which are pure functions that take atomic positions and force field parameters as inputs and compute the energy. -Some programming styles and standards should obey in the *Code convention* section. Those conventions will help developers write the code quickly; on the other hand, make the code reviewer and other maintainers easier to modify. +When developing DMFF, the developers need to obey some programming styles and standards. These are explained in the *Code convention* section. These conventions will help the code reviewers and other developers to understand and maintain the project. -In the *easily expand new form* section, finally, we can write the calculation part of energy and force. However, before you turn your equation to the code to be consistent with other force field sub-modules, this section will introduce the spec that your calculation kernel should follow. +In the *Implementation of New Potentials* section, we will show how to implement a new calculator for a new potential. Before you turn your equations into code, this section will introduce the specs that your code should follow, making it consistent with other force field sub-modules in DMFF. -In the *Write related docs* section, we will talk about how to write the manual. Duo to the DMFF is a collection of force field module, each force field has it unique parameters and usage. To make it clear to use and easy to maintain, you should write down the theroy behind the code and the meaning of parameters. +In the *Document Writing* section, we will talk about how to write docs for your new module. DMFF is a collection of force field calculators, and each force field calculator has its own parameters and may be invoked in different ways. Therefore, to make it easy to use and easy to maintain, the developers are required to document the theroy behind the code and the user interface of the code before PR. -In the *Checklist before PR* section is what you should do before you publish your work to the Github. In this section, you will know how to write unit test, format checking and proper comment. +In the *Checklist before PR* section is what you should do before you submit your PR to Github. In this section, you will learn how to write unit tests, check format, and add proper commentsin your code. diff --git a/docs/index.md b/docs/index.md index 8ecd3198f..2af0071a9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,10 +1,8 @@ # DMFF's Manual -**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a package written in Python, designed to implement differentiable molecular force field calculations. This project aims to establish a general extensible framework to support the development of force fields by minimizing the effort required during the parameters fitting process. Currently, the project mainly focuses on development of force fields that describe the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers (PEG) and small organic molecules (organic electrolyte, drug-like molecules). +**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a Jax-based python package that provides a full differentiable implementation of molecular force field calculations. This project aims to establish an extensible framework to minimize the efforts in force field parameter fitting, and to support an easy evaluation of forces and virial tensors for complicated advanced potentials (such as polarizable models with geometry-dependent atomic parameters). Currently, this project mainly focuses on the force fields of the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers, and small organic molecules (organic electrolyte, drug-like molecules) etc. And we support both the conventional point charge models (OPLS and AMBER like) and multipolar polarizable models (AMOEBA and MPID like). -There are many factors involved in organic molecular interactions, and the behavior of organic molecular systems (such as protein folding, polymer structure, etc.) often depends on the joint influence of various interactions. The existing general organic molecular force fields (such as OPLS and amber) are mainly empirical fitting, and their portability and prediction ability are insufficient. When extended to new molecules, the parameter fitting process is cumbersome and strongly depends on error cancellation under manual intervention. - -In order to accurately describe organic molecular systems, we need to accurately model various interactions within and between molecules (including long-range and short-range). Therefore, it is necessary to realize a closer combination of traditional force field and AI method, and apply AI tools to short-range potential energy surface fitting, traditional force field parameter optimization and so on. We will use the automatic differential programming framework to develop the tool chain from force field calculation to molecular mechanics simulation, so as to realize the complex functions such as traditional force field / machine learning hybrid model and parameter optimization based on molecular mechanics trajectory. Based on this project, a new generation of general organic force field database is developing, and a more automatic force field development process is established. +The behavior of organic molecular systems (e.g., protein folding, polymer structure, etc.) is often determined by a complex effect of many different types of interactions. The existing organic molecular force fields are mainly empirically fitted and their performance relies heavily on error cancellation. Therefore, the transferrabilities and the prediction powers of these force fields are insufficient. For new molecules, the parameter fitting process requires heavy load of manual intervention and can be quite cubersome. In order to automize the parametrization process and increase the robustness of the model, it is necessary to apply modern AI techniques in conventional force field development. This project serves for this purpose by utilizing the automatic differential programming technique to develop a toolchain, which may lead to many advanced functions such as: hybrid force field / machine learning models and parameter optimization based on molecular mechanics trajectory. ## User Guide @@ -12,6 +10,8 @@ In order to accurately describe organic molecular systems, we need to accurately + [2. Installation](user_guide/installation.md) + [3. Compute energy and forces](user_guide/compute.md) + [4. Compute gradients with auto differentiable framework](user_guide/auto_diff.md) ++ [5. Theories](user_guide/theory.md) ++ [6. Introduction to force field xml files](user_guide/xml_spec.md) ## Developer Guide + [1. Introduction](dev_guide/introduction.md) @@ -24,4 +24,4 @@ In order to accurately describe organic molecular systems, we need to accurately ## Support and Contribution -Please visit our repository on [GitHub](https://github.com/deepmodeling/DMFF) for the library source code. Any issues or bugs may be reported at our issue tracker. All contributions to DMFF are welcomed via pull requests! \ No newline at end of file +Please visit our repository on [GitHub](https://github.com/deepmodeling/DMFF) for the library source code. Any issues or bugs may be reported at our issue tracker. All contributions to DMFF are welcomed via pull requests! diff --git a/docs/modules/admp.md b/docs/modules/admp.md new file mode 100644 index 000000000..02cab44d7 --- /dev/null +++ b/docs/modules/admp.md @@ -0,0 +1,5 @@ +# ADMP + +Automatic Differentiable Multipolar Polarizable (ADMP) force field calculator. + +[Introduction](../admp/readme.md) diff --git a/docs/user_guide/installation.md b/docs/user_guide/installation.md index 20ced0df3..4798144e7 100644 --- a/docs/user_guide/installation.md +++ b/docs/user_guide/installation.md @@ -1,6 +1,6 @@ # 2. Installation -## 2.1 Install dependencies -+ Install [jax](https://github.com/google/jax) (pick the correct cuda version, see more details on their installation guide): +## 2.1 Install Dependencies ++ Install [jax](https://github.com/google/jax) (select the correct cuda version, see more details in the Jax installation guide): ```bash pip install jax[cuda11_cudnn82] -f https://storage.googleapis.com/jax-releases/jax_releases.html ``` @@ -12,19 +12,19 @@ pip install jax-md ```bash conda install -c conda-forge openmm ``` -## 2.2 Install DMFF from source code -One can download the source code of DMFF by +## 2.2 Install DMFF from Source Code +One can download the DMFF source code from github: ```bash git clone https://github.com/deepmodeling/DMFF.git ``` -then you may install DMFF easily by: +Then you may install DMFF using `pip`: ```bash cd dmff pip install . --user ``` -## 2.3 Test installation -To test if the DMFF is correctly installed, you can run the following commands in a Python interpreter: +## 2.3 Test Installation +To test if DMFF is correctly installed, you can run the following commands in an interactive python session: ```python >>> import dmff >>> import dmff.admp @@ -38,4 +38,4 @@ python ./run_admp.py cd ./examples/water_pol_1024 python ./run_admp.py ``` -Note that the first run of the scripts will be a little bit slow if `DO_JIT = True` in `dmff/settings.py`. This is because the programm will try to do the jit compilation. \ No newline at end of file +Note that the scripts will run slower than expect if `DO_JIT = True` in `dmff/settings.py`. This is because the programm will do the jit compilation when a function is invoked in the first time. diff --git a/docs/user_guide/introduction.md b/docs/user_guide/introduction.md index f07e768e7..fc8033ec1 100644 --- a/docs/user_guide/introduction.md +++ b/docs/user_guide/introduction.md @@ -1,16 +1,17 @@ # 1. Introduction -In this user guide, you will learn: +In this user guide, you will learn how to: -- Installation of DMFF -- Computation of energy and force -- Auto differentiate alone computation path +- Install DMFF +- Compute energy and force +- Auto differentiate potential functions - Couple DMFF with MD engine -The first thing you should know is that DMFF is not an actual force field (such as OPLS or AMBER), but a collection of various force field (or called "potential") forms: +The first thing you should know is that DMFF is not an actual force field (such as OPLS or AMBER), but a differentiable implementation of various force field (or "potential") functional forms. It contains many modules: -- Automatic Differentiable Multipolar Polarizable (ADMP) -- Classical force field derived from GAFF -- SGNN +- ADMP module: Automatic Differentiable Multipolar Polarizable potential (MPID like potentials) +- Classical module: implements classical force fields (OPLS or GAFF like potentials) +- SGNN module: implements subgragh neural network model for intramolecular interactions + +Each module implements a particular form of force field, which takes a unique set of input parameters, usually provided in a XML file. With DMFF, one can easily compute the energy as well as energy gradients including: forces, virial tensors, and gradients with respect to force field parameters etc. -Those modules can easily be combined with a specific research topic to create a force field. Each module has its usage and required parameters, and provide them in a specified XML file and then use them under a Python program. With DMFF, one can calculate the energy and force of a molecular mechanics system and even get the parameters' gradient. \ No newline at end of file diff --git a/docs/user_guide/multipole_pme.md b/docs/user_guide/multipole_pme.md new file mode 100644 index 000000000..d207f2914 --- /dev/null +++ b/docs/user_guide/multipole_pme.md @@ -0,0 +1,605 @@ +# Notes on Multipolar Ewald + + + +## References: + +* [Anthony's book](https://oxford.universitypressscholarship.com/view/10.1093/acprof:oso/9780199672394.001.0001/acprof-9780199672394) +* The Multipolar Ewald paper in JCTC: ***J. Chem. Theory Comput.*** 2015, **11**, 2, 436–450 [Link](https://pubs.acs.org/doi/abs/10.1021/ct5007983) +* The `convert_mom_to_xml.py` code, which converts the CAMCASP moments (global harmonics) to OpenMM moments (local cartesian). +* The dispersion Ewald/PME: [Link](https://aip.scitation.org/doi/pdf/10.1063/1.470117) + + + +## Relevant mathematics + +### Cartesian Tensors + +Multipole operators in Cartesian Tensors: + +$$ +\displaylines{ +\begin{align} +&\hat{q} = 1 \\ +&\hat{\mu}_{\alpha} = r_{\alpha} \\ +&\hat{\Theta}_{\alpha\beta}=\frac{3}{2}\left(r_{\alpha}r_{\beta}-\frac{1}{3}r^2\delta_{\alpha\beta}\right) +\end{align} +} +$$ + +Interaction Hamiltonian (up to quadrupole): + +$$ +\displaylines{ +\hat{H}' = T q^{A} q^{B}+T_{\alpha}\left(q^{A} \hat{\mu}_{\alpha}^{B}-\hat{\mu}_{\alpha}^{A} q^{B}\right)+T_{\alpha \beta}\left(\frac{1}{3} q^{A} \hat{\Theta}_{\alpha \beta}^{B}-\hat{\mu}_{\alpha}^{A} \hat{\mu}_{\beta}^{B}+\frac{1}{3} \hat{\Theta}_{\alpha \beta}^{A} q^{B}\right) \\ +-\frac{1}{3} T_{\alpha \beta \gamma}\left(\hat{\mu}_{\alpha}^{A} \hat{\Theta}_{\beta \gamma}^{B}-\hat{\Theta}_{\alpha \beta}^{A} \hat{\mu}_{\gamma}^{B}\right) +\frac{1}{9}T_{\alpha \beta \gamma \delta}\hat{\Theta}_{\alpha \beta}^{A} \hat{\Theta}_{\gamma \delta}^{B} + \cdots +} +$$ + +And the corresponding interaction tensors are: + +$$ +T_{\alpha \beta \ldots v}^{(n)}=\frac{1}{4 \pi \epsilon_{0}} \nabla_{\alpha} \nabla_{\beta} \ldots \nabla_{v} \frac{1}{R} +$$ + +The first few terms are listed in the page 4 of Anthony's book (up to quad-quad interactions). + +### Spherical Tensors + +The often seen spherical harmonics include: + +* The original spherical harmonics (**adopting the convention without $(-1)^m$**): + +$$ +Y_{lm}(\theta, \phi) = \sqrt{\frac{2 l+1}{4 \pi} \frac{(l-m) !}{(l+m) !}} P_{l}^{m}(\cos \theta) e^{i m \phi} +$$ + + with $P_l^m$ being the associated Legendre Polynomials: +$$ +P_{\ell}^{m}(x)=\frac{(-1)^{m}}{2^{\ell} \ell !}\left(1-x^{2}\right)^{m / 2} \frac{d^{\ell+m}}{d x^{\ell+m}}\left(x^{2}-1\right)^{\ell} +$$ + Note we have: +$$ +P_{\ell}^{-m}(x)=(-1)^{m} \frac{(\ell-m) !}{(\ell+m) !} P_{\ell}^{m}(x) +$$ + The exact form of these polynomials can be found in: + + [Associated_Legendre_polynomials](https://en.wikipedia.org/wiki/Associated_Legendre_polynomials) + + The lowest few orders of them are: + +$$ +\displaylines{ +\begin{aligned} +&P_{0}^{0}(x)=1 \\ +&P_{1}^{0}(x)=x \\ +&P_{1}^{1}(x)=-\left(1-x^{2}\right)^{1 / 2} \\ +&P_{2}^{0}(x)=\frac{1}{2}\left(3 x^{2}-1\right) \\ +&P_{2}^{1}(x)=-3 x\left(1-x^{2}\right)^{1 / 2} \\ +&P_{2}^{2}(x)=3\left(1-x^{2}\right) +\end{aligned} +} +$$ + +* We also use the renormalized spherical harmonics: + +$$ +\displaylines{ +C_{l m}(\theta, \varphi)=\sqrt{\frac{4 \pi}{2 l+1}} Y_{l m}(\theta, \varphi) \\ + = \sqrt{\frac{(l-m) !}{(l+m) !}} P_{l}^{m}(\cos \theta) e^{i m \phi} \\ + =\epsilon_m\sqrt{\frac{(l-|m|)!}{(l+|m|)!}} P_l^{|m|}(\cos\theta)e^{im\phi} +} +$$ + +**Note that I believe the equation B.1.3 in Pg. 272 of Anthony's book is not quite right** (missing an absolute value in $P_l^m$). Definition of $\epsilon_m$ can be found in Pg. 272. + +* Now we can define the regular and irregular spherical harmonics: + +$$ +\displaylines{ +\begin{aligned} +R_{l m}(\vec{r}) &=r^{l} C_{l m}(\theta, \varphi) \\ +I_{l m}(\vec{r}) &=r^{-l-1} C_{l m}(\theta, \varphi) +\end{aligned} +} +$$ + +In particular: + +$$ +R_{lm}(\vec{r}) = r^l \cdot \sqrt{\frac{(l-m) !}{(l+m) !}} P_{l}^{m}(\cos \theta) e^{i m \phi} +$$ + +From this we can define the real-valued regular spherical harmonics (for $m>0$): + +$$ +\displaylines{ +\begin{aligned} +R_{l m c} &=\sqrt{\frac{1}{2}}\left[(-1)^{m} R_{l m}+R_{l,-m}\right] \\ +\mathrm{i} R_{l m s} &=\sqrt{\frac{1}{2}}\left[(-1)^{m} R_{l m}-R_{l,-m}\right] +\end{aligned} +} +$$ + +According to my derivation, that is: + +$$ +\displaylines{ +\begin{cases} +R_{l0} = r^l\cdot C_{l0} = r^l\cdot P_l^{0}(\cos\theta)\\ +R_{lmc} = (-1)^m \cdot \sqrt{2} \cdot r^l \sqrt{\frac{(l-m)!}{(l+m)!}}P_l^m(\cos\theta)\cos(m\phi) \\ +R_{lms} = (-1)^m \cdot \sqrt{2} \cdot r^l \sqrt{\frac{(l-m)!}{(l+m)!}}P_l^m(\cos\theta)\sin(m\phi) +\end{cases} +} +$$ + +In Anthony's book, they usually use Greek letters ($\mu,\nu,\kappa$ etc.​) or letter $t,u$ to represent $1c, 1s, 2c, 2s$​ etc. These are the projector functions to compute all the moments. + +In the real-valued regular spherical harmonics representation, the interaction energy is: + +$$ +\hat{H}' = \sum_{at,bu} {\hat{Q}_t^a T_{tu}^{ab}\hat{Q}_u^b} +$$ + +The interaction tensor $T_{tu}^{AB}$ can be found in Appendix F of Anthony's book (pg. 291). + +* A couple of things regarding paper: ***J. Chem. Theory Comput.*** 2015, **11**, 2, 436–450 (https://pubs.acs.org/doi/abs/10.1021/ct5007983) + +In this paper, the definition (***in their notation***) of: + +$$ +\displaylines{ +C_{l\mu} = (-1)^{\mu}\sqrt{\left(2-\delta_{\mu, 0}\right)(l+\mu) !(l-\mu) !}\cdot R_{l\mu} \\ += +\begin{cases} +(-1)^{m}\sqrt{\left(2-\delta_{m, 0}\right)(l+m) !(l-m) !} \cdot R_{l mc}(\vec{r}) & \mu \geq 0 \\ +(-1)^{-m}\sqrt{2(l-m) !(l+m) !} \cdot R_{lms}(\vec{r}) & \mu<0 +\end{cases} \\ +(\text{Here, we assumes $m=|\mu|$}) \\ += +\begin{cases} +r^l\cdot P_l^0(\cos\theta) & \mu=0 \\ +(-1)^m\cdot\sqrt{2}\cdot r^l\sqrt{\frac{(l-m)!}{(l+m)!}}P_l^m(\cos\theta)\cos(m\phi) & \mu\gt 0 \\ +(-1)^m\cdot\sqrt{2}\cdot r^l\sqrt{\frac{(l-m)!}{(l+m)!}}P_l^m(\cos\theta)\sin(m\phi) & \mu\lt 0 +\end{cases} +} +$$ + +This is identical to Eqn. 14. **Therefore, the $C_{l\mu}$ in the JCTC paper is identical to the $R_\mu$ in Anthony's book**. + +And the interaction function also checks out! So we have a compact form for the interaction tensor in table F.1 of the book + +$$ +T_{tu}^{ab} = \frac{R_t(\nabla_a)}{(2l_t-1)!!}\frac{R_u(\nabla_b)}{(2l_u-1)!!}\frac{1}{R_{ab}} +$$ + +This is verified manually by computing the $T_{21c,11c}=T_{xz, x} = \sqrt{3}\frac{1}{R^4}\left(\hat{z}-5\hat{x}^2\hat{z}\right)$​ tensor. + + + +## Rotations + +Assume the local frame matrix for a particular atom is: + +$$ +\displaylines{ +\mathbf{R} = +\left[ +\matrix{ +\mathbf{r_1^T} \\ +\mathbf{r_2^T} \\ +\mathbf{r_3^T} \\ +}\right] = \left[ +\matrix{ +x_1 & y_1 & z_1 \\ +x_2 & y_2 & z_2 \\ +x_3 & y_3 & z_3 +}\right] +} +$$ + +Then for any vector, the local ($\vec{r}'$)-to-global (\vec{r}) transform is: + +$$ +\vec{r}=\mathbf{R}^T\cdot\vec{r}' +$$ + +Following the convention in the `convert_mom_to_xml.py` code, assuming the order for spherical harmonics is: $Q_{00}, Q_{10}, Q_{11c}, Q_{11s}, Q_{20}, Q_{21c}, Q_{21s}, Q_{22c}, Q_{22s}$​​ + +* **Dipole rotation** + +For dipole, the harmonics-to-cartesian conversion is: + +$$ +\mathbf{C}_1=\left[ +\matrix{ +0 & 1 & 0 \\ +0 & 0 & 1 \\ +1 & 0 & 0 +} +\right] +$$ + +So the **local-harmonics-to-global-harmonics** conversion for dipole moments is: + +$$ +\mathbf{R}_{1}^{l-g}=\mathbf{C}_1^T\mathbf{R}^T\mathbf{C}_1 +$$ + +* **Quadrupole rotation** + +First of all, the cartesian moments are: + +$$ +\displaylines{ +\mathbf{\Theta}= +\int {d\vec{r}\cdot\rho(\vec{r})\cdot\left(\frac{3}{2}\left[\matrix{ +xx & xy & xz \\ +yx & yy & yz \\ +zx & zy & zz \\ +}\right] - \frac{1}{2}r^2\mathbf{I} \right)} \\ += \int {d\vec{r}\cdot\rho(\vec{r})\cdot\left(\frac{3}{2}\vec{r}\vec{r}^T -\frac{1}{2}(\vec{r}^T\cdot\vec{r})\mathbf{I}\right)} +} +$$ + +Then obviously, the **local-to-global** conversion is: + +$$ +\mathbf{\Theta} = \mathbf{R}^T\mathbf{\Theta}'\mathbf{R} +$$ + +The conversion between $\vec{\Theta}=[xx,yy,zz,xy,xz,yz]$​​​​ and harmonic moments ($\vec{Q}=[Q_{20}, Q_{21c}, Q_{21s}, Q_{22c}, Q_{22s}]$​​​​​) is: + +$$ +\displaylines{ +\mathbf{C}_2^{h-c} = \left[\matrix{ +-\frac{1}{2} & 0 & 0 & \frac{\sqrt{3}}{2} & 0 \\ +-\frac{1}{2} & 0 & 0 & -\frac{\sqrt{3}}{2} & 0 \\ +1 & 0 & 0 & 0 & 0 \\ +0 & 0 & 0 & 0 & \frac{\sqrt{3}}{2} \\ +0 & \frac{\sqrt{3}}{2} & 0 & 0 & 0 \\ +0 & 0 & \frac{\sqrt{3}}{2} & 0 & 0 +}\right] +} +$$ + +$$ +\vec{\Theta} = \mathbf{C}_2^{h-c} \vec{Q} +$$ + +And the inversed conversion is: + +$$ +\displaylines{ +\mathbf{C}_2^{c-h} = \left[\matrix{ +0 & 0 & 1 & 0 & 0 & 0 \\ +0 & 0 & 0 & 0 & \frac{2}{\sqrt{3}} & 0 \\ +0 & 0 & 0 & 0 & 0 & \frac{2}{\sqrt{3}} \\ +\frac{1}{\sqrt{3}} & -\frac{1}{\sqrt{3}} & 0 & 0 & 0 & 0 \\ +0 & 0 & 0 & \frac{2}{\sqrt{3}} & 0 & 0 \\ +}\right] +} +$$ + +$$ +\vec{Q} = \mathbf{C}_2^{c-h}\vec{\Theta} +$$ + +So the rotation procedure from **local-to-global** rotation for (spherical harmonics) quadrupole moments is: + +$$ +\displaylines{ +\vec{\Theta}' = \mathbf{C}_2^{h-c} \vec{Q}' \\ +\mathbf{\Theta} = \mathbf{R}^T\mathbf{\Theta}'\mathbf{R} \\ +\vec{Q} = \mathbf{C}_2^{c-h}\vec{\Theta} +} +$$ + +And vice-versa for the invert process. + +Using `sympy`, we can derive the actual linear transformation matrix, which is coded in `test_rot_quad.py`. The derivation is done using `derive_rot_mat.py` + + + + + +## Multipolar Ewald + +* **The reciprocal space part:** + + The structure factor is: + + $$ + S(\vec{k}) = \sum_{a,t} Q_t^a\frac{R_t(\vec{k})(-i)^{l_t}}{(2l-1)!!}e^{-i\vec{k}\cdot\vec{R}_a} + $$ + + The reciprocal space energy is: + + $$ + E_{recip} = \sum_{k\neq 0} {\frac{2\pi}{V k^2}\exp\left(-\frac{k^2}{4\kappa^2}\right)\left|S(\vec{k})\right|^2} + $$ + +* The real space part: + +$$ +\displaylines{ +E_{real} = \sum_{\substack{a @@ -29,7 +39,7 @@ Examples of XML files are as follows: ``` -Where "- C" indicates the connection with the "C" atom in the **previous** residue. During typification, all atoms in the residue with the same name will try to match. Once the typification is successful, it will be bonded, and if the matching fails, it will be skipped. Therefore, the actual number of bonds can be less than the number set in the template. +Where "-C" indicates an external bond between the "C" atom and the **previous** residue. During typification, the code will try to match all atoms in the topology template with the actual atoms in the real structure. Once a match is successful, the matched atom will be bonded accordingly. If the match fails, this template atom will be skipped. Therefore, the actual number of bonds in the matched structure can be less than the number of bonds defined in the template. The XML file registration method is as follows: @@ -47,9 +57,11 @@ top = app.Topology() top.createStandardBonds() # Connect keys according to template files ``` -It should be noted that disulfide bond is not completed in this step. The OpenMM topology class will look for SG atoms in Cys that are not connected to Hg, and connect atom pairs less than 0.3nm as disulfide bonds. +After this process, the bonding topologies are constructed in the matched residue, but the force field parameters are not yet assigned. It should be noted that disulfide bonds are not registered in this step. The OpenMM topology class will look for SG atoms in Cys that are not connected to Hg, and connect SG atom pairs within 0.3nm as disulfide bonds. -## Force field parameter file +## Force field Parameter File + +After all bonds are constructed using the topology file, the force field parameters will be assigned using the force field parameter file. The force field parameter file is as follows: ``` xml @@ -81,9 +93,9 @@ The force field parameter file is as follows: ``` -This document can be divided into residue part and force field part. +This file can be further divided into the residue part and the force field part. -### residue part +### Residue Part ``` xml @@ -99,7 +111,7 @@ This document can be divided into residue part and force field part. ... ``` -The `` node of the residue part defines the atomtype of each atom in the residue and some parameter information of per atom, which can be called by the force field part on demand. The `` node defines the bonding information of residues. The information contained in this part is different from that in the topology file above. Take ALA as an example. For ALA, we usually need to define at least three state, N-end, C-end and in-chain. The template in the force field is as follows: +The `` node of the residue part defines all the atoms involved in the residue and some paramemters per atom, which can be called by the force field part on demand. The `` node defines the bonding information of the residue. The information contained in this part is different from that in the topology file discussed above. Take ALA as an example, we usually have at least three states for ALA, N-end, C-end and in-chain. The corresponding parameter templates in the force field file are as follows: ``` xml @@ -139,7 +151,7 @@ The `` node of the residue part defines the atomtype of each atom in the r - + <\displaylines{Bond atomName1="CA" atomName2="HA"/> @@ -177,9 +189,11 @@ The `` node of the residue part defines the atomtype of each atom in the r ``` -In this example, the atom number and bonding relationship of ALA, CALA and NALA are different. When matching each ALA, OpenMM will try to match CALA, NALA and ALA, and finally select the template with the same number of atoms, element composition and bonding relationship as the residue to define the force field parameters for each atom. +In this example, the atom numbers and the bonding configurations of ALA, CALA and NALA are different. When matching each ALA, OpenMM will try to match CALA, NALA, and ALA separately. It will compare each parameter template with the topology of the residue, and select the one with the right number of atoms, element composition, and bonding configurations as the matched template. The parameter template contains atom type and class information, which are then used to assign force field parameters. + -### forcefield part +### Forcefield Part +```xml ... @@ -199,9 +213,10 @@ In this example, the atom number and bonding relationship of ALA, CALA and NALA +``` -The `` node defines many atomic types. The `type` label of each atom in the residue part will match the `name` label of each child node of ``. For each atom type, it also defines a `class` tag for different matching scenarios. The `name` of different `` child nodes must be different, but the `class` can be the same. +The `` node defines all atom types. The `type` label of each atom in the residue part will match the `name` label of each child node of ``. For each atom type, it also defines a `class` tag for different matching scenarios. The `name` tag of different `` must be different, but the `class` tag can be the same. -The `<*force>` node defines the matching rule of a potential function. For example, `` defines harmonic bond, and the `` node defines intermolecular interaction. You can view the document for specific parameter [details](http://docs.openmm.org/latest/userguide/application/05_creating_ffs.html#writing-the-xml-file) +The `<*Force>` node defines the matching rule of a potential function. For example, `` defines harmonic bond, and the `` node defines intermolecular interaction. For more information about each force, the readers are referred to this document: [details](http://docs.openmm.org/latest/userguide/application/05_creating_ffs.html#writing-the-xml-file). -In the matching process, OpenMM will iterate all atom, bond, angle, dihedral and improver, and add all matching entries to the total potential function. Matching can be carried out according to the `type` tag, corresponding to the `name` of each atom in ``; It can also be based on the `class` tag, corresponding to the `class` of each atom in ``. This design is applicable to the situation that there are many types of atoms but they are roughly the same. For example, there are few kinds of LJ parameters in small molecular force field, but there are many kinds of intramolecular force parameters. We can even create a separate type for a specific small molecule to define the intra molecular interaction, but it belongs to the same class on LJ, so as to achieve the effect that the small molecule parameters can be tuned and do not affect each other. \ No newline at end of file +In the matching process, OpenMM will iterate all atoms, bonds, angles, dihedrals and impropers, and add all matched entries to the total potential function. Matching can be carried out according to the `type` tag, corresponding to the `name` of each atom defined in ``; It can also be based on the `class` tag, corresponding to the `class` of each atom in ``. This design is applicable to the situation when there are many types of atoms but they are roughly the same. For example, there are few kinds of LJ parameters in small molecular force field, but there are many kinds of intramolecular force parameters. We can even create a separate type for a specific small molecule to define the intra molecular interaction, but it belongs to the same class on LJ, so as to achieve the effect that the small molecule parameters can be tuned and do not affect each other. diff --git a/mkdocs.yml b/mkdocs.yml index 6472d1086..6833919a7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,7 +6,9 @@ nav: - 2. Installation: user_guide/installation.md - 3. Compute energy and force: user_guide/compute.md - 4. Auto-diff: user_guide/auto_diff.md - - 5. couple with MD: user_guide/couple.md + - 5. Theory: user_guide/theory.md + - 6. couple with MD: user_guide/couple.md + - 7. Introduction to force field xml file: user_guide/xml_spec.md - Developer Guide: - 1. Introduction: dev_guide/introduction.md @@ -15,7 +17,7 @@ nav: - Modules: - ADMP: - Introduction: admp/readme.md - - Theory: admp/theory.md + - Frontends: admp/frontend.md - About: about.md theme: readthedocs From c62b90c99e8ab23fc4b586dd93ee4111f2161eba Mon Sep 17 00:00:00 2001 From: KuangYu Date: Thu, 5 May 2022 10:16:39 +0800 Subject: [PATCH 8/8] Modify README.md and index.md --- README.md | 8 +++++--- docs/index.md | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 87e559477..5406747fb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# DMFF's Manual +# DMFF -**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a python-based package that provides a full differentiable implementation of molecular force field calculations. This project aims to establish an extensible framework to minimize the efforts in force field parameter fitting, and to support an easy evaluation of forces and virial tensors for complicated advanced potentials (such as polarizable models with geometry-dependent atomic parameters). Currently, this project mainly focuses on the force fields of the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers, and small organic molecules (organic electrolyte, drug-like molecules) etc. And we support both the conventional point charge models (OPLS and AMBER like) and multpolar polarizable models (AMOEBA and MPID like). +**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a Jax-based python package that provides a full differentiable implementation of molecular force field models. This project aims to establish an extensible codebase to minimize the efforts in force field parameterization, and to ease the force and virial tensor evaluations for advanced complicated potentials (e.g., polarizable models with geometry-dependent atomic parameters). Currently, this project mainly focuses on the molecular systems such as: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers, and small organic molecules (organic electrolyte, drug-like molecules) etc. We support both the conventional point charge models (OPLS and AMBER like) and multipolar polarizable models (AMOEBA and MPID like). The entire project is backed by the XLA technique in JAX, thus can be "jitted" and run in GPU devices much more efficiently compared to normal python codes. -The behavior of organic molecular systems (e.g., protein folding, polymer structure, etc.) is often determined by a complex effect of many different types of interactions. The existing organic molecular force fields are mainly empirically fitted and their performance relies heavily on error cancellation. Therefore, the transferrabilities and the prediction powers of these force fields are insufficient. For new molecules, the parameter fitting process requires heavy load of manual intervention and can be quite cubersome. In order to automize the parametrization process and increase the robustness of the model, it is necessary to combine modern AI techniques with conventional force field development. This project serves for this purpose by utilizing the automatic differential programming framework to develop a toolchain, leading to many advanced functions such as: hybrid force field / machine learning models and parameter optimization based on molecular mechanics trajectory. +The behavior of organic molecular systems (e.g., protein folding, polymer structure, etc.) is often determined by a complex effect of many different types of interactions. The existing organic molecular force fields are mainly empirically fitted and their performance relies heavily on error cancellation. Therefore, the transferability and the prediction power of these force fields are insufficient. For new molecules, the parameter fitting process requires essential manual intervention and can be quite cumbersome. In order to automate the parametrization process and increase the robustness of the model, it is necessary to apply modern AI techniques in conventional force field development. This project serves for this purpose by utilizing the automatic differentiable programming technique to develop a codebase, which allows a more convenient incorporation of modern AI optimization techniques. It also helps the realization of many exciting functions including (but not limited to): hybrid machine learning/force field models and parameter optimization based on trajectory. ## User Guide @@ -10,6 +10,8 @@ The behavior of organic molecular systems (e.g., protein folding, polymer struct + [2. Installation](user_guide/installation.md) + [3. Compute energy and forces](user_guide/compute.md) + [4. Compute gradients with auto differentiable framework](user_guide/auto_diff.md) ++ [5. Theories](user_guide/theory.md) ++ [6. Introduction to force field xml files](user_guide/xml_spec.md) ## Developer Guide + [1. Introduction](dev_guide/introduction.md) diff --git a/docs/index.md b/docs/index.md index 2af0071a9..5406747fb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,8 @@ -# DMFF's Manual +# DMFF -**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a Jax-based python package that provides a full differentiable implementation of molecular force field calculations. This project aims to establish an extensible framework to minimize the efforts in force field parameter fitting, and to support an easy evaluation of forces and virial tensors for complicated advanced potentials (such as polarizable models with geometry-dependent atomic parameters). Currently, this project mainly focuses on the force fields of the following systems: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers, and small organic molecules (organic electrolyte, drug-like molecules) etc. And we support both the conventional point charge models (OPLS and AMBER like) and multipolar polarizable models (AMOEBA and MPID like). +**DMFF** (**D**ifferentiable **M**olecular **F**orce **F**ield) is a Jax-based python package that provides a full differentiable implementation of molecular force field models. This project aims to establish an extensible codebase to minimize the efforts in force field parameterization, and to ease the force and virial tensor evaluations for advanced complicated potentials (e.g., polarizable models with geometry-dependent atomic parameters). Currently, this project mainly focuses on the molecular systems such as: water, biological macromolecules (peptides, proteins, nucleic acids), organic polymers, and small organic molecules (organic electrolyte, drug-like molecules) etc. We support both the conventional point charge models (OPLS and AMBER like) and multipolar polarizable models (AMOEBA and MPID like). The entire project is backed by the XLA technique in JAX, thus can be "jitted" and run in GPU devices much more efficiently compared to normal python codes. -The behavior of organic molecular systems (e.g., protein folding, polymer structure, etc.) is often determined by a complex effect of many different types of interactions. The existing organic molecular force fields are mainly empirically fitted and their performance relies heavily on error cancellation. Therefore, the transferrabilities and the prediction powers of these force fields are insufficient. For new molecules, the parameter fitting process requires heavy load of manual intervention and can be quite cubersome. In order to automize the parametrization process and increase the robustness of the model, it is necessary to apply modern AI techniques in conventional force field development. This project serves for this purpose by utilizing the automatic differential programming technique to develop a toolchain, which may lead to many advanced functions such as: hybrid force field / machine learning models and parameter optimization based on molecular mechanics trajectory. +The behavior of organic molecular systems (e.g., protein folding, polymer structure, etc.) is often determined by a complex effect of many different types of interactions. The existing organic molecular force fields are mainly empirically fitted and their performance relies heavily on error cancellation. Therefore, the transferability and the prediction power of these force fields are insufficient. For new molecules, the parameter fitting process requires essential manual intervention and can be quite cumbersome. In order to automate the parametrization process and increase the robustness of the model, it is necessary to apply modern AI techniques in conventional force field development. This project serves for this purpose by utilizing the automatic differentiable programming technique to develop a codebase, which allows a more convenient incorporation of modern AI optimization techniques. It also helps the realization of many exciting functions including (but not limited to): hybrid machine learning/force field models and parameter optimization based on trajectory. ## User Guide