Add bounded fully coupled second-order trial correction and frozen screen
This commit is contained in:
@@ -1359,6 +1359,7 @@ export namespace mean_field::solver {
|
||||
const Clock::time_point lineSearchStart = Clock::now();
|
||||
try {
|
||||
for (int trial = 0; trial < options.backtracking.maximumTrials; ++trial) {
|
||||
strategy.BeginTrial(diagnostics.numericalStrategies);
|
||||
++lineSearchTrials;
|
||||
++diagnostics.totalLineSearchTrials;
|
||||
nonlinear::LineSearchTrialDisposition trialDisposition =
|
||||
@@ -1497,6 +1498,41 @@ export namespace mean_field::solver {
|
||||
metricSeconds = std::chrono::duration<double>(Clock::now() - metricStart).count();
|
||||
timings.metricEvaluationSeconds += metricSeconds;
|
||||
diagnostics.totalMetricEvaluationSeconds += metricSeconds;
|
||||
const auto acceptsTrialMetric = [&](const nonlinear::MetricEvaluation &candidateMetric) {
|
||||
if constexpr (Strategy::altersDirection) {
|
||||
return candidateMetric.merit <= acceptedMetric.merit +
|
||||
options.backtracking.sufficientDecrease * stepLength *
|
||||
diagnostics.numericalStrategies.lastMeritDirectionalDerivative;
|
||||
} else {
|
||||
return AcceptStep(acceptedMetric, candidateMetric, stepLength, options.backtracking);
|
||||
}
|
||||
};
|
||||
if constexpr (Strategy::correctsTrial) {
|
||||
if (detail::AllStellarRanksSatisfy(ValidMetric(trialMetric), communicator)) {
|
||||
const Clock::time_point correctionStart = Clock::now();
|
||||
const double previousMetricSeconds = metricSeconds;
|
||||
strategy.TryImproveTrial(state, stepLength, preparationResult, trialMetric,
|
||||
diagnostics.numericalStrategies,
|
||||
[&](const mfem::Vector &residual) {
|
||||
const Clock::time_point start = Clock::now();
|
||||
auto metric = EvaluateMetric(residual);
|
||||
const double seconds = std::chrono::duration<double>(Clock::now() - start).count();
|
||||
metricSeconds += seconds;
|
||||
timings.metricEvaluationSeconds += seconds;
|
||||
diagnostics.totalMetricEvaluationSeconds += seconds;
|
||||
return metric;
|
||||
}, acceptsTrialMetric,
|
||||
[&](const nonlinear::MetricEvaluation &candidate, const nonlinear::MetricEvaluation &original) {
|
||||
return ValidMetric(candidate) && candidate.merit < original.merit;
|
||||
});
|
||||
const double seconds = std::chrono::duration<double>(Clock::now() - correctionStart).count() -
|
||||
(metricSeconds - previousMetricSeconds);
|
||||
preparationSeconds += seconds;
|
||||
timings.trialPreparationSeconds += seconds;
|
||||
diagnostics.totalTrialPreparationSeconds += seconds;
|
||||
minimumJacobianDeterminant = preparationResult->minimumJacobianDeterminant;
|
||||
}
|
||||
}
|
||||
observedTrialMetric = trialMetric;
|
||||
if (!detail::AllStellarRanksSatisfy(ValidMetric(trialMetric), communicator)) {
|
||||
rejectionReason = StellarEquilibriumFailureReason::non_finite_residual;
|
||||
@@ -1508,15 +1544,7 @@ export namespace mean_field::solver {
|
||||
++diagnostics.nonFiniteLineSearchTrials;
|
||||
} else if (
|
||||
detail::AllStellarRanksSatisfy(
|
||||
[&] {
|
||||
if constexpr (Strategy::altersDirection) {
|
||||
return trialMetric.merit <= acceptedMetric.merit +
|
||||
options.backtracking.sufficientDecrease * stepLength *
|
||||
diagnostics.numericalStrategies.lastMeritDirectionalDerivative;
|
||||
} else {
|
||||
return AcceptStep(acceptedMetric, trialMetric, stepLength, options.backtracking);
|
||||
}
|
||||
}(),
|
||||
acceptsTrialMetric(trialMetric),
|
||||
communicator
|
||||
)
|
||||
) {
|
||||
@@ -1559,7 +1587,8 @@ export namespace mean_field::solver {
|
||||
|
||||
timings.observerSeconds += NotifyLineSearchTrial(
|
||||
iteration, trial, stepLength, trialDisposition, rejectionSource, observedTrialMetric,
|
||||
minimumJacobianDeterminant, preparationSeconds, metricSeconds, residualAvailable, state
|
||||
minimumJacobianDeterminant, preparationSeconds, metricSeconds, residualAvailable, state,
|
||||
diagnostics.numericalStrategies
|
||||
);
|
||||
|
||||
if (accepted) {
|
||||
@@ -1767,7 +1796,8 @@ export namespace mean_field::solver {
|
||||
const double preparationSeconds,
|
||||
const double metricSeconds,
|
||||
const bool residualAvailable,
|
||||
const State &state
|
||||
const State &state,
|
||||
const nonlinear::NumericalStrategyDiagnostics &numericalStrategies
|
||||
) {
|
||||
if constexpr (nonlinear::detail::ObservesLineSearchTrial<ObserverType>) {
|
||||
const nonlinear::AfterLineSearchTrial event{
|
||||
@@ -1786,7 +1816,8 @@ export namespace mean_field::solver {
|
||||
.candidateNormalizedResidual = residualAvailable
|
||||
? detail::ReadOnlySpan(state.trialNormalizedResidual)
|
||||
: std::span<const mfem::real_t>{},
|
||||
.normalizedDirection = detail::ReadOnlySpan(state.normalizedCorrection)
|
||||
.normalizedDirection = detail::ReadOnlySpan(state.normalizedCorrection),
|
||||
.numericalStrategies = std::addressof(numericalStrategies)
|
||||
};
|
||||
const Clock::time_point observerStart = Clock::now();
|
||||
nonlinear::detail::InvokeAfterLineSearchTrial(m_observer, event);
|
||||
|
||||
Reference in New Issue
Block a user