# 3.12. Deep Potential - Range Correction (DPRc)

Deep Potential - Range Correction (DPRc) is designed to combine with QM/MM method, and corrects energies from a low-level QM/MM method to a high-level QM/MM method:

$E=E_\text{QM}(\mathbf R; \mathbf P) + E_\text{QM/MM}(\mathbf R; \mathbf P) + E_\text{MM}(\mathbf R) + E_\text{DPRc}(\mathbf R)$

See the JCTC paper for details.

## 3.12.1. Training data

Instead the normal ab initio data, one needs to provide the correction from a low-level QM/MM method to a high-level QM/MM method:

$E = E_\text{high-level QM/MM} - E_\text{low-level QM/MM}$

Two levels of data use the same MM method, so $$E_\text{MM}$$ is eliminated.

## 3.12.2. Training the DPRc model

In a DPRc model, QM atoms and MM atoms have different atom types. Assuming we have 4 QM atom types (C, H, O, P) and 2 MM atom types (HW, OW):

"type_map": ["C", "H", "HW", "O", "OW", "P"]


As described in the paper, the DPRc model only corrects $$E_\text{QM}$$ and $$E_\text{QM/MM}$$ within the cutoff, so we use a hybrid descriptor to describe them separatedly:

"descriptor" :{
"type":             "hybrid",
"list" : [
{
"type":     "se_e2_a",
"sel":              [6, 11, 0, 6, 0, 1],
"rcut_smth":        1.00,
"rcut":             9.00,
"neuron":           [12, 25, 50],
"exclude_types":    [[2, 2], [2, 4], [4, 4], [0, 2], [0, 4], [1, 2], [1, 4], [3, 2], [3, 4], [5, 2], [5, 4]],
"axis_neuron":      12,
"set_davg_zero":    true,
"_comment": " QM/QM interaction"
},
{
"type":     "se_e2_a",
"sel":              [6, 11, 100, 6, 50, 1],
"rcut_smth":        0.50,
"rcut":             6.00,
"neuron":           [12, 25, 50],
"exclude_types":    [[0, 0], [0, 1], [0, 3], [0, 5], [1, 1], [1, 3], [1, 5], [3, 3], [3, 5], [5, 5], [2, 2], [2, 4], [4, 4]],
"axis_neuron":      12,
"set_davg_zero":    true,
"_comment": " QM/MM interaction"
}
]
}


exclude_types can be generated by the following Python script:

from itertools import combinations_with_replacement, product
qm = (0, 1, 3, 5)
mm = (2, 4)
print("QM/QM:", list(map(list, list(combinations_with_replacement(mm, 2)) + list(product(qm, mm)))))
print("QM/MM:", list(map(list, list(combinations_with_replacement(qm, 2)) + list(combinations_with_replacement(mm, 2)))))


Also, DPRc assumes MM atom energies (atom_ener) are zero:

"fitting_net": {
"neuron": [240, 240, 240],
"resnet_dt": true,
"atom_ener": [null, null, 0.0, null, 0.0, null]
}


Note that atom_ener only works when descriptor/set_davg_zero is true.

## 3.12.3. Run MD simulations

The DPRc model has the best practices with the AMBER QM/MM module. An example is given by GitLab RutgersLBSR/AmberDPRc. In theory, DPRc is able to be used with any QM/MM package, as long as the DeePMD-kit package accepts QM atoms and MM atoms within the cutoff range and returns energies and forces.