Skip to content

Commit 35fe2dc

Browse files
committed
Add assymetry to CT
1 parent 7a802b4 commit 35fe2dc

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

src/fes_ml/alchemical/modifications/charge_transfer.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,23 @@ class ChargeTransferModification(BaseModification):
3636
post_dependencies: List[str] = []
3737

3838
@staticmethod
39-
def get_is_donor_acceptor(topology: _Topology) -> tuple[list[int], list[int]]:
39+
def get_is_donor_acceptor(
40+
topology: _Topology, alchemical_atoms: List[int], symmetric: bool = False
41+
) -> tuple[list[int], list[int]]:
4042
"""
4143
Generate per-atom flags for donors and acceptors.
4244
4345
Parameters
4446
----------
4547
topology : openff.toolkit.topology.Topology
4648
49+
alchemical_atoms : list of int
50+
List of indices of alchemical atoms.
51+
52+
symmetric : bool, optional
53+
If True, CT will be applied symmetrically between alchemical and MM atoms.
54+
Otherwise, only from MM to alchemical atoms. Default is False.
55+
4756
Returns
4857
-------
4958
is_donor : list[int]
@@ -57,13 +66,13 @@ def get_is_donor_acceptor(topology: _Topology) -> tuple[list[int], list[int]]:
5766

5867
for idx, atom in enumerate(topology.atoms):
5968
# Donor: hydrogen bonded to N/O/S
60-
if atom.atomic_number == 1:
69+
if atom.atomic_number == 1 and (symmetric or idx in alchemical_atoms):
6170
for bonded_atom in atom.bonded_atoms:
6271
if bonded_atom.atomic_number in [7, 8, 16]:
6372
is_donor[idx] = 1
6473
break
6574
# Acceptor: heavy atoms
66-
elif atom.atomic_number == 8:
75+
elif atom.atomic_number == 8 and (symmetric or idx not in alchemical_atoms):
6776
num_H = sum(b.atomic_number == 1 for b in atom.bonded_atoms)
6877
is_acceptor[idx] = 1
6978
elif atom.atomic_number == 7:
@@ -138,7 +147,9 @@ def apply(
138147
energy_function = f"-{lambda_value}*donor_acceptor*epsilon*exp(-sigma*r);"
139148
energy_function += "sigma = 0.5*(sigma1+sigma2);"
140149
energy_function += "epsilon = sqrt(epsilon1*epsilon2);"
141-
energy_function += "donor_acceptor = isDonor1*isAcceptor2;"
150+
energy_function += (
151+
"donor_acceptor = isDonor1*isAcceptor2 + isDonor2*isAcceptor1;"
152+
)
142153

143154
logger.debug(f"Charge transfer function: {energy_function}")
144155

@@ -165,7 +176,7 @@ def apply(
165176

166177
# Get donor/acceptor flags
167178
is_donor, is_acceptor = ChargeTransferModification.get_is_donor_acceptor(
168-
topology_off
179+
topology_off, alchemical_atoms
169180
)
170181

171182
for index in range(system.getNumParticles()):

0 commit comments

Comments
 (0)