Skip to content

Commit 83f64b6

Browse files
committed
Fix redistribution of excess QM charge. [closes #294]
1 parent cb1111f commit 83f64b6

File tree

4 files changed

+27
-10
lines changed

4 files changed

+27
-10
lines changed

doc/source/changelog.rst

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ organisation on `GitHub <https://github.com/openbiosim/sire>`__.
2020
* Allow user to force fresh inference of stereochemistry when converting to RDKit format.
2121
* Fix setting of positive formal charge when reading SDF files.
2222
* Only use ``atom->setNoImplicit(True)`` inside custom RDKit sterochemistry inference function.
23+
* Fix redistribution of excess QM charge and make it the default behaviour.
2324

2425
`2024.4.0 <https://github.com/openbiosim/sire/compare/2024.3.1...2024.4.0>`__ - Feb 2025
2526
----------------------------------------------------------------------------------------

src/sire/qm/__init__.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def create_engine(
1818
cutoff="7.5A",
1919
neighbour_list_frequency=0,
2020
mechanical_embedding=False,
21-
redistribute_charge=False,
21+
redistribute_charge=True,
2222
map=None,
2323
):
2424
"""
@@ -68,8 +68,11 @@ def create_engine(
6868
6969
redistribute_charge : bool
7070
Whether to redistribute charge of the QM atoms to ensure that the total
71-
charge of the QM region is an integer. Excess charge is redistributed
72-
over the non QM atoms within the residues involved in the QM region.
71+
charge of the QM region is an integer. If the QM region is a an entire
72+
molecule, then the charge on each atom is shifted so that the total
73+
charge is an integer. Alternatively, when the QM region is part of a
74+
molecule, the excess charge is redistributed over the MM atoms within
75+
the residues of the QM region.
7376
7477
Returns
7578
-------

src/sire/qm/_emle.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def emle(
107107
calculator,
108108
cutoff="7.5A",
109109
neighbour_list_frequency=0,
110-
redistribute_charge=False,
110+
redistribute_charge=True,
111111
map=None,
112112
):
113113
"""
@@ -137,8 +137,11 @@ def emle(
137137
138138
redistribute_charge : bool
139139
Whether to redistribute charge of the QM atoms to ensure that the total
140-
charge of the QM region is an integer. Excess charge is redistributed
141-
over the non QM atoms within the residues involved in the QM region.
140+
charge of the QM region is an integer. If the QM region is a an entire
141+
molecule, then the charge on each atom is shifted so that the total
142+
charge is an integer. Alternatively, when the QM region is part of a
143+
molecule, the excess charge is redistributed over the MM atoms within
144+
the residues of the QM region.
142145
143146
Returns
144147
-------

src/sire/qm/_utils.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ def _check_charge(mols, qm_atoms, map, redistribute_charge=False, tol=1e-6):
102102
"""
103103

104104
import math as _math
105+
import sys as _sys
105106

106107
from sire.units import e_charge as _e_charge
107108

@@ -127,8 +128,16 @@ def _check_charge(mols, qm_atoms, map, redistribute_charge=False, tol=1e-6):
127128
# Redistribute the charge over the QM atoms.
128129
qm_frac = excess_charge / len(qm_atoms)
129130

130-
# Redistribute the charge over the non QM atoms.
131-
rem_frac = excess_charge / (residues.num_atoms() - len(qm_atoms))
131+
# Work out the number of non-QM atoms.
132+
num_mm = residues.num_atoms() - len(qm_atoms)
133+
134+
# Redistribute the charge over the MM atoms.
135+
if num_mm > 0:
136+
rem_frac = excess_charge / num_mm
137+
138+
print(
139+
f"Redistributing excess QM charge of {excess_charge}", file=_sys.stderr
140+
)
132141

133142
# Loop over the residues.
134143
for res in residues:
@@ -140,10 +149,11 @@ def _check_charge(mols, qm_atoms, map, redistribute_charge=False, tol=1e-6):
140149

141150
# Loop over the atoms in the residue.
142151
for atom in res:
143-
# Shift the charge.
152+
# Shift the charge of the QM atoms.
144153
if atom in qm_atoms:
145154
cursor[atom][charge_prop] -= qm_frac
146-
else:
155+
# Shift the charge of the MM atoms.
156+
elif num_mm > 0:
147157
cursor[atom][charge_prop] += rem_frac
148158

149159
# Commit the changes.

0 commit comments

Comments
 (0)