Add frozen nonlinear path and mixed curvature investigation
This commit is contained in:
@@ -23,6 +23,7 @@ import mean_field;
|
||||
#include "plateau_pressure_obstruction_diagnostics.hpp"
|
||||
#include "plateau_shape_curvature_diagnostics.hpp"
|
||||
#include "plateau_numerical_strategy_diagnostics.hpp"
|
||||
#include "plateau_nonlinear_step_diagnostics.hpp"
|
||||
#include "plateau_gravity_application_diagnostics.hpp"
|
||||
#include "plateau_positivity_strategy_diagnostics.hpp"
|
||||
#include "plateau_polynomial_certificate.hpp"
|
||||
@@ -35,7 +36,7 @@ struct Options {
|
||||
int maxNewton = 12, maxLinear = 200, restart = 40, probeRestart = 40;
|
||||
bool probes = false, noCentral = false;
|
||||
bool strategyProbe = false, positivityProbe = false, positivityCertificate = false;
|
||||
bool preconditionerProbe = false;
|
||||
bool preconditionerProbe = false, nonlinearStepProbe = false;
|
||||
std::string preconditionerVariant = "independent";
|
||||
int schurCorrectionSweeps = 1;
|
||||
double schurRelaxation = 0.5;
|
||||
@@ -100,6 +101,8 @@ Options Parse(int argc, char **argv) {
|
||||
o.positivityCertificate = true;
|
||||
else if (a == "--preconditioner-probe")
|
||||
o.preconditionerProbe = true;
|
||||
else if (a == "--nonlinear-step-probe")
|
||||
o.nonlinearStepProbe = true;
|
||||
else if (a == "--preconditioner-variant")
|
||||
o.preconditionerVariant = v();
|
||||
else if (a == "--schur-sweeps")
|
||||
@@ -141,24 +144,33 @@ Options Parse(int argc, char **argv) {
|
||||
if (o.positivityCertificate && o.probeState.empty())
|
||||
throw std::invalid_argument("--positivity-certificate requires --probe-state");
|
||||
if (o.positivityCertificate && (o.probes || o.pressureProbe || o.shapeCurvature || o.surfaceTrace ||
|
||||
o.strategyProbe || o.positivityProbe || o.preconditionerProbe || !o.probeDirection.empty() || !o.replayCandidate.empty()))
|
||||
o.strategyProbe || o.positivityProbe || o.preconditionerProbe || o.nonlinearStepProbe || !o.probeDirection.empty() || !o.replayCandidate.empty()))
|
||||
throw std::invalid_argument("--positivity-certificate is a certificate-only mode; omit other probe options");
|
||||
if (o.preconditionerProbe) {
|
||||
experiment::plateau_diagnostics::ParsePreconditionerBenchmarkVariant(o.preconditionerVariant);
|
||||
if (o.maxNewton != 0 || o.probes || o.pressureProbe || o.shapeCurvature || o.surfaceTrace ||
|
||||
o.strategyProbe || o.positivityProbe || o.positivityCertificate || !o.probeDirection.empty() ||
|
||||
o.strategyProbe || o.positivityProbe || o.positivityCertificate || o.nonlinearStepProbe || !o.probeDirection.empty() ||
|
||||
!o.replayCandidate.empty() || !o.captureIterations.empty() || o.strategy != "baseline")
|
||||
throw std::invalid_argument("--preconditioner-probe requires --max-newton 0 and no nonlinear/probe strategies");
|
||||
if (!std::isfinite(o.linearTolerance) || o.linearTolerance <= 0.0)
|
||||
throw std::invalid_argument("A preconditioner benchmark requires a finite positive --linear-tol");
|
||||
}
|
||||
if (o.nonlinearStepProbe) {
|
||||
if (o.maxNewton != 0 || o.probes || o.pressureProbe || o.shapeCurvature || o.surfaceTrace ||
|
||||
o.strategyProbe || o.positivityProbe || o.positivityCertificate || o.preconditionerProbe ||
|
||||
!o.probeDirection.empty() || !o.replayCandidate.empty() || !o.captureIterations.empty() ||
|
||||
o.strategy != "baseline")
|
||||
throw std::invalid_argument("--nonlinear-step-probe requires --max-newton 0 and no other probes or strategy; it compares raw and curvature paths itself");
|
||||
if (!std::isfinite(o.linearTolerance) || o.linearTolerance <= 0.0)
|
||||
throw std::invalid_argument("A nonlinear-step probe requires a finite positive --linear-tol");
|
||||
}
|
||||
if (!o.preconditionerProbe) {
|
||||
if (o.preconditionerVariant != "independent" && o.preconditionerVariant != "gravity-schur" &&
|
||||
o.preconditionerVariant != "stellar-ldu" && o.preconditionerVariant != "stellar-ldu-gravity-schur")
|
||||
throw std::invalid_argument("Newton preconditioner variants are independent, gravity-schur, stellar-ldu, or stellar-ldu-gravity-schur");
|
||||
if (o.preconditionerVariant != "independent") {
|
||||
if (o.probes || o.pressureProbe || o.shapeCurvature || o.surfaceTrace || o.strategyProbe ||
|
||||
o.positivityProbe || o.positivityCertificate || !o.probeState.empty() || !o.probeDirection.empty() ||
|
||||
o.positivityProbe || o.positivityCertificate || (!o.probeState.empty() && !o.nonlinearStepProbe) || !o.probeDirection.empty() ||
|
||||
!o.replayCandidate.empty())
|
||||
throw std::invalid_argument("A custom Newton preconditioner cannot be combined with frozen or certificate probes");
|
||||
if (o.strategy != "baseline" && o.strategy != "positivity" && o.strategy != "curvature" &&
|
||||
@@ -441,6 +453,7 @@ int RunContext(Context &context, const Options &o, const Scales &scales) {
|
||||
<< "\nM=1\nR_reference=1\nxi1=" << scales.xi << "\nmu1=" << scales.mu << "\ncentral_phase=" << !o.noCentral
|
||||
<< "\nrestart=" << o.restart << "\nprobe_restart=" << o.probeRestart
|
||||
<< "\nfrozen_probe_backend=" << (o.preconditionerProbe ? "direct_mfem_fgmres_preconditioner_benchmark" :
|
||||
o.nonlinearStepProbe ? "prepared_fgmres_cold_with_independent_true_gate" :
|
||||
o.positivityCertificate ? "polynomial_certificate_no_linear_solve" :
|
||||
o.probeDirection.empty() ? "direct_mfem_fgmres_cold" : "supplied_direction_no_linear_solve")
|
||||
<< "\nlinear_tol=" << o.linearTolerance << "\nmax_linear=" << o.maxLinear
|
||||
@@ -448,6 +461,7 @@ int RunContext(Context &context, const Options &o, const Scales &scales) {
|
||||
<< "\nstrategy=" << o.strategy << "\ngravity_tolerance=" << o.gravityTolerance
|
||||
<< "\ngravity_iterations=" << o.gravityIterations << "\ngravity_restart=" << o.gravityRestart
|
||||
<< "\npreconditioner_probe=" << o.preconditionerProbe
|
||||
<< "\nnonlinear_step_probe=" << o.nonlinearStepProbe
|
||||
<< "\npreconditioner_variant=" << o.preconditionerVariant
|
||||
<< "\ncontext_preconditioner_variant=" << (o.preconditionerProbe ? "independent" : o.preconditionerVariant)
|
||||
<< "\ncontext_gravity_schur_sweeps="
|
||||
@@ -456,6 +470,27 @@ int RunContext(Context &context, const Options &o, const Scales &scales) {
|
||||
<< "\nschur_correction_sweeps=" << o.schurCorrectionSweeps << "\nschur_relaxation=" << o.schurRelaxation
|
||||
<< "\ncompiler=" << __VERSION__ << "\ncompiled=" << __DATE__ << ' ' << __TIME__ << '\n';
|
||||
metadata.flush();
|
||||
if (o.nonlinearStepProbe) {
|
||||
metadata << "nonlinear_step_input=" << (o.probeState.empty() ? "lane_emden_seed" : "physical_snapshot")
|
||||
<< "\nnonlinear_step_paths=raw,curvature\nnonlinear_step_positivity_repair=0\n";
|
||||
if (!o.probeState.empty()) metadata << "probe_state=" << o.probeState << '\n';
|
||||
metadata.flush();
|
||||
solver::detail::StellarEquilibriumContextDiagnostics::WithState(context, [&](auto &s, const fem::FEM &) {
|
||||
mfem::Vector base(s.acceptedNormalizedState);
|
||||
if (!o.probeState.empty()) {
|
||||
const auto snapshot = LoadVector(o.probeState, s.AcceptedPhysicalState().Size());
|
||||
s.normalizedOperator->NormalizeState(snapshot, base);
|
||||
}
|
||||
experiment::plateau_diagnostics::ProbeNonlinearStep(s, base, o.output, {
|
||||
.linear = {.relativeTolerance = o.linearTolerance, .absoluteTolerance = 0.,
|
||||
.maximumIterations = o.maxLinear},
|
||||
.restartLength = o.restart,
|
||||
.gravity = {.control = {.relativeTolerance = o.gravityTolerance, .absoluteTolerance = 1e-14,
|
||||
.maximumIterations = o.gravityIterations},
|
||||
.backend = {.restartLength = o.gravityRestart, .printLevel = -1}}});
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
// Custom Newton recipes do not instantiate the nine-variant frozen suite.
|
||||
if constexpr (FullDefaultStack) if (o.preconditionerProbe) {
|
||||
metadata << "benchmark_input=" << (o.probeState.empty() ? "lane_emden_seed" : "physical_snapshot") << '\n';
|
||||
|
||||
Reference in New Issue
Block a user