Hybrid-PIC: checkpoint the electron temperature under the electron energy equation - #7238
Conversation
…tion With `hybrid_pic_model.solve_electron_energy_equation = 1`, the electron temperature `hybrid_electron_temperature_fp` is the evolved state variable of the QDSMC electron-energy equation: it carries the accumulated Joule heating, Q_ei equilibration and advected entropy. It was not written to the checkpoint, so on restart it was reconstructed twice from scratch -- `HybridPICModel::InitData` filled it with the uniform `elec_temp`, and `WarpX::HybridPICInitializeRhoJandB` then overwrote it with the floored adiabat closure on the restored rho. Every restart silently discarded the evolved electron thermal structure, with no warning; a checkpointed run was not equivalent to an uninterrupted one. Measured on a 2D 48^2 Ohm's-law deck with Joule heating (10 steps, checkpoint at step 5), the restarted run differed from the uninterrupted one at step 10 by 9.1e-2 in Te, 1.7e-1 in Ez and 1.4e-4 in Bx -- five steps after the checkpoint. With this change the same pair is bit-identical. Fix: * Flag `hybrid_electron_temperature_fp` with `checkpoint_restart` when the energy equation is on. With the equation off it stays unflagged: there it is a pure diagnostic mirror of the closure, refilled every step. * `MultiFabRegister::read_restarts` now skips a flagged field whose file is absent from the checkpoint instead of aborting the restart, and returns the names it actually read. Without this, checkpoints written before a field was flagged become unrestartable -- which also applies to the pre-existing NuclearFusion `checkpoint_restart` field today. * `WarpX::InitFromCheckpoint` sets `m_te_restored_from_checkpoint` when T_e came back on every level, and warns (WarnPriority::high) when the energy equation is on but the checkpoint has no T_e, in which case the adiabat re-seed still happens as before. * Both T_e seeds are skipped when that flag is set, and `HybridPICInitializeRhoJandB` emits Pe from the restored T_e (with the same boundary treatment grad(Pe) needs) instead of re-seeding. The pre-existing non-energy-equation restart pair is unchanged: its checksum still matches the stored benchmark to 0.00e+00.
765f1d4 to
b218e6f
Compare
|
Verification, for the record — run locally rather than added to CI to keep this PR light. I built a restart-equivalence deck alongside the existing Before the fix, the restarted arm diverges from the uninterrupted one: After the fix, Also checked:
The deck is a small variant of the existing |
The bug
With
hybrid_pic_model.solve_electron_energy_equation = 1, the electron temperaturehybrid_electron_temperature_fpis the evolved state variable of the QDSMCelectron-energy equation — it carries the accumulated Joule heating, the
Q_eiequilibration and the advected entropy. It is not written to the checkpoint, so on
restart it is reconstructed from scratch twice over:
HybridPICModel::InitDatafills it with the uniform<hybrid>.elec_temp, andWarpX::HybridPICInitializeRhoJandBthen overwrites it viaCalculateElectronPressure(floor_density=true), the floored adiabat closure on therestored
rho.Every restart therefore silently discards the evolved electron thermal structure, with
no warning. A checkpointed run is not equivalent to an uninterrupted one, and the
divergence feeds straight back into the fields through
Pe.Source/FieldSolver/WarpXPushFieldsHybridPIC.cppacknowledges this in a comment today("T_e is not checkpointed either … evolved T_e structure is not preserved across a
restart"), but nothing warns the user at runtime.
Measured impact
On a 2D 48² Ohm's-law deck with the energy equation and Joule heating (checkpoint at
step 5, compared at step 10 — five steps of divergence), restart vs. uninterrupted,
relative max error:
TeEzExjxBxrhoWith this PR the same pair is bit-identical (max 1.0e-16, roundoff).
The fix
hybrid_electron_temperature_fpwithcheckpoint_restartwhen the energyequation is on. With the equation off it stays unflagged — there it is a pure
diagnostic mirror of the closure, refilled every step, so checkpoints for the
algebraic-closure path are unchanged.
ablastr::fields::MultiFabRegister::read_restartsnow skips a flagged field whosefile is absent from the checkpoint instead of aborting, and returns the names it
actually read. This keeps older checkpoints restartable. It is also a latent fix
independent of this PR: the pre-existing
checkpoint_restartfield inNuclearFusionFunc.Hmakes a checkpoint written without fusion unrestartable withfusion enabled today.
WarpX::InitFromCheckpointsetsm_te_restored_from_checkpointwhen T_e came back onevery level, and records a
WarnPriority::highwarning when the energy equation is onbut the checkpoint has no T_e — in which case the adiabat re-seed still happens,
exactly as before, so nothing regresses for existing checkpoints.
HybridPICInitializeRhoJandBemits
Pefrom the restored T_e viaQDSMCFillElectronPressureFromTe(with theApplyElectronPressureBoundary+FillBoundarytreatmentgrad(Pe)needs) instead ofre-seeding.
This is the electron-energy-equation companion to #7049, which fixed the rho/J/Pe half of
the same restart path.
Testing
Kept source-only to stay light; verified locally against a restart-equivalence deck (see
comment below). The pre-existing non-energy-equation restart pair is untouched and still
matches the stored benchmark
test_2d_ohm_solver_checkpoint_picmi.jsonto0.00e+00.Happy to add a
test_2d_ohm_solver_ee_checkpoint_picmi{,_restart}pair toExamples/Tests/ohm_solver_restartif reviewers would like the coverage in CI.