Add explicit mass-compatible rotating n3 physical-family control

This commit is contained in:
2026-09-19 13:58:08 -04:00
parent 6d423cba46
commit 1d746b028e
3 changed files with 103 additions and 1 deletions

View File

@@ -45,6 +45,7 @@ namespace {
using Clock = std::chrono::steady_clock;
struct Options {
double n = 1., angularMomentum = 0., atol = 0., rtol = 1e-8, linearTolerance = .03;
double n3KFactor = 1.;
int maxNewton = 12, maxLinear = 200, restart = 40, probeRestart = 40;
bool probes = false, noCentral = false;
bool strategyProbe = false, positivityProbe = false, positivityCertificate = false;
@@ -89,6 +90,8 @@ Options Parse(int argc, char **argv) {
};
if (a == "--index")
o.n = std::stod(v());
else if (a == "--n3-K-factor")
o.n3KFactor = std::stod(v());
else if (a == "--angular-momentum")
o.angularMomentum = std::stod(v());
else if (a == "--output")
@@ -238,6 +241,8 @@ Options Parse(int argc, char **argv) {
}
if (o.output.empty() || o.n < 1 || o.n >= 5 || o.maxNewton < 0 || o.maxLinear < 1 || o.restart < 1)
throw std::invalid_argument("Invalid options");
if (!std::isfinite(o.n3KFactor) || o.n3KFactor <= 0. || (o.n3KFactor != 1. && o.n != 3.))
throw std::invalid_argument("--n3-K-factor requires a positive factor and index exactly three");
if ((o.continuation || o.allowUnconvergedRestart) && o.restartSnapshot.empty())
throw std::invalid_argument("Continuation/restart permission requires --restart-snapshot");
if (!o.restartSnapshot.empty() && (o.densityDiagnostic || !o.probeState.empty() ||
@@ -767,6 +772,8 @@ int RunContext(Context &context, const Options &o, const Scales &scales) {
<< "\ncontext_gravity_schur_relaxation=" << (contextUsesGravitySchur ? o.schurRelaxation : 0.0)
<< "\nschur_correction_sweeps=" << o.schurCorrectionSweeps << "\nschur_relaxation=" << o.schurRelaxation
<< "\ncompiler=" << __VERSION__ << "\ncompiled=" << __DATE__ << ' ' << __TIME__ << '\n';
metadata << "n3_K_factor=" << o.n3KFactor << "\nseed_analytic_mass_estimate="
<< std::pow(o.n3KFactor, 1.5) << '\n';
metadata << "restart_snapshot=" << o.restartSnapshot.string() << "\ncontinuation=" << o.continuation
<< "\nallow_unconverged_restart=" << o.allowUnconvergedRestart
<< "\nbenchmark_trials=" << o.benchmarkTrials << '\n';
@@ -1393,7 +1400,13 @@ template <class Model> int Setup(Model model, fem::FEM f, const Options &o, cons
deformation::NodalRadialSurface{std::move(center)}, o, scales);
}
int Run(const Options &o) {
const auto scales = Derive(o.n);
auto scales = Derive(o.n);
// At n=3, rotation requires mass above the nonrotating mass at fixed K.
// This explicit physical-family control leaves M=1 while changing K.
// Rescale only the analytic seed's central density to retain R_reference=1;
// its mass is intentionally off-constraint and all fields remain unknowns.
scales.K *= o.n3KFactor;
scales.rho *= std::pow(o.n3KFactor, 1.5);
std::cout << "n=" << o.n << " K=" << scales.K << " rho_c=" << scales.rho << " J=" << o.angularMomentum << std::endl;
utils::Args args;
args.mesh_file = o.mesh;