Match frozen trial metric validation to production backtracking

This commit is contained in:
2026-09-18 10:49:44 -04:00
parent 422c46bcbf
commit 25816d4328
2 changed files with 17 additions and 4 deletions

View File

@@ -59,7 +59,9 @@ every candidate evaluation, fresh selected-state replay and unchanged accepted
buffers/normalization. Only the accepted trial is replayed for quadrature-14 and
quadrature-18 physical observations, outside the timed selection phase.
Operation timings exclude artifact output and physical replay; search wall time
Operation timings include raw preparation, gravity correction and the coupled transaction.
They exclude setup, ordinary initial/final metric calls, final restoration, accepted
commit refresh, artifact output and physical replay; search wall time
also includes artifact output. Callback vector copies remain in the measured
transaction. The no-correction control captures the same tangent for a comparable
screen, so capture cost is reported separately and is not ordinary Newton work

View File

@@ -133,7 +133,12 @@ void ProbeDampedCoupledPath(State &state, const mfem::Vector &base, const mfem::
const auto baseMetric = evaluate(baseF);
mfem::Vector defect(action);
defect += baseF;
const bool outerGate = d::Norm(defect) <= options.common.outerLinearTolerance * baseMetric.residualNorm;
const double defectNorm = d::Norm(defect);
const bool outerGate = d::Finite(baseF) && d::Finite(action) && d::Finite(defect) &&
std::isfinite(baseMetric.residualNorm) && baseMetric.residualNorm > 0. &&
std::isfinite(baseMetric.merit) && baseMetric.merit >= 0. && std::isfinite(d::Norm(direction)) &&
std::isfinite(d::Norm(action)) &&
std::isfinite(defectNorm) && defectNorm <= options.common.outerLinearTolerance * baseMetric.residualNorm;
metric("base_norm", baseMetric.residualNorm);
metric("base_merit", baseMetric.merit);
metric("outer_relative_defect", d::Norm(defect) / baseMetric.residualNorm);
@@ -196,11 +201,17 @@ void ProbeDampedCoupledPath(State &state, const mfem::Vector &base, const mfem::
gravitySeconds = d::Seconds(started);
if (gravityGate) d::Save(file("gravity_correction" + suffix), gravity->fullCorrection);
}
const bool usable = preparation.has_value() && gravityGate;
// Production rejects an overflowing prepared residual before the
// correction transaction, whose precondition requires a valid metric.
const bool preparedFinite = preparation.has_value() && gravityGate && d::Finite(state.trialNormalizedResidual);
const auto preparedMetric = preparedFinite ? evaluate(state.trialNormalizedResidual) :
solver::nonlinear::MetricEvaluation{nan, nan};
const bool usable = preparedFinite && std::isfinite(preparedMetric.residualNorm) &&
preparedMetric.residualNorm >= 0. && std::isfinite(preparedMetric.merit) && preparedMetric.merit >= 0.;
const mfem::Vector before(state.trialNormalizedState);
auto beforeMetric = solver::nonlinear::MetricEvaluation{nan, nan};
if (usable) {
beforeMetric = evaluate(state.trialNormalizedResidual);
beforeMetric = preparedMetric;
d::Save(file("before" + suffix), before);
d::Save(file("before_residual" + suffix), state.trialNormalizedResidual);
}