experiment: replay captured candidates and run focused frozen probes
This commit is contained in:
@@ -18,6 +18,8 @@ import mean_field;
|
||||
#include "plateau_enthalpy_step_diagnostics.hpp"
|
||||
#include "plateau_physical_diagnostics.hpp"
|
||||
#include "plateau_preconditioner_diagnostics.hpp"
|
||||
#include "plateau_pressure_obstruction_diagnostics.hpp"
|
||||
#include "plateau_shape_curvature_diagnostics.hpp"
|
||||
|
||||
using namespace mean_field;
|
||||
namespace {
|
||||
@@ -26,9 +28,10 @@ struct Options {
|
||||
double n = 1., angularMomentum = 0., atol = 0., rtol = 1e-8, linearTolerance = .03;
|
||||
int maxNewton = 12, maxLinear = 200, restart = 40, probeRestart = 40;
|
||||
bool probes = false, noCentral = false;
|
||||
bool pressureProbe = false, shapeCurvature = false;
|
||||
std::vector<int> captureIterations;
|
||||
std::string mesh = "sandbox.smesh";
|
||||
std::filesystem::path output, probeState;
|
||||
std::filesystem::path output, probeState, probeDirection, replayCandidate;
|
||||
};
|
||||
Options Parse(int argc, char **argv) {
|
||||
Options o;
|
||||
@@ -63,6 +66,14 @@ Options Parse(int argc, char **argv) {
|
||||
o.rtol = std::stod(v());
|
||||
else if (a == "--probe-state")
|
||||
o.probeState = v();
|
||||
else if (a == "--probe-direction")
|
||||
o.probeDirection = v();
|
||||
else if (a == "--replay-candidate")
|
||||
o.replayCandidate = v();
|
||||
else if (a == "--pressure-probe")
|
||||
o.pressureProbe = true;
|
||||
else if (a == "--shape-curvature")
|
||||
o.shapeCurvature = true;
|
||||
else if (a == "--probes")
|
||||
o.probes = true;
|
||||
else if (a == "--no-central")
|
||||
@@ -87,6 +98,10 @@ Options Parse(int argc, char **argv) {
|
||||
throw std::invalid_argument("Invalid options");
|
||||
if (o.probeRestart != 40 && o.probeRestart != 160)
|
||||
throw std::invalid_argument("--probe-restart must be 40 or 160");
|
||||
if ((o.pressureProbe || o.shapeCurvature) && (o.probeState.empty() || o.probeDirection.empty()))
|
||||
throw std::invalid_argument("Focused probes require --probe-state and --probe-direction");
|
||||
if ((!o.probeDirection.empty() || !o.replayCandidate.empty()) && o.probeState.empty())
|
||||
throw std::invalid_argument("A supplied direction or candidate requires --probe-state");
|
||||
if (std::filesystem::exists(o.output))
|
||||
throw std::runtime_error("Output directory already exists");
|
||||
std::filesystem::create_directories(o.output);
|
||||
@@ -125,6 +140,101 @@ void SaveVector(const std::filesystem::path &p, const mfem::Vector &v) {
|
||||
s << v.Size() << '\n';
|
||||
v.Print(s, 1);
|
||||
}
|
||||
mfem::Vector LoadVector(const std::filesystem::path &path, int expectedSize) {
|
||||
std::ifstream input(path);
|
||||
int count = -1;
|
||||
input >> count;
|
||||
if (!input || count != expectedSize)
|
||||
throw std::runtime_error("Snapshot size mismatch: " + path.string());
|
||||
mfem::Vector result(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
input >> result(i);
|
||||
if (!input || !std::isfinite(result(i)))
|
||||
throw std::runtime_error("Invalid snapshot: " + path.string());
|
||||
}
|
||||
std::string extra;
|
||||
if (input >> extra)
|
||||
throw std::runtime_error("Unexpected trailing snapshot data: " + path.string());
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class State>
|
||||
void FocusedProbes(State &s, const fem::FEM &f, const Options &o, const mfem::Vector &physicalBase) {
|
||||
mfem::Vector base;
|
||||
s.normalizedOperator->NormalizeState(physicalBase, base);
|
||||
auto restore = [&]() {
|
||||
s.trialNormalizedState = base;
|
||||
if (!s.PrepareTrial())
|
||||
throw std::runtime_error("Focused probe base is inadmissible");
|
||||
};
|
||||
restore();
|
||||
const mfem::Vector residual(s.trialNormalizedResidual);
|
||||
SaveVector(o.output / "frozen_physical_base.txt", physicalBase);
|
||||
SaveVector(o.output / "frozen_normalized_base.txt", base);
|
||||
SaveVector(o.output / "frozen_normalized_residual.txt", residual);
|
||||
auto layout = File(o.output / "layout.csv");
|
||||
layout << "kind,block,offset,size,scale\n";
|
||||
for (const auto &b : s.Problem().GetManifest().residualBlocks())
|
||||
layout << "residual," << b.stableId << ',' << b.offset << ',' << b.size << ',' << b.scale << '\n';
|
||||
for (const auto &b : s.Problem().GetManifest().valueBlocks())
|
||||
layout << "value," << b.stableId << ',' << b.offset << ',' << b.size << ',' << b.scale << '\n';
|
||||
auto checks = File(o.output / "frozen_input_checks.csv");
|
||||
checks << "metric,value\nbase_residual_norm," << residual.Norml2() << '\n';
|
||||
const auto capturedBase = o.probeState.parent_path() / "normalized_base.txt";
|
||||
if (std::filesystem::is_regular_file(capturedBase)) {
|
||||
mfem::Vector difference = LoadVector(capturedBase, base.Size());
|
||||
difference -= base;
|
||||
checks << "captured_normalized_base_difference," << difference.Norml2() << '\n';
|
||||
if (difference.Norml2() > 64. * std::numeric_limits<double>::epsilon() * std::max(1., base.Norml2()))
|
||||
throw std::runtime_error("Frozen normalization disagrees with the captured base");
|
||||
}
|
||||
const auto capturedResidual = o.probeState.parent_path() / "normalized_residual.txt";
|
||||
if (std::filesystem::is_regular_file(capturedResidual)) {
|
||||
mfem::Vector difference = LoadVector(capturedResidual, residual.Size());
|
||||
difference -= residual;
|
||||
checks << "captured_residual_difference," << difference.Norml2() << '\n';
|
||||
}
|
||||
if (!o.replayCandidate.empty()) {
|
||||
s.trialNormalizedState = LoadVector(o.replayCandidate, base.Size());
|
||||
const auto prepared = s.PrepareTrial();
|
||||
auto replay = File(o.output / "replayed_candidate.csv");
|
||||
replay << "admissible,reason,stage,eos_code,minimum_jacobian,residual_norm\n";
|
||||
if (prepared)
|
||||
replay << "1,-1,-1,-1," << prepared->minimumJacobianDeterminant << ','
|
||||
<< s.trialNormalizedResidual.Norml2() << '\n';
|
||||
else
|
||||
replay << "0," << int(prepared.error().reason) << ',' << int(prepared.error().stage) << ','
|
||||
<< int(prepared.error().thermodynamicErrorCode) << ','
|
||||
<< prepared.error().minimumJacobianDeterminant << ",nan\n";
|
||||
restore();
|
||||
}
|
||||
if (!o.probeDirection.empty()) {
|
||||
const auto direction = LoadVector(o.probeDirection, base.Size());
|
||||
mfem::Vector action(base.Size());
|
||||
restore();
|
||||
s.normalizedOperator->Mult(direction, action);
|
||||
SaveVector(o.output / "probe_normalized_correction.txt", direction);
|
||||
checks << "direction_norm," << direction.Norml2() << "\naction_norm," << action.Norml2() << '\n';
|
||||
action += residual;
|
||||
checks << "linear_defect_norm," << action.Norml2() << "\nlinear_defect_relative,"
|
||||
<< action.Norml2() / std::max(residual.Norml2(), 1e-300) << '\n';
|
||||
checks.flush();
|
||||
s.normalizedCorrection = direction;
|
||||
auto bounds = File(o.output / "frozen_enthalpy_bound.csv");
|
||||
bounds << "metric,value\n";
|
||||
for (const auto &[key, value] : experiment::plateau_diagnostics::MeasureEnthalpyStep(s, f, o.n, &physicalBase))
|
||||
bounds << key << ',' << value << '\n';
|
||||
bounds.flush();
|
||||
if (o.pressureProbe)
|
||||
experiment::plateau_diagnostics::ProbePressureObstruction(s, f, o.n, base, direction, o.output);
|
||||
if (o.shapeCurvature)
|
||||
experiment::plateau_diagnostics::ProbeShapeCurvature(s, f, o.n, base, direction, o.output);
|
||||
}
|
||||
restore();
|
||||
mfem::Vector difference(s.trialNormalizedResidual);
|
||||
difference -= residual;
|
||||
checks << "final_restoration_residual_difference," << difference.Norml2() << '\n';
|
||||
}
|
||||
|
||||
template <class State>
|
||||
void FrozenProbes(State &s, const fem::FEM &f, const Options &o, const mfem::Vector *physicalBase = nullptr) {
|
||||
@@ -240,7 +350,7 @@ template <class Context> int RunContext(Context &context, const Options &o, cons
|
||||
metadata << "n=" << o.n << "\nK=" << scales.K << "\nrho_c=" << scales.rho << "\nJ=" << o.angularMomentum
|
||||
<< "\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=direct_mfem_fgmres_cold"
|
||||
<< "\nfrozen_probe_backend=" << (o.probeDirection.empty() ? "direct_mfem_fgmres_cold" : "supplied_direction_no_linear_solve")
|
||||
<< "\nlinear_tol=" << o.linearTolerance << "\nmax_linear=" << o.maxLinear
|
||||
<< "\nmax_newton=" << o.maxNewton << "\natol=" << o.atol << "\nrtol=" << o.rtol
|
||||
<< "\ncompiler=" << __VERSION__ << "\ncompiled=" << __DATE__ << ' ' << __TIME__ << '\n';
|
||||
@@ -249,24 +359,23 @@ template <class Context> int RunContext(Context &context, const Options &o, cons
|
||||
if (o.maxNewton != 0)
|
||||
throw std::invalid_argument("--probe-state requires --max-newton 0");
|
||||
metadata << "probe_state=" << o.probeState << '\n';
|
||||
if (!o.probeDirection.empty())
|
||||
metadata << "probe_direction=" << o.probeDirection << '\n';
|
||||
if (!o.replayCandidate.empty())
|
||||
metadata << "replay_candidate=" << o.replayCandidate << '\n';
|
||||
metadata << "pressure_probe=" << o.pressureProbe << "\nshape_curvature=" << o.shapeCurvature << '\n';
|
||||
metadata.flush();
|
||||
solver::detail::StellarEquilibriumContextDiagnostics::WithState(context, [&](auto &s, const fem::FEM &f) {
|
||||
std::ifstream input(o.probeState);
|
||||
int count = 0;
|
||||
input >> count;
|
||||
if (count != s.AcceptedPhysicalState().Size())
|
||||
throw std::runtime_error("Snapshot size mismatch");
|
||||
mfem::Vector snapshot(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
input >> snapshot(i);
|
||||
if (!input || !std::isfinite(snapshot(i)))
|
||||
throw std::runtime_error("Invalid snapshot");
|
||||
}
|
||||
const auto snapshot = LoadVector(o.probeState, s.AcceptedPhysicalState().Size());
|
||||
s.normalizedOperator->NormalizeState(snapshot, s.trialNormalizedState);
|
||||
auto prep = s.PrepareTrial();
|
||||
if (!prep)
|
||||
throw std::runtime_error("Snapshot is inadmissible");
|
||||
std::cout << "Snapshot F=" << s.trialNormalizedResidual.Norml2() << std::endl;
|
||||
if (!o.probeDirection.empty() || !o.replayCandidate.empty()) {
|
||||
FocusedProbes(s, f, o, snapshot);
|
||||
return;
|
||||
}
|
||||
experiment::plateau_diagnostics::InspectPreconditioner(s, o.output);
|
||||
FrozenProbes(s, f, o, &snapshot);
|
||||
});
|
||||
|
||||
@@ -135,3 +135,46 @@ Check a completed endpoint with
|
||||
This gates strict recorded solver convergence and all eight finite virial errors
|
||||
at 1e-5, while reporting local field errors separately. See
|
||||
`check_plateau_physics_README.md` for the exit codes and interpretation limits.
|
||||
|
||||
## Pressure obstruction and shape curvature (September 17)
|
||||
|
||||
These switches belong only to this experiment executable; no production model or
|
||||
solver options are added.
|
||||
|
||||
`--capture-iterations 2,7,11` copies the selected zero-based Newton iteration's
|
||||
physical/normalized base, residual, and exact first-trial candidate from observer
|
||||
spans into `capture_N/`. It reconstructs the normalized direction as
|
||||
`(candidate - base) / first_trial_alpha`. `capture.txt` records the step, observed
|
||||
rejection, reconstruction error, and a heuristic subtraction-roundoff scale.
|
||||
This is not a direct copy of the solver's internal correction. Prefer an onset
|
||||
capture whose first step is large for derivative measurements; retain the exact
|
||||
candidate for unambiguous replay even when a late direction loses digits.
|
||||
No operator or preconditioner is evaluated from the observer, and no accepted
|
||||
state is changed. Compare non-timing trajectory columns and final-state hashes
|
||||
against the control to verify that capture is observational.
|
||||
|
||||
A focused frozen investigation bypasses both cold Krylov solves:
|
||||
|
||||
```sh
|
||||
./cmake-build-release-homebrew/plateau_diagnostic \
|
||||
--index 1 --angular-momentum 0.1 --no-central --max-newton 0 \
|
||||
--probe-state /absolute/path/to/capture_2/physical_base.txt \
|
||||
--probe-direction /absolute/path/to/capture_2/normalized_direction.txt \
|
||||
--replay-candidate /absolute/path/to/capture_2/normalized_candidate.txt \
|
||||
--pressure-probe --shape-curvature \
|
||||
--output /absolute/path/to/new-focused-results
|
||||
```
|
||||
|
||||
The state input is physical; direction and candidate inputs are normalized in the
|
||||
same recorded normalization. Mesh, model, field layout, and scaling must match the
|
||||
capture. If a sibling `normalized_base.txt` exists, its agreement with the newly
|
||||
normalized physical base is checked before probing. This check is not a complete
|
||||
model fingerprint. The runner hashes each explicit input plus every text/CSV/JSON
|
||||
output, including nested capture files. Exact replay logs root rejection reason,
|
||||
stage and EOS code; the EOS code has meaning only for thermodynamic rejections.
|
||||
|
||||
`frozen_input_checks.csv` records the current F, Jp+F defect, captured normalization
|
||||
agreement, and final restoration error. The two methodology notes describe the
|
||||
pressure-bound crossings and common-step vector Taylor decomposition. Every
|
||||
candidate remains uncommitted. The flags may be used separately to limit work.
|
||||
These are diagnostic outcomes, not new equilibrium-convergence or virial claims.
|
||||
|
||||
156
experiments/plateau_focused_cases_2026-09-17.json
Normal file
156
experiments/plateau_focused_cases_2026-09-17.json
Normal file
@@ -0,0 +1,156 @@
|
||||
[
|
||||
{
|
||||
"id": "n1_J0p10_iteration_2",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"1",
|
||||
"--angular-momentum",
|
||||
"0.1",
|
||||
"--no-central",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_2/physical_base.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_2/normalized_direction.txt",
|
||||
"--replay-candidate",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_2/normalized_candidate.txt",
|
||||
"--pressure-probe",
|
||||
"--shape-curvature"
|
||||
],
|
||||
"notes": "Exact first candidate replay and frozen current-direction bound; onset/late boundary crossings, onset shape split."
|
||||
},
|
||||
{
|
||||
"id": "n1_J0p10_iteration_3",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"1",
|
||||
"--angular-momentum",
|
||||
"0.1",
|
||||
"--no-central",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_3/physical_base.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_3/normalized_direction.txt",
|
||||
"--replay-candidate",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_3/normalized_candidate.txt"
|
||||
],
|
||||
"notes": "Exact first candidate replay and frozen current-direction bound; onset/late boundary crossings, onset shape split."
|
||||
},
|
||||
{
|
||||
"id": "n1_J0p10_iteration_4",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"1",
|
||||
"--angular-momentum",
|
||||
"0.1",
|
||||
"--no-central",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_4/physical_base.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_4/normalized_direction.txt",
|
||||
"--replay-candidate",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_4/normalized_candidate.txt"
|
||||
],
|
||||
"notes": "Exact first candidate replay and frozen current-direction bound; onset/late boundary crossings, onset shape split."
|
||||
},
|
||||
{
|
||||
"id": "n1_J0p10_iteration_7",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"1",
|
||||
"--angular-momentum",
|
||||
"0.1",
|
||||
"--no-central",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_7/physical_base.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_7/normalized_direction.txt",
|
||||
"--replay-candidate",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_7/normalized_candidate.txt"
|
||||
],
|
||||
"notes": "Exact first candidate replay and frozen current-direction bound; onset/late boundary crossings, onset shape split."
|
||||
},
|
||||
{
|
||||
"id": "n1_J0p10_iteration_11",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"1",
|
||||
"--angular-momentum",
|
||||
"0.1",
|
||||
"--no-central",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_11/physical_base.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_11/normalized_direction.txt",
|
||||
"--replay-candidate",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1_J0p10_capture/capture_11/normalized_candidate.txt",
|
||||
"--pressure-probe"
|
||||
],
|
||||
"notes": "Exact first candidate replay and frozen current-direction bound; onset/late boundary crossings, onset shape split."
|
||||
},
|
||||
{
|
||||
"id": "n1p5_J0_iteration_1",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"1.5",
|
||||
"--angular-momentum",
|
||||
"0",
|
||||
"--no-central",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1p5_J0_capture/capture_1/physical_base.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1p5_J0_capture/capture_1/normalized_direction.txt",
|
||||
"--replay-candidate",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1p5_J0_capture/capture_1/normalized_candidate.txt",
|
||||
"--shape-curvature"
|
||||
],
|
||||
"notes": "First merit-limited cold step and following guarded step; shape split on onset direction."
|
||||
},
|
||||
{
|
||||
"id": "n1p5_J0_iteration_2",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"1.5",
|
||||
"--angular-momentum",
|
||||
"0",
|
||||
"--no-central",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1p5_J0_capture/capture_2/physical_base.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1p5_J0_capture/capture_2/normalized_direction.txt",
|
||||
"--replay-candidate",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/pressure_shape_2026-09-17/captures/n1p5_J0_capture/capture_2/normalized_candidate.txt"
|
||||
],
|
||||
"notes": "First merit-limited cold step and following guarded step; shape split on onset direction."
|
||||
},
|
||||
{
|
||||
"id": "n3_J0_seed_R160_curvature",
|
||||
"arguments": [
|
||||
"--index",
|
||||
"3",
|
||||
"--angular-momentum",
|
||||
"0",
|
||||
"--max-newton",
|
||||
"0",
|
||||
"--probe-state",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/numerical_campaign_2026-09-16/baseline_n3/n3_J0_seed_probe160/accepted_state.txt",
|
||||
"--probe-direction",
|
||||
"/Users/tboudreaux/.codex/.chatgpt-projects/g-p-6a6b3f2194ec8191bebcd59075897f1d/diagnostics/numerical_campaign_2026-09-16/baseline_n3/n3_J0_seed_probe160/probe_normalized_correction.txt",
|
||||
"--shape-curvature"
|
||||
],
|
||||
"notes": "Same saved n3 constrained seed and exact prior baseline R160 cold correction; no new linear solve."
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user