Resolve reduced derivative trend with a recorded four-step diagnostic grid

This commit is contained in:
2026-09-17 10:09:24 -04:00
parent 2e31917269
commit b7ea1bdcf8
2 changed files with 36 additions and 1 deletions

View File

@@ -19,6 +19,9 @@ struct NumericalStrategyProbeOptions final {
int restartLength{80};
int maximumCompletionCorrections{2};
double gravityCompletionTolerance{1.e-11};
// Coarser differences resolve truncation before cancellation dominates;
// the final small step independently checks derivative accuracy.
std::array<double, 4> reducedDifferenceSteps{.1, .03, .01, .001};
};
namespace numerical_strategy_detail {
@@ -55,6 +58,12 @@ void ProbeNumericalStrategies(
if (options.restartLength <= 0 || options.maximumCompletionCorrections <= 0 ||
!std::isfinite(options.gravityCompletionTolerance) || options.gravityCompletionTolerance <= 0.)
throw std::invalid_argument("Numerical strategy probes require valid inner and completion controls.");
double previousDifferenceStep = std::numeric_limits<double>::infinity();
for (const double step : options.reducedDifferenceSteps) {
if (!std::isfinite(step) || step <= 0. || step >= previousDifferenceStep)
throw std::invalid_argument("Reduced finite-difference steps must be finite, positive, and strictly decreasing.");
previousDifferenceStep = step;
}
int ranks = 0;
MPI_Comm_size(state.Problem().GetCommunicator(), &ranks);
if (ranks != 1 || !finiteElements.mesh || normalizedBase.Size() != state.Problem().StateSize() ||
@@ -92,6 +101,8 @@ void ProbeNumericalStrategies(
<< "\ninner_maximum_iterations," << options.inner.maximumIterations
<< "\ninner_restart_length," << options.restartLength
<< "\ngravity_completion_tolerance," << options.gravityCompletionTolerance << '\n';
for (std::size_t index = 0; index < options.reducedDifferenceSteps.size(); ++index)
summary << "reduced_difference_step_" << index << ',' << options.reducedDifferenceSteps[index] << '\n';
const double nan = std::numeric_limits<double>::quiet_NaN();
int preparationCount = 0;
double restorationError = 0.;
@@ -281,7 +292,7 @@ void ProbeNumericalStrategies(
<< "\nlifted_gravity_action_norm," << gravityResidual.Norml2()
<< "\nlifted_retained_action_difference," << d::Difference(retainedAction, reducedAction)
<< "\ncompleted_base_residual_norm," << completedBaseResidual.Norml2() << '\n';
for (const double alpha : {1.e-2, 1.e-3, 1.e-4}) {
for (const double alpha : options.reducedDifferenceSteps) {
std::array<mfem::Vector, 2> residuals{mfem::Vector(base.Size()), mfem::Vector(base.Size())};
std::array<bool, 2> completed{};
std::array<double, 2> gravityNorms{nan, nan};