Repository navigation
Fix twelve findings from the 2026-08-17 review - #22
Merged
Merged
Conversation
Replica exchange: - Add the de Broglie cross-term 3*sum_s(dN_s)*ln(Lambda_i/Lambda_j) to the grand-canonical swap criterion in both BatchedReplicaExchange and the MPI ReplicaExchange (lambda_dbs now rides on get_state). Mu ladders were already exact (the term cancels at shared T); temperature and joint ladders with fluctuating N were biased. - Reject non-finite swap exponents with a warning instead of silently inverting the NaN behavior (the old min(1, exp(nan)) accepted every swap). - Warn per rung on zero second-half swap acceptance (midpoint tally snapshot): the whole-run check could not see a ladder dead at one rung. - Report swap attempts, not doubled per-slot tallies, in the degeneracy warning, and emit it as a single log record. - Refuse factories that share atoms, move_selector or cells across replicas under batching. State and cells: - set_state restores step and exchange tallies when present (lossless restart round-trip); ReplicaExchange strips them on swaps instead. - is_point_exchangeable defaults on BaseCell, and the molecule moves fall back to is_point_inside for duck-typed cells (pre-1.4.0 contract). Alchemi calculators: - Raise when head= is passed with a pre-loaded MACEWrapper (it was silently ignored, evaluating multihead models on the pretrain head). - Drop the impossible workaround from the energy_only guard message. - Refuse forces-stripped models in AlchemiFCalculator and in run_md. Docs: - Ladder-spacing reference: include the mu_max endpoint (fencepost), sort descending isotherms, clip noise-negative dN/dmu.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the twelve high- and medium-severity findings from the 2026-08-17 review of the v1.4.0 changes (the review ran against PR #21, whose content was already rebased onto main).
Replica exchange
Lambda_s^(-3 N_s)per exchangeable species, andLambdadepends on T, so swaps between rungs at different temperatures with different particle counts were biased (e.g. 300/400 K with dN = 10: acceptance off by ~e^4.3). BothBatchedReplicaExchange._accept_swapand the MPIReplicaExchange._exchange_prob_Tnow add3 * sum_s dN_s * ln(Lambda_i,s / Lambda_j,s);lambda_dbsrides onget_state(). Mu ladders were already exact (the term cancels at shared T) and are pinned unchanged; LJ units (Lambda = 1) are unaffected automatically.min(1, exp(nan))form silently accepted every swap involving a NaN energy; the rewritten comparison would have silently rejected. Neither is acceptable for a diverged relaxation, so a NaN/inf delta now logs a warning naming the pair and rejects.State and cells
set_staterestoresstepand the exchange tallies when the dict carries them;ReplicaExchangestrips those slot-bound keys before applying a swap (previouslyset_statedropped them unconditionally, silently renumbering restarted runs from step 0).is_point_exchangeabledefaults onBaseCell, and the molecule moves fall back tois_point_insidefor plain duck-typed cells, restoring the pre-1.4.0 single-predicate contract that 1.4.0 broke with an AttributeError.Alchemi calculators
head=with a pre-loadedMACEWrapperraises. It was silently ignored, so a fine-tuned multihead model shared as a wrapper evaluated on head 0, the pretrain head.energy_onlyguard message no longer suggests an impossible workaround ("set energy_only on all of the sharers" trips the same guard).AlchemiFCalculator.__init__rejects a wrapper whoseactive_outputslacks forces (the.modelof an energy-only calculator), andrun_mdon an energy-only calculator raises up front instead of dying steps deep inside nvalchemi.Docs
mu_maxendpoint (thenp.arangefencepost dropped the top rung by up to a full spacing), sorts descending isotherms (desorption scans), and clips noise-negativedN/dmuinstead of propagating NaN into a cryptic crash. Verified by executing the snippet: endpoint exact, noisy input stays finite, descending input matches ascending.Tests
11 new tests: analytic swap probabilities with and without the cross-term, slot-order symmetry, NaN rejection with warning, per-rung second-half detection, un-doubled warning counts, replica-isolation refusal and acceptance, restart round-trip for both ensembles, and the duck-typed-cell fallback. Full suite: 198 passed; flake8 clean.