Skip to content

Feat: Electronic minimization convergence plot#299

Merged
martin-schlipf merged 12 commits into
masterfrom
electronic-minimization-convergence-plot
Jul 9, 2026
Merged

Feat: Electronic minimization convergence plot#299
martin-schlipf merged 12 commits into
masterfrom
electronic-minimization-convergence-plot

Conversation

@martin-schlipf

Copy link
Copy Markdown
Collaborator

Improve the electronic-minimization convergence plot

Reworks electronic_minimization into a proper convergence overview and adds the Graph features it needs.

Electronic minimization

  • read/plot now use the standard select/index selection logic, so composing and listing columns works ("E + dE", "E, rms"). The rms(c) label is aliased to the grammar-safe rms_c.
  • Not-yet-computed entries (magnitude below a small threshold — notably rms(c)/ort before the NELMDL delay) are reported as NaN instead of zero.
  • Default plot() is a convergence overview: energy changes (E − E_final, dE, d eps) on a log left axis, residuals (rms, rms(c)/ort) on a log secondary axis. Residual columns are derived from the labels, so the ALGO=All ort column works.
  • The energy distance uses E − E_final (positive while converging). Points whose sign is atypical for their series are flagged with a small "×" ("unusual sign"), so a normally-negative dE isn't marked wholesale.

Graph

  • Log-scale axes via xscale/yscale/y2scale.
  • New Marker(symbol, size) (a bare string is shorthand); a friendly symbol-alias map keeps plotly's vocabulary out of the public API. Added show_legend so series can share one legend entry.
  • The legend no longer overlaps the secondary y-axis title.

Add xscale/yscale/y2scale fields (default None = automatic linear scale)
to the Graph dataclass and wire them into the plotly axis options. This
enables log-scale convergence plots such as the electronic-minimization
summary.
Route the selection through select.Tree + index.Selector (as dos/band do)
so that multi-column selections ("E, dE") and compositions ("E + dE") work.
The VASP label "rms(c)" clashes with the selection grammar (parentheses mean
nesting), so it is exposed under the grammar-safe alias "rms_c"; the raw label
is retained for printing.
Without a selection, plot() now produces a convergence overview: the energy
changes (|E_final - E|, |dE|, |d eps|) on a logarithmic left axis and the
residuals (rms, rms_c) on a logarithmic secondary axis, mirroring the ALGO
convergence-summary idea. An explicit selection plots the chosen columns on a
logarithmic axis, flowing through the standard selection logic (e.g. "E, rms").

Positive-value marker flagging from the idea is intentionally left out for a
later exploration.
VASP reports zero for a column until it is computed - most notably rms(c),
which stays zero until density updates begin after the NELMDL delay. read()
now treats any convergence entry whose magnitude is below a small threshold as
not-yet-computed and reports it as NaN, for every column. The convergence
overview therefore no longer plots spurious near-zero points on its log axis.
Printing (__str__) still reproduces the raw OSZICAR values verbatim.
A logarithmic axis cannot show negative numbers, but some columns are signed -
most notably "ort" (reported as rms(c) for ALGO=All), which can be negative. A
directly plotted series is now shown as |value| and labelled "|label|" when any
of its values is negative, and plotted/labelled as-is when all are non-negative.
The energy distance |E_final - E| remains a magnitude by construction.
The overview hardcoded the residual token as "rms_c", so a run whose 7th column
is labelled differently (e.g. "ort" for the fixed ALGO=All output) raised a
KeyError. Derive the residual series from the actual labels by excluding the
fixed non-residual columns (N, E, dE, deps, ncg) instead.
…tive

The convergence overview measured the energy distance as E_final - E, which is
negative while the energy sits above its converged value - i.e. for essentially
every step of a normal run. Flip the convention to E - E_final so the distance
is positive by default, and route it through the same sign-aware _make_series
helper as the other columns (shown as |E - E_final| only when the energy
overshoots below its final value). The demo energy now decreases monotonically.
Add a Marker(symbol, size) dataclass (exported as graph.Marker) and wire the
marker symbol and size through to the plotly trace, so a series can choose how
its points are drawn. A bare string stays valid as a shorthand for the symbol,
and a small alias map translates friendly names (o, *, x, s, ^, v, d, +) to
plotly symbols so the plotly vocabulary does not leak into the public API. Add
a show_legend flag so several series can share a single legend entry.
The convergence overview plots magnitudes on a log axis, so the sign of signed
columns (dE, d eps, and ort) is not visible. When any value is negative, add an
extra markers-only "negative" series that flags those points with a small cross
at their magnitude, one overlay per axis sharing a single legend entry.
Three fixes to the sign overlay:
- The 'x' alias mapped to plotly's 'x-thin', an open thin symbol that renders
  invisibly without a line width; map it to the filled 'x' so the points show.
- Flag only the atypical (minority) sign of each series instead of every
  negative point, so a normally-negative dE is no longer marked wholesale.
- Relabel the overlay 'unusual sign' to match that meaning.

Markers on the two axes still share a single legend entry.
When a graph has a secondary y-axis, the default legend position (x=1.02)
sits on top of the y2 axis title on the right. Move the legend further right
and widen the right margin so the (potentially long) labels are not clipped.
@martin-schlipf martin-schlipf merged commit b39bd5c into master Jul 9, 2026
28 checks passed
@martin-schlipf martin-schlipf deleted the electronic-minimization-convergence-plot branch July 9, 2026 16:13
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