Add bounded fully coupled second-order trial correction and frozen screen

This commit is contained in:
2026-09-18 09:41:00 -04:00
parent 2944dd5019
commit 0d87b8b919
14 changed files with 2442 additions and 35 deletions

View File

@@ -5,6 +5,7 @@ module;
#include <cstdint>
#include <limits>
#include <span>
#include <stdexcept>
#include <type_traits>
#include <utility>
@@ -12,6 +13,7 @@ export module mean_field:solver.newton_numerics;
export import :solver.enthalpy_admissibility;
export import :solver.linear_backend;
export import :solver.coupled_trial_correction;
export namespace mean_field::solver::nonlinear {
struct SampledEnthalpy final { };
@@ -39,6 +41,18 @@ export namespace mean_field::solver::nonlinear {
GravitySolveOptions gravity{};
};
struct UncorrectedTrial final { };
struct CoupledCurvatureCorrection final {
CoupledTrialCorrectionOptions correction{};
int maximumAttemptsPerIteration{1};
void Validate() const {
correction.Validate();
if (maximumAttemptsPerIteration <= 0)
throw std::invalid_argument("A coupled trial policy requires a positive attempt budget.");
}
};
template <typename Candidate>
concept EnthalpyNumerics = std::same_as<Candidate, SampledEnthalpy> ||
std::same_as<Candidate, PolynomialEnthalpy>;
@@ -48,23 +62,33 @@ export namespace mean_field::solver::nonlinear {
std::same_as<Candidate, GravityCurvatureCorrection> ||
std::same_as<Candidate, EliminatedGravity>;
template <typename Candidate>
concept TrialPathNumerics = std::same_as<Candidate, UncorrectedTrial> ||
std::same_as<Candidate, CoupledCurvatureCorrection>;
// Types select algorithms; tolerances and the mesh-dependent work sizes
// remain runtime data. Adding a strategy cannot silently change a model's
// equation set or impose an additional specification such as rho_c.
template <EnthalpyNumerics Enthalpy = SampledEnthalpy, GravityNumerics Gravity = MonolithicGravity>
template <EnthalpyNumerics Enthalpy = SampledEnthalpy, GravityNumerics Gravity = MonolithicGravity,
TrialPathNumerics Trial = UncorrectedTrial>
requires (!std::same_as<Gravity, EliminatedGravity> || std::same_as<Trial, UncorrectedTrial>)
struct NewtonNumerics final {
using EnthalpyType = Enthalpy;
using GravityType = Gravity;
using TrialType = Trial;
[[no_unique_address]] Enthalpy enthalpy{};
[[no_unique_address]] Gravity gravity{};
[[no_unique_address]] Trial trial{};
};
template <typename Enthalpy, typename Gravity>
NewtonNumerics(Enthalpy, Gravity) -> NewtonNumerics<Enthalpy, Gravity>;
template <typename Enthalpy, typename Gravity, typename Trial>
NewtonNumerics(Enthalpy, Gravity, Trial) -> NewtonNumerics<Enthalpy, Gravity, Trial>;
template <typename> struct IsNewtonNumerics : std::false_type { };
template <typename Enthalpy, typename Gravity>
struct IsNewtonNumerics<NewtonNumerics<Enthalpy, Gravity>> : std::true_type { };
template <typename Enthalpy, typename Gravity, typename Trial>
struct IsNewtonNumerics<NewtonNumerics<Enthalpy, Gravity, Trial>> : std::true_type { };
template <typename Candidate>
concept NewtonNumericalConfiguration = IsNewtonNumerics<std::remove_cvref_t<Candidate>>::value;
@@ -102,6 +126,9 @@ export namespace mean_field::solver::nonlinear {
double initialGravityResidual{0.0};
double completedInitialGravityResidual{0.0};
double lastLiftedRelativeTrueResidual{0.0};
// Gravity diagnostics refer to the preceding gravity-only preparation
// when this transaction subsequently keeps a fully coupled candidate.
CoupledTrialDiagnostics coupledTrial{};
};
}