Add bounded coupled damping and prediction-based attempt selection
This commit is contained in:
@@ -44,8 +44,8 @@ namespace mean_field::solver::detail {
|
||||
using Enthalpy = typename Recipe::EnthalpyType;
|
||||
using Gravity = typename Recipe::GravityType;
|
||||
using Trial = typename Recipe::TrialType;
|
||||
std::array<int, 13> integers{};
|
||||
std::array<double, 5> reals{};
|
||||
std::array<int, 14> integers{};
|
||||
std::array<double, 7> reals{};
|
||||
integers[0] = std::same_as<Enthalpy, nonlinear::PolynomialEnthalpy>;
|
||||
integers[1] = std::same_as<Gravity, nonlinear::GravityCurvatureCorrection> ? 1 :
|
||||
std::same_as<Gravity, nonlinear::EliminatedGravity> ? 2 : 0;
|
||||
@@ -61,8 +61,9 @@ namespace mean_field::solver::detail {
|
||||
reals[0] = options.control.relativeTolerance;
|
||||
reals[1] = options.control.absoluteTolerance;
|
||||
}
|
||||
integers[8] = std::same_as<Trial, nonlinear::CoupledCurvatureCorrection>;
|
||||
if constexpr (std::same_as<Trial, nonlinear::CoupledCurvatureCorrection>) {
|
||||
integers[8] = std::same_as<Trial, nonlinear::CoupledCurvatureCorrection> ? 1 :
|
||||
std::same_as<Trial, nonlinear::BacktrackedCoupledCurvatureCorrection> ? 2 : 0;
|
||||
if constexpr (nonlinear::CoupledTrialNumerics<Trial>) {
|
||||
const auto &options = recipe.trial.correction;
|
||||
integers[9] = options.control.maximumIterations;
|
||||
integers[10] = options.backend.restartLength;
|
||||
@@ -72,13 +73,18 @@ namespace mean_field::solver::detail {
|
||||
reals[3] = options.control.absoluteTolerance;
|
||||
reals[4] = options.maximumCorrectionRatio;
|
||||
}
|
||||
if constexpr (std::same_as<Trial, nonlinear::BacktrackedCoupledCurvatureCorrection>) {
|
||||
integers[13] = recipe.trial.search.maximumSteps;
|
||||
reals[5] = recipe.trial.search.reduction;
|
||||
reals[6] = recipe.trial.attempt.maximumExcessRatio;
|
||||
}
|
||||
integers[7] = std::all_of(reals.begin(), reals.end(), [](double value) { return std::isfinite(value); });
|
||||
std::array<int, 13> minimumIntegers{}, maximumIntegers{};
|
||||
std::array<double, 5> minimumReals{}, maximumReals{};
|
||||
if (MPI_Allreduce(integers.data(), minimumIntegers.data(), 13, MPI_INT, MPI_MIN, communicator) != MPI_SUCCESS ||
|
||||
MPI_Allreduce(integers.data(), maximumIntegers.data(), 13, MPI_INT, MPI_MAX, communicator) != MPI_SUCCESS ||
|
||||
MPI_Allreduce(reals.data(), minimumReals.data(), 5, MPI_DOUBLE, MPI_MIN, communicator) != MPI_SUCCESS ||
|
||||
MPI_Allreduce(reals.data(), maximumReals.data(), 5, MPI_DOUBLE, MPI_MAX, communicator) != MPI_SUCCESS) {
|
||||
std::array<int, 14> minimumIntegers{}, maximumIntegers{};
|
||||
std::array<double, 7> minimumReals{}, maximumReals{};
|
||||
if (MPI_Allreduce(integers.data(), minimumIntegers.data(), 14, MPI_INT, MPI_MIN, communicator) != MPI_SUCCESS ||
|
||||
MPI_Allreduce(integers.data(), maximumIntegers.data(), 14, MPI_INT, MPI_MAX, communicator) != MPI_SUCCESS ||
|
||||
MPI_Allreduce(reals.data(), minimumReals.data(), 7, MPI_DOUBLE, MPI_MIN, communicator) != MPI_SUCCESS ||
|
||||
MPI_Allreduce(reals.data(), maximumReals.data(), 7, MPI_DOUBLE, MPI_MAX, communicator) != MPI_SUCCESS) {
|
||||
throw std::runtime_error("Newton could not compare numerical strategies across ranks.");
|
||||
}
|
||||
if (minimumIntegers != maximumIntegers || minimumReals != maximumReals ||
|
||||
@@ -86,7 +92,7 @@ namespace mean_field::solver::detail {
|
||||
throw std::invalid_argument("Newton numerical strategies and controls must agree on every rank.");
|
||||
}
|
||||
if constexpr (!std::same_as<Gravity, nonlinear::MonolithicGravity>) { recipe.gravity.gravity.Validate(); }
|
||||
if constexpr (std::same_as<Trial, nonlinear::CoupledCurvatureCorrection>) { recipe.trial.Validate(); }
|
||||
if constexpr (nonlinear::CoupledTrialNumerics<Trial>) { recipe.trial.Validate(); }
|
||||
}
|
||||
|
||||
template <typename State, typename Policy> class PreparedGravityStrategy;
|
||||
@@ -431,6 +437,11 @@ namespace mean_field::solver::detail {
|
||||
: transaction(state, policy.correction, policy.maximumAttemptsPerIteration) { }
|
||||
PreparedCoupledTrialTransaction<State> transaction;
|
||||
};
|
||||
template <typename State> struct PreparedTrialPath<State, nonlinear::BacktrackedCoupledCurvatureCorrection> {
|
||||
PreparedTrialPath(State &state, const nonlinear::BacktrackedCoupledCurvatureCorrection &policy)
|
||||
: transaction(state, policy.correction, policy.maximumAttemptsPerIteration, policy.search, policy.attempt) { }
|
||||
PreparedCoupledTrialTransaction<State, BacktrackedCoupledStep, NearAcceptanceCoupledAttempt> transaction;
|
||||
};
|
||||
|
||||
template <typename State, nonlinear::NewtonNumericalConfiguration Recipe>
|
||||
class PreparedNewtonStrategy final : public NewtonStrategyStorage {
|
||||
@@ -439,7 +450,7 @@ namespace mean_field::solver::detail {
|
||||
using Gravity = typename Recipe::GravityType;
|
||||
using Trial = typename Recipe::TrialType;
|
||||
static constexpr bool altersDirection = std::same_as<Enthalpy, nonlinear::PolynomialEnthalpy>;
|
||||
static constexpr bool correctsTrial = std::same_as<Trial, nonlinear::CoupledCurvatureCorrection>;
|
||||
static constexpr bool correctsTrial = nonlinear::CoupledTrialNumerics<Trial>;
|
||||
|
||||
PreparedNewtonStrategy(State &state, const Recipe &recipe)
|
||||
: m_enthalpy(state, recipe.enthalpy), m_gravity(state, recipe.gravity), m_trial(state, recipe.trial) { }
|
||||
|
||||
Reference in New Issue
Block a user