Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Changelog
* Fixed the regular runner's final block when the `runtime` isn't a multiple of the `checkpoint_frequency`, which ran a single integration step rather than the remaining time, without GCMC moves. Each checkpoint now appends exactly the energies sampled since the last one, so energies are no longer duplicated, or lost on restart when `checkpoint_frequency` is zero. Blocks that aren't a whole number of GCMC or terminal flip intervals no longer overrun, and energy components are time stamped correctly after a restart [#248](https://github.com/OpenBioSim/somd2/pull/248).
* Require the `runtime`, `checkpoint_frequency`, `energy_frequency`, `frame_frequency`, `gcmc_frequency` and `terminal_flip_frequency` to be multiples of the `timestep` for the regular runner, which runs in whole integration steps. GCMC and terminal flip moves now keep their frequency across checkpoints [#248](https://github.com/OpenBioSim/somd2/pull/248).
* Speed up checkpointing, which could take minutes for large systems. Sire now uses every CPU thread while checkpoint files are written, unless `max_sire_threads` is set, and replica exchange checkpoints replicas in parallel, writing the shared GCMC topologies once rather than once per replica. The regular runner's worker processes now also apply the Sire thread limit, which previously only took effect in the parent process [#251](https://github.com/OpenBioSim/somd2/pull/251).
* Reduce the setup time of replica exchange simulations that re-use OpenMM contexts across lambda values. Minimisation and equilibration now create their dynamics objects once per context, rather than once per replica [#255](https://github.com/OpenBioSim/somd2/pull/255).

[2026.2.0](https://github.com/openbiosim/somd2/compare/2026.1.0...2026.2.0) - Sep 2026
--------------------------------------------------------------------------------------
Expand Down
5 changes: 0 additions & 5 deletions src/somd2/runner/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1060,11 +1060,6 @@ def _set_dynamics_kwargs(self):
self._config.opencl_platform_index
)

# Set the initial constraint values. This can be modified
# by minimisation and equilibration option.
self._initial_constraint = self._config.constraint
self._initial_perturbable_constraint = self._config.perturbable_constraint

# Common kwargs shared by both dynamics and GCMC sampling.
self._common_kwargs = {
"cutoff": self._config.cutoff,
Expand Down
22 changes: 17 additions & 5 deletions src/somd2/runner/_dynamics_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,11 +623,8 @@ def _create_dynamics(
f"Created dynamics object for lambda {lam:.5f} on device {device}"
)

# Leave the slot marked as holding no replica, so that the first
# call to load_replica() does the full setup (lambda value, GCMC
# parameters, ghost file and sampling statistics) rather than
# assuming the seeding replica is already fully installed.
self._slot_replica[i] = None
# The first load sets up the seeding replica in full.
self.release(i)

# Give each replica its own energy trajectory. These are seeded from a
# slot's own so that the "ensemble" property is carried over. A slot
Expand Down Expand Up @@ -744,6 +741,21 @@ def set(self, slot, dynamics):
"""
self._dynamics[slot] = dynamics

def release(self, slot):
"""
Mark a slot as holding no replica, so that the next replica loaded into
it has its state pushed and its lambda value, GCMC water state, ghost
file and energy trajectory set, e.g. after the slot's dynamics object
is replaced or a failed step left its context in a bad state.

Parameters
----------

slot: int
The index of the slot.
"""
self._slot_replica[slot] = None

def delete(self, slot):
"""
Delete the dynamics object for a given slot.
Expand Down
Loading
Loading