Phonons at temperature: the 0 K stability answer is often the wrong one - #14
Merged
Conversation
mv.prop.phonon_at_temperature fits, through hiphive, the effective harmonic
force constants that best describe the potential energy surface sampled *at* a
temperature, rather than expanding about the 0 K minimum.
obs['dynamically_stable_{level}'] from mv.prop.phonon is a statement about 0 K,
and a great many real materials fail it and exist anyway: bcc metals and cubic
perovskites are unstable in the harmonic approximation and held up by
anharmonicity at the temperature they are used at. A screen that discarded them
on the 0 K answer would be discarding the answer.
Three copper lattices give the three answers this can return, and the suite
asserts each:
bcc 4 imaginary modes at 50 K, none from 300 K -> stabilised at 300 K
fcc none at any temperature -> nothing to stabilise
sc 21 at every temperature -> never stabilised
obs['stabilisation_temperature_{level}'] is NaN for both fcc and sc, for
opposite reasons, so uns[...]['verdict'] says which. A NaN meaning two opposite
things is worse than no column.
I nearly shipped a wrong conclusion here. Lattice.cubic(2.9) with one atom is
simple cubic, not bcc, and on that structure the method looked erratic - 72
imaginary modes at 50 K and a stabilisation temperature that moved from 900 K
to 300 K on iteration count alone. It was the input that was wrong. With the
real bcc primitive the answer is identical at 8 and 20 iterations, and a test
now asserts that so a genuine convergence failure would be visible rather than
inferred.
Two diagnostics are recorded because both change the answer silently.
n_free_parameters is the size of the cluster space: a strongly unstable cell
with four of them gave imaginary modes reappearing at a higher temperature,
which is not physics, and eleven did not. Fewer than six now warns. Note that
on well-behaved cases the two cutoffs agree exactly, so a small cluster space is
a risk rather than a guaranteed error, and the note says so rather than
overclaiming. convergence_drift is how far the parameters were still moving over
the last five iterations, because a fixed-point iteration run for a fixed number
of steps does not report its own convergence.
The cutoff is checked against half the shortest supercell dimension up front,
rather than left to a confusing failure deep inside the fit. hiphive's stdout
reporting is captured, because a library should not print into the middle of
somebody else's loop, and a test asserts it.
hiphive reaches numba through trainstation and numba caps numpy below 2.5, so
matverse[anharmonic] gets a CI job of its own. Adding it to the existing extras
would quietly downgrade numpy on the 3.12 leg, which exists precisely to test
the newest numpy - the extra would be covered at the cost of no longer covering
what that leg is for.
The tutorial says plainly that its cell prints a fallback in the rendered docs,
because the environment that builds them runs numpy 2.5 and hiphive cannot, and
that the table beside it is what the cell produces where hiphive is installed.
948 pass on py3.12 without hiphive, 846 on py3.10, and the nine
self-consistent-phonon tests pass in an environment with hiphive and numpy
2.4.6. Contract-verified rate stays 165/165, all 16 notebooks execute, docs
build.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wh5NzNE9Wn49nuUm7zg2a
…them CI caught what one machine could not. The anharmonic job reported 22 imaginary modes for bcc copper at 300 K where there should be none, on a solve whose drift diagnostic had already flagged it as unconverged. Locally the same settings gave the right answer on five different seeds with a worst drift of 0.023. The stochastic sampling differs with the BLAS underneath, so a setting that converges on the machine it was tuned on is not a setting that converges. Defaults raised from 10 iterations and 15 structures to 20 and 25, which brings the worst drift across those seeds from 0.023 to 0.007. Chasing that turned up a worse mistake in the test rather than the code. With proper convergence bcc copper came back *stable* at 50 K, which looked like the method destroying the very effect it exists to detect. It was not: the transition sits between 25 K and 100 K, and 50 K is on it. Scanning 5, 25, 50, 100 and 200 K shows four imaginary modes at 5 and 25 K under both 8 and 30 iterations, and the only thing convergence moves is where in that window the crossing lands - 100 K at 8 iterations, 50 K at 30. So the test was asserting the resolution limit and calling it physics. It now brackets the transition instead, asserting instability at 5 K and 25 K and stability at 300 K and 600 K, and leaving the boundary alone. The notes and the tutorial say that the crossing is resolved no better than the spacing scanned and that it moves with convergence, rather than quoting a number as if it were sharp. A test that runs first asserts the fixture converged at all, so a convergence failure is named as one instead of surfacing as the physics being wrong. The fixture deliberately runs past the defaults, because these tests assert a specific physical outcome and so have to be somewhere it has converged. 948 pass on py3.12 without hiphive; the ten self-consistent-phonon tests pass with hiphive on numpy 2.4.6. Contract-verified rate stays 165/165, all 16 notebooks execute, docs build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016wh5NzNE9Wn49nuUm7zg2a
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.
mv.prop.phonon_at_temperaturefits, through hiphive, the effective harmonic force constants that best describe the potential energy surface sampled at a temperature — rather than expanding about the 0 K minimum.obs["dynamically_stable_{level}"]frommv.prop.phononis a statement about 0 K, and a great many real materials fail it and exist anyway. bcc metals and cubic perovskites are unstable in the harmonic approximation and held up by anharmonicity at the temperature they are actually used at. A screen that discarded them on the 0 K answer would be discarding the answer.Three lattices, three answers
stabilisation_temperatureis NaN for both fcc and sc, for opposite reasons, souns[...]["verdict"]says which. A NaN meaning two opposite things is worse than no column, and a test asserts the two verdicts differ.I nearly shipped a wrong conclusion
Lattice.cubic(2.9)with one atom is simple cubic, not bcc. On that structure the method looked erratic — 72 imaginary modes at 50 K, and a stabilisation temperature that moved from 900 K to 300 K on iteration count alone. I was about to report the method as unreliable.It was the input that was wrong. With the real bcc primitive the answer is identical at 8 and 20 iterations, and a test now asserts that, so a genuine convergence failure would be visible rather than inferred.
Two diagnostics, because both change the answer silently
n_free_parameters— the cluster space size. A strongly unstable cell with four gave imaginary modes reappearing at higher temperature (not physics); eleven did not. Fewer than six warns. On well-behaved cases both cutoffs agree exactly, so a small cluster space is a risk, not a guaranteed error — the note says that rather than overclaiming.convergence_drift— how far the parameters were still moving over the last five iterations. This is a fixed-point iteration run for a fixed step count, so it does not report its own convergence.The cutoff is checked against half the shortest supercell dimension up front rather than failing deep inside the fit. hiphive's stdout reporting is captured — a library should not print into the middle of somebody else's loop — and a test asserts it.
A CI job of its own
hiphive reaches numba through trainstation, and numba caps numpy < 2.5. Adding it to the existing extras would quietly downgrade numpy on the 3.12 leg — which exists precisely to test the newest numpy. The extra would be covered at the cost of no longer covering what that leg is for, so it gets its own job.
The tutorial says plainly that its cell prints a fallback in the rendered docs (the docs environment runs numpy 2.5) and that the table beside it is what the cell produces where hiphive is installed.
Verification
🤖 Generated with Claude Code
https://claude.ai/code/session_016wh5NzNE9Wn49nuUm7zg2a