Skip to content

Extend script_mode to liquid, alchemy, and mode:ts#248

Open
ligerzero-ai wants to merge 2 commits into
ICAMS:mainfrom
ligerzero-ai:feat/script-mode-all-phases
Open

Extend script_mode to liquid, alchemy, and mode:ts#248
ligerzero-ai wants to merge 2 commits into
ICAMS:mainfrom
ligerzero-ai:feat/script-mode-all-phases

Conversation

@ligerzero-ai
Copy link
Copy Markdown

Summary

Currently script_mode: true only works for mode: fe with reference_phase: solid. For other phases/modes the code unconditionally constructs a pylammpsmpi.LammpsLibrary — which requires LAMMPS built as a shared library with Python bindings (PKG_PYTHON=ON, BUILD_LIB=ON, BUILD_SHARED_LIBS=ON).

This is restrictive for users running ML interatomic potentials whose LAMMPS plugins ship only as a regular executable build (e.g. pair_grace against a TensorFlow SavedModel; pair_mace; etc.). For these the natural workflow is script_mode: true + lammps_executable: <path> — calphy emits a .lmp script and the user's lmp runs it.

This PR extends that workflow to liquid, alchemy, and mode: ts so they all honour script_mode: true end-to-end and shell out via lammps_executable.

Changes

  1. Extend script_mode to liquid and alchemy phases (1cd7612)

    • helpers.py: LammpsScript gains a __getattr__ polyfill so unknown attributes (e.g. lmp.velocity(...), lmp.run(N)) lower to the equivalent command(...) call. Lets the liquid/alchemy routines use the same Python-style API as the in-process LammpsLibrary path without each call site needing two branches.
    • liquid.py: propagate script_mode into the LAMMPS factory; emit averaging.lmp and integration.lmp at the end of each routine when in script mode.
    • alchemy.py: same propagation pattern.
  2. Extend script_mode to mode:ts (76b0ad7)

    • phase.py: reversible_scaling and temperature_scaling were the last sites hardcoding script_mode=False; replace with script_mode=self.calc.script_mode and write the resulting reversible_scaling_<i>.lmp / temperature_scaling_<i>.lmp.

Default behaviour is unchanged: script_mode still defaults to false, all existing in-process workflows go through the same LammpsLibrary path as before.

Tests

pytest tests/ — all 96 existing tests pass on this branch.

The branch is based on commit 0911ac4; main has since moved 9 commits ahead (phase_diagram.py rework + version bump 1.7.2 → 1.7.3 + tdb test renames). None of the upstream changes touch the files modified here (phase.py, liquid.py, alchemy.py, helpers.py), so this should merge cleanly — happy to rebase if preferred.

Out-of-band validation

Used to drive a 48-potential calphy mode: ts campaign computing F(T) BCC/FCC for GRACE Fe ML interatomic potentials against a custom LAMMPS binary that doesn't have Python bindings.

ligerzero-ai and others added 2 commits May 2, 2026 20:49
Previously script_mode (which writes averaging.lmp/integration.lmp for
execution by an external lammps_executable) was wired up only for the
solid phase. Liquid and alchemy phases hardcoded the in-process
LammpsLibrary path, so users running with a custom LAMMPS binary could
only do solid-phase free-energy calculations.

Changes:
- helpers.py: LammpsScript now polyfills the LammpsLibrary Python API.
  Unknown attribute access lowers to a LAMMPS command (so lmp.velocity(...)
  and lmp.run(N) work in script_mode the same way they do in-process).
  Adds no-op close() and clear() to mirror LammpsLibrary teardown.
- liquid.py: run_averaging and run_integration now propagate
  script_mode to create_object and emit averaging.lmp / integration.lmp
  at the end of each step. Iterative pyscal-based solid-fraction check is
  skipped under script_mode (cannot run mid-script). melting_cycle is
  rejected with a clear ValueError under script_mode since it requires
  Python-driven feedback.
- alchemy.py: same propagation and script-emission for run_averaging
  and run_integration.

Pair-style handling is unchanged and remains pair-style-agnostic, so any
LAMMPS binary that supports the user's pair_style (EAM, MEAM, SNAP, ACE,
GRACE, ML-PACE, etc.) can be plugged in via the existing
lammps_executable / mpi_executable input fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
reversible_scaling, temperature_scaling, and the alchemy-side hardcoded
script_mode=False sites were the last places where in-process LAMMPS
was forced even when the calculation requested script_mode. They are now
the same script_mode-aware pattern as the rest of the codebase: emit a
single static LAMMPS script and return so the user's lammps_executable
can run it.

- phase.py reversible_scaling: writes reversible_scaling_<iteration>.lmp
- phase.py temperature_scaling: writes temperature_scaling_<iteration>.lmp
- alchemy-side reversible_scaling at the same site picks up the same
  fix automatically (replace_all)

This unblocks running mode:ts free-energy temperature sweeps end-to-end
under script_mode, which is the workflow needed to drive an external
ML-potential-built lammps binary (e.g. GRACE, ACE, MACE) for phase-
boundary calculations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant