Add checked harmonic snapshot continuation and matched linear trial diagnostics

This commit is contained in:
2026-09-19 13:43:49 -04:00
parent 77130fa603
commit 53faac1cd2
8 changed files with 582 additions and 7 deletions

View File

@@ -840,6 +840,48 @@ export namespace mean_field::solver {
export namespace mean_field::solver::detail {
struct StellarEquilibriumContextDiagnostics final {
// Research continuation supplies physical coefficients in a newly
// compiled problem. Keep this explicit mutation separate from WithState:
// a prepared initial guess has no equilibrium certification, and a
// correction recycled from the preceding problem has no valid tangent.
template <StellarEquilibriumContextType Context>
static void InitializePhysicalState(Context &context, const mfem::Vector &physicalState) {
if (context.hasActiveSolver() || !context.isReady())
throw std::logic_error("Initial-state installation requires a ready, inactive context.");
auto &state = *context.m_state;
bool valid = physicalState.Size() == state.Problem().StateSize();
for (int i = 0; i < physicalState.Size(); ++i)
valid = valid && std::isfinite(physicalState(i));
if (!AllStellarRanksSatisfy(valid, state.Problem().GetCommunicator()))
throw std::invalid_argument("Initial physical coefficients have invalid size or values.");
context.AcquireSolver();
try {
state.BeginEvaluation();
state.normalizedOperator->NormalizeState(physicalState, state.trialNormalizedState);
const auto preparation = state.PrepareTrial();
if (!preparation)
throw std::invalid_argument("Initial physical coefficients fail operator preparation.");
bool finiteResidual = true;
for (int i = 0; i < state.trialNormalizedResidual.Size(); ++i)
finiteResidual = finiteResidual && std::isfinite(state.trialNormalizedResidual(i));
if (!AllStellarRanksSatisfy(finiteResidual, state.Problem().GetCommunicator()))
throw std::invalid_argument("Initial physical coefficients produce a nonfinite residual.");
state.PrepareTrialCommit();
state.CommitPreparedTrial(preparation->minimumJacobianDeterminant);
state.normalizedCorrection = 0.;
state.physicalCorrection = 0.;
state.volumeDisplacementDirection = 0.;
state.linearRightHandSide = 0.;
context.ReleaseSolver();
} catch (...) {
const auto original = std::current_exception();
try { state.RestoreAccepted(); }
catch (...) { context.ReleaseSolver(); throw; }
context.ReleaseSolver();
std::rethrow_exception(original);
}
}
// The callback must not retain references to runtime storage. It may
// prepare trial states, but accepted vectors must remain unchanged.
// Restore the production preparation and correction on every exit.