fix: projection convergence loop referenced previous time step's energy - #1254
Merged
Merged
Conversation
The projection routine re-converges the projection orbitals at each output step with a CG loop, exiting when the kinetic-energy change dE = E_kin - rt%E_old drops below threshold_projection. rt%E_old is a persistent (s_rt) value carried over from the previous time step and was not reset to the current step's starting E_kin before the loop. The first iteration's dE was therefore measured against the previous time step rather than the current step's starting orbitals, so when E_kin changes little between steps (large systems / small dt) the loop could exit after a single CG iteration without having converged the projection orbitals. Reset rt%E_old to the current step's E_kin before the loop, and update it before the exit test so it holds the converged value for the next step's "already converged" check. dE in the loop is now the change within this projection's own iterations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Can one of the admins verify this patch? |
MZKC
commented
Jun 24, 2026
MZKC
left a comment
Contributor
Author
There was a problem hiding this comment.
Reviewed — no correctness issues found. Seeding rt%E_old = energy%E_kin before the projection CG loop is the right fix: the first iteration's dE is now measured within this step (against the freshly computed starting-orbital E_kin) instead of against the previous time step, so the loop no longer exits after a single CG step. Moving the in-loop rt%E_old = energy%E_kin ahead of the exit check is behavior-neutral.
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.
Summary
The
projectionroutine re-converges the projection orbitals (Houston /instantaneous eigenstates) at each output step with a CG loop, exiting when the
kinetic-energy change
dE = energy%E_kin - rt%E_olddrops belowthreshold_projection.rt%E_oldis a persistent (s_rt) value carried overfrom the previous time step, and it was not reset to the current step's starting
E_kinbefore the loop. The first iteration therefore measureddEagainst theprevious time step rather than against the current step's starting orbitals.
When
E_kinafter a single CG step happens to land withinthreshold_projectionof the previous step's value, the loop can exit after one iteration without having
converged the projection orbitals — a premature exit. This is a coincidence, so it
shows up intermittently and is more likely for large systems / long runs (matching
the report that the loop "sometimes" stops without converging).
Fix
Reset
rt%E_oldto the current step'sE_kinbefore the loop, and update itbefore the exit test so it holds the converged value for the next step's
"already converged" cross-step check.
dEinside the loop is now the changewithin this projection's own iterations.
Verification (Wisteria-O)
GS → RT with
projection_option='gs', comparing the fixed binary against thepre-fix (
develop-2.0.0) binary:2x2x2k) and SiO2 (18 atoms,4x4x4k,I = 1e14 W/cm^2):Si_rt_energy.data/SiO2_rt_energy.dataare identical (
Eallbit-for-bit); the macroscopic current differs only atthe
1e-19–1e-21(denormal) level. The projection is a read-only analysis,and the fix does not alter the dynamics.
binaries; the per-iteration
dEforiter >= 2is bit-for-bit identical, andonly the first iteration's printed
dEchanges (reflecting the correctedreference). The premature exit is a rare coincidence that did not trigger in
these short runs, so base and fix converged identically.
The change is therefore a safe correctness fix: it removes a rare premature exit
(the reported intermittent under-convergence) and is a no-op in the common case.
🤖 Generated with Claude Code