Snapshot optimized solver and audit diagnostics before numerical experiments
This commit is contained in:
@@ -143,11 +143,12 @@ namespace mean_field::solver::detail {
|
||||
};
|
||||
std::array<double, 9> minimumRealValues{};
|
||||
std::array<double, 9> maximumRealValues{};
|
||||
const std::array<int, 3> localIntegerValues{
|
||||
options.maximumIterations, options.linearSolve.maximumIterations, options.backtracking.maximumTrials
|
||||
const std::array<int, 4> localIntegerValues{
|
||||
options.maximumIterations, options.linearSolve.maximumIterations, options.backtracking.maximumTrials,
|
||||
static_cast<int>(options.backtracking.geometryPreflight)
|
||||
};
|
||||
std::array<int, 3> minimumIntegerValues{};
|
||||
std::array<int, 3> maximumIntegerValues{};
|
||||
std::array<int, 4> minimumIntegerValues{};
|
||||
std::array<int, 4> maximumIntegerValues{};
|
||||
|
||||
if (MPI_Allreduce(
|
||||
localRealValues.data(), minimumRealValues.data(), static_cast<int>(localRealValues.size()), MPI_DOUBLE,
|
||||
@@ -341,7 +342,6 @@ export namespace mean_field::solver {
|
||||
ValidateInitialState();
|
||||
InitializeWorkspaces();
|
||||
PrepareInitialOperator();
|
||||
InitializeGeometryPreflightRules();
|
||||
|
||||
physicalInverse = std::unique_ptr<PhysicalInverseType>{new PhysicalInverseType(
|
||||
PreparePhysicalInverse(std::move(preconditionerPrescription), RequireProblem(storage))
|
||||
@@ -485,6 +485,10 @@ export namespace mean_field::solver {
|
||||
const double maximumStepSize,
|
||||
const double fractionToBoundarySafety
|
||||
) {
|
||||
if (!geometryPreflightRulesInitialized) {
|
||||
InitializeGeometryPreflightRules();
|
||||
geometryPreflightRulesInitialized = true;
|
||||
}
|
||||
normalizedOperator->DenormalizeState(normalizedCorrection, physicalCorrection);
|
||||
const auto &physicalOperator = Problem().GetPhysicalOperator();
|
||||
Problem().BuildVolumeDisplacementDirection(physicalCorrection, volumeDisplacementDirection);
|
||||
@@ -513,6 +517,7 @@ export namespace mean_field::solver {
|
||||
mfem::Vector volumeDisplacementDirection;
|
||||
mfem::Vector candidatePhysicalState;
|
||||
std::vector<deformation::NewtonStepGeometryRule> geometryPreflightRules;
|
||||
bool geometryPreflightRulesInitialized{false};
|
||||
double acceptedMinimumJacobianDeterminant{std::numeric_limits<double>::quiet_NaN()};
|
||||
std::unique_ptr<NormalizedOperatorType> normalizedOperator;
|
||||
std::unique_ptr<PhysicalInverseType> physicalInverse;
|
||||
@@ -1271,31 +1276,33 @@ export namespace mean_field::solver {
|
||||
}
|
||||
|
||||
const nonlinear::MetricEvaluation previousMetric = acceptedMetric;
|
||||
const Clock::time_point geometryPreflightStart = Clock::now();
|
||||
timings.geometryPreflight = state.EstimateLargestSafeStepSize(
|
||||
nextLineSearchStepLength, options.backtracking.fractionToBoundarySafety
|
||||
);
|
||||
timings.geometryPreflightSeconds =
|
||||
std::chrono::duration<double>(Clock::now() - geometryPreflightStart).count();
|
||||
diagnostics.totalGeometryPreflightSeconds += timings.geometryPreflightSeconds;
|
||||
diagnostics.lastGeometryPreflight = timings.geometryPreflight;
|
||||
if (timings.geometryPreflight->limitedByGeometry) {
|
||||
++diagnostics.geometryLimitedIterations;
|
||||
}
|
||||
|
||||
if (timings.geometryPreflight->stepSize < options.backtracking.minimumStepLength) {
|
||||
diagnostics.finalResidualNorm = acceptedMetric.residualNorm;
|
||||
NotifyAfter(
|
||||
iteration, nonlinear::IterationDisposition::globalization_failure, false, 0.0, 0,
|
||||
diagnostics.initialResidualNorm, previousMetric, acceptedMetric, linearReport, timings, state
|
||||
if (options.backtracking.geometryPreflight) {
|
||||
const Clock::time_point geometryPreflightStart = Clock::now();
|
||||
timings.geometryPreflight = state.EstimateLargestSafeStepSize(
|
||||
nextLineSearchStepLength, options.backtracking.fractionToBoundarySafety
|
||||
);
|
||||
return Failure(
|
||||
state, std::move(diagnostics), StellarEquilibriumFailureReason::globalization_failure,
|
||||
"The geometry preflight found no orientation-preserving Newton step at or above the "
|
||||
"configured minimum step length."
|
||||
);
|
||||
}
|
||||
timings.geometryPreflightSeconds =
|
||||
std::chrono::duration<double>(Clock::now() - geometryPreflightStart).count();
|
||||
diagnostics.totalGeometryPreflightSeconds += timings.geometryPreflightSeconds;
|
||||
diagnostics.lastGeometryPreflight = timings.geometryPreflight;
|
||||
if (timings.geometryPreflight->limitedByGeometry) {
|
||||
++diagnostics.geometryLimitedIterations;
|
||||
}
|
||||
|
||||
if (timings.geometryPreflight->stepSize < options.backtracking.minimumStepLength) {
|
||||
diagnostics.finalResidualNorm = acceptedMetric.residualNorm;
|
||||
NotifyAfter(
|
||||
iteration, nonlinear::IterationDisposition::globalization_failure, false, 0.0, 0,
|
||||
diagnostics.initialResidualNorm, previousMetric, acceptedMetric, linearReport, timings, state
|
||||
);
|
||||
return Failure(
|
||||
state, std::move(diagnostics), StellarEquilibriumFailureReason::globalization_failure,
|
||||
"The geometry preflight found no orientation-preserving Newton step at or above the "
|
||||
"configured minimum step length."
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
bool accepted = false;
|
||||
double acceptedStepLength = 0.0;
|
||||
int lineSearchTrials = 0;
|
||||
@@ -1303,7 +1310,8 @@ export namespace mean_field::solver {
|
||||
StellarEquilibriumFailureReason rejectionReason =
|
||||
StellarEquilibriumFailureReason::globalization_failure;
|
||||
std::string rejectionMessage = "The backtracking line search found no acceptable Newton step.";
|
||||
double stepLength = timings.geometryPreflight->stepSize;
|
||||
double stepLength = timings.geometryPreflight ?
|
||||
timings.geometryPreflight->stepSize : nextLineSearchStepLength;
|
||||
|
||||
const Clock::time_point lineSearchStart = Clock::now();
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user