Skip to content

Commit 3f281a7

Browse files
committed
Add option to limit size of ring flip region.
1 parent 795f377 commit 3f281a7

3 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/somd2/config/_config.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def __init__(
141141
perturbed_system=None,
142142
terminal_flip_frequency=None,
143143
terminal_flip_angle=None,
144+
terminal_flip_max_mobile_atoms=None,
144145
gcmc=False,
145146
gcmc_frequency=None,
146147
gcmc_selection=None,
@@ -391,6 +392,11 @@ def __init__(
391392
``"180 degrees"``. If None (the default), the angle is determined
392393
automatically for each group from its geometry.
393394
395+
terminal_flip_max_mobile_atoms: int or None
396+
Maximum number of mobile atoms allowed in a terminal ring group.
397+
Groups with more mobile atoms than this threshold are skipped during
398+
detection. Defaults to None (no limit).
399+
394400
gcmc: bool
395401
Whether to perform Grand Canonical Monte Carlo (GCMC) water insertions/deletions.
396402
@@ -575,6 +581,7 @@ def __init__(
575581
self.perturbed_system = perturbed_system
576582
self.terminal_flip_frequency = terminal_flip_frequency
577583
self.terminal_flip_angle = terminal_flip_angle
584+
self.terminal_flip_max_mobile_atoms = terminal_flip_max_mobile_atoms
578585
self.gcmc = gcmc
579586
self.gcmc_frequency = gcmc_frequency
580587
self.gcmc_selection = gcmc_selection
@@ -2064,6 +2071,26 @@ def terminal_flip_angle(self, terminal_flip_angle):
20642071
else:
20652072
self._terminal_flip_angle = None
20662073

2074+
@property
2075+
def terminal_flip_max_mobile_atoms(self):
2076+
return self._terminal_flip_max_mobile_atoms
2077+
2078+
@terminal_flip_max_mobile_atoms.setter
2079+
def terminal_flip_max_mobile_atoms(self, terminal_flip_max_mobile_atoms):
2080+
if terminal_flip_max_mobile_atoms is not None:
2081+
if not isinstance(terminal_flip_max_mobile_atoms, int):
2082+
try:
2083+
terminal_flip_max_mobile_atoms = int(terminal_flip_max_mobile_atoms)
2084+
except:
2085+
raise ValueError(
2086+
"'terminal_flip_max_mobile_atoms' must be of type 'int'"
2087+
)
2088+
if terminal_flip_max_mobile_atoms < 1:
2089+
raise ValueError(
2090+
"'terminal_flip_max_mobile_atoms' must be greater than 0"
2091+
)
2092+
self._terminal_flip_max_mobile_atoms = terminal_flip_max_mobile_atoms
2093+
20672094
@property
20682095
def gcmc(self):
20692096
return self._gcmc

src/somd2/runner/_base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,11 @@ def __init__(self, system, config):
692692
if self._config.terminal_flip_angle is not None
693693
else None
694694
)
695-
self._terminal_groups = detect_terminal_groups(mols, flip_angle=flip_angle)
695+
self._terminal_groups = detect_terminal_groups(
696+
mols,
697+
flip_angle=flip_angle,
698+
max_mobile_atoms=self._config.terminal_flip_max_mobile_atoms,
699+
)
696700

697701
if not self._terminal_groups:
698702
_logger.warning(

src/somd2/runner/_samplers/_terminal_flip.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def _round_to_symmetry_angle(raw_angle, tolerance=10.0):
125125
return symmetry_angles[min_idx]
126126

127127

128-
def detect_terminal_groups(system, flip_angle=None):
128+
def detect_terminal_groups(system, flip_angle=None, max_mobile_atoms=None):
129129
"""
130130
Detect terminal ring groups in perturbable molecules using Sire's native
131131
connectivity.
@@ -151,6 +151,11 @@ def detect_terminal_groups(system, flip_angle=None):
151151
a float is given it overrides the geometric measurement for all
152152
groups.
153153
154+
max_mobile_atoms : int or None
155+
Maximum number of mobile atoms allowed in a terminal ring group.
156+
Groups with more mobile atoms than this threshold are skipped.
157+
Defaults to None (no limit).
158+
154159
Returns
155160
-------
156161
@@ -238,6 +243,14 @@ def detect_terminal_groups(system, flip_angle=None):
238243
if not mobile:
239244
continue
240245

246+
# Skip groups with too many mobile atoms.
247+
if max_mobile_atoms is not None and len(mobile) > max_mobile_atoms:
248+
_logger.warning(
249+
f"Terminal group at pivot atom {j} has {len(mobile)} mobile "
250+
f"atoms (max_mobile_atoms={max_mobile_atoms}). Skipping group."
251+
)
252+
continue
253+
241254
# Determine the flip angle for this group.
242255
if flip_angle is not None:
243256
group_angle = flip_angle

0 commit comments

Comments
 (0)