Skip to content

Commit 05f5306

Browse files
authored
Merge pull request #127 from OpenBioSim/fix_gcmc_sync
Fix GCMC trajectory synchronisation
2 parents ce6448c + dd1eaed commit 05f5306

3 files changed

Lines changed: 31 additions & 35 deletions

File tree

.img/somd2.png

53 Bytes
Loading

src/somd2/runner/_repex.py

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,28 +1242,6 @@ def _run_block(
12421242
# Draw new velocities from the Maxwell-Boltzmann distribution.
12431243
dynamics.randomise_velocities()
12441244

1245-
# Perform a GCMC move. For repex this needs to be done before the
1246-
# dynamics block so that the final energies, which are used in the
1247-
# repex acceptance criteria, are correct.
1248-
if is_gcmc and gcmc_sampler is not None:
1249-
# Push the PyCUDA context on top of the stack.
1250-
gcmc_sampler.push()
1251-
1252-
# Perform the GCMC move.
1253-
_logger.info(f"Performing GCMC move at {_lam_sym} = {lam:.5f}")
1254-
gcmc_sampler.move(dynamics.context())
1255-
1256-
# Remove the PyCUDA context from the stack.
1257-
gcmc_sampler.pop()
1258-
1259-
# A frame was saved at the end of the last cycle, so write
1260-
# the current ghost water residue indices to file. This is
1261-
# done here, immediately after the GCMC move, since the
1262-
# sampler state is only updated during GCMC moves and waters
1263-
# may have moved in/out of the GCMC sphere during dynamics.
1264-
if write_gcmc_ghosts:
1265-
gcmc_sampler.write_ghost_residues()
1266-
12671245
# Run the dynamics.
12681246
dynamics.run(
12691247
self._config.energy_frequency,
@@ -1287,13 +1265,30 @@ def _run_block(
12871265
),
12881266
)
12891267

1290-
# Set the state.
1291-
self._dynamics_cache.save_openmm_state(index)
1292-
1293-
# Save the GCMC state.
12941268
if gcmc_sampler is not None:
1269+
# Write ghost residues before the GCMC move so the ghost state
1270+
# is consistent with the saved frame (which is also captured
1271+
# before the GCMC move).
1272+
if write_gcmc_ghosts:
1273+
gcmc_sampler.write_ghost_residues()
1274+
1275+
if is_gcmc:
1276+
# Push the PyCUDA context on top of the stack.
1277+
gcmc_sampler.push()
1278+
1279+
# Perform the GCMC move.
1280+
_logger.info(f"Performing GCMC move at {_lam_sym} = {lam:.5f}")
1281+
gcmc_sampler.move(dynamics.context())
1282+
1283+
# Remove the PyCUDA context from the stack.
1284+
gcmc_sampler.pop()
1285+
1286+
# Save the GCMC state.
12951287
self._dynamics_cache.save_gcmc_state(index)
12961288

1289+
# Save the OpenMM state after any GCMC move so the context is consistent.
1290+
self._dynamics_cache.save_openmm_state(index)
1291+
12971292
# Get the energy at each lambda value.
12981293
energies = dynamics._current_energy_array()
12991294

src/somd2/runner/_runner.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ def generate_lam_vals(lambda_base, increment=0.001):
690690
next_frame = self._config.frame_frequency
691691

692692
# Loop until we reach the runtime.
693-
while runtime <= checkpoint_frequency:
693+
while runtime < checkpoint_frequency:
694694
# Run the dynamics in blocks of the GCMC frequency.
695695
dynamics.run(
696696
self._config.gcmc_frequency,
@@ -714,21 +714,22 @@ def generate_lam_vals(lambda_base, increment=0.001):
714714
),
715715
)
716716

717-
# Perform a GCMC move.
718-
_logger.info(
719-
f"Performing GCMC move at {_lam_sym} = {lambda_value:.5f}"
720-
)
721-
gcmc_sampler.move(dynamics.context())
722-
723717
# Update the runtime.
724718
runtime += self._config.energy_frequency
725719

726-
# If a frame is saved, then we need to save current indices
727-
# of the ghost water residues.
720+
# If a frame is saved, write the ghost residue indices
721+
# before the GCMC move so the ghost state is consistent
722+
# with the saved frame.
728723
if save_frames and runtime >= next_frame:
729724
gcmc_sampler.write_ghost_residues()
730725
next_frame += self._config.frame_frequency
731726

727+
# Perform a GCMC move.
728+
_logger.info(
729+
f"Performing GCMC move at {_lam_sym} = {lambda_value:.5f}"
730+
)
731+
gcmc_sampler.move(dynamics.context())
732+
732733
else:
733734
dynamics.run(
734735
checkpoint_frequency,

0 commit comments

Comments
 (0)