From a28531bd3ee7ce145e2ffb04b03fe475a7751c60 Mon Sep 17 00:00:00 2001 From: d-burg Date: Fri, 28 Aug 2026 01:41:59 -0400 Subject: [PATCH 1/2] InnerLayer.SLAYER - TEST - Pin the reverse-shear invariance of the layer magnitudes The shear-magnitude fix has no test coverage: every SLAYER testset builds its parameters at sval_r = 1.0, and no shipped deck has a reverse-shear rational surface, so a regression would be silent. Assert that a negative-shear surface reproduces its positive-shear mirror bit-identically across every normalized layer quantity, that sval_r keeps its sign in the diagnostic, and that the Lundquist number stays positive so the S^(1/3) that used to raise a DomainError evaluates. Co-Authored-By: Claude Opus 5 --- test/runtests_slayer_params.jl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/runtests_slayer_params.jl b/test/runtests_slayer_params.jl index 330ba7297..2ece4abd2 100644 --- a/test/runtests_slayer_params.jl +++ b/test/runtests_slayer_params.jl @@ -165,4 +165,31 @@ @test_throws ArgumentError r_based_shear(0.5, 2.0, 1.0, 0.0) @test_throws ArgumentError r_based_shear(0.5, 0.0, 1.0, 0.5) end + + @testset "Test 3: reverse-shear invariance" begin + # The layer timescales and widths depend on |dq/dr|, not its sign, so a + # negative-shear rational surface must reduce to its positive-shear mirror. + # Only the recorded `sval_r` diagnostic keeps the sign. `dc_type=:lar` + # with a nonzero `dr_val` exercises the Wd iteration and the critical-Δ + # square roots as well as tau_h. + base = _ref_kwargs(; dr_val=-0.1, dc_type=:lar) + pos = slayer_parameters(; base...) + neg = slayer_parameters(; merge(base, (; sval_r=-1.0))...) + + # The sign survives where it is a diagnostic, not a magnitude. + @test pos.sval_r == 1.0 + @test neg.sval_r == -1.0 + + # Every normalized layer quantity is bit-identical: abs(-1.0) === 1.0, + # so the whole downstream chain reproduces exactly. + for f in (:tau, :lu, :c_beta, :D_norm, :P_perp, :P_tor, :Q_e, :Q_i, + :iota_e, :tauk, :tau_r, :delta_n, :eta, :d_beta, :dc_tmp) + @test getfield(neg, f) == getfield(pos, f) + end + + # tau_h > 0 keeps the Lundquist number positive, so the S^(1/3) that + # used to raise a DomainError on a reverse-shear surface now evaluates. + @test neg.lu > 0 + @test neg.tauk > 0 + end end From 42ec8dbfe3eb3315ebba11d2167766b445638306 Mon Sep 17 00:00:00 2001 From: d-burg Date: Fri, 28 Aug 2026 13:23:33 -0400 Subject: [PATCH 2/2] InnerLayer.SLAYER - MINOR - State the reverse-shear test comments as invariants Co-Authored-By: Claude Fable 5 --- test/runtests_slayer_params.jl | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/test/runtests_slayer_params.jl b/test/runtests_slayer_params.jl index 2ece4abd2..bab15e393 100644 --- a/test/runtests_slayer_params.jl +++ b/test/runtests_slayer_params.jl @@ -167,11 +167,10 @@ end @testset "Test 3: reverse-shear invariance" begin - # The layer timescales and widths depend on |dq/dr|, not its sign, so a - # negative-shear rational surface must reduce to its positive-shear mirror. - # Only the recorded `sval_r` diagnostic keeps the sign. `dc_type=:lar` - # with a nonzero `dr_val` exercises the Wd iteration and the critical-Δ - # square roots as well as tau_h. + # The layer timescales and widths depend on |dq/dr|, not its sign: a negative-shear + # surface must reduce to its positive-shear mirror, with only the recorded sval_r + # diagnostic keeping the sign. dc_type=:lar with nonzero dr_val exercises the Wd + # iteration and the critical-Δ square roots as well as tau_h. base = _ref_kwargs(; dr_val=-0.1, dc_type=:lar) pos = slayer_parameters(; base...) neg = slayer_parameters(; merge(base, (; sval_r=-1.0))...) @@ -187,8 +186,7 @@ @test getfield(neg, f) == getfield(pos, f) end - # tau_h > 0 keeps the Lundquist number positive, so the S^(1/3) that - # used to raise a DomainError on a reverse-shear surface now evaluates. + # tau_h > 0 keeps the Lundquist number positive, so S^(1/3) is defined on reverse shear. @test neg.lu > 0 @test neg.tauk > 0 end