Skip to content

Commit 044de7e

Browse files
authored
KineticForces - BUGFIX! - Give the energy integration its own tolerances (#392)
2 parents 9a98f7c + 1a9b376 commit 044de7e

4 files changed

Lines changed: 37 additions & 11 deletions

File tree

src/KineticForces/CalculatedKineticMatrices.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ function compute_calculated_kinetic_matrices(
136136
z_s, m_s, kf_ctrl.wdfac, kf_ctrl.divxfac,
137137
el_s, equil, intr_t, prof_s;
138138
nutype=kf_ctrl.nutype, f0type=kf_ctrl.f0type, nufac=kf_ctrl.nufac,
139-
atol_xlmda=kf_ctrl.atol_xlmda, rtol_xlmda=kf_ctrl.rtol_xlmda
139+
atol_xlmda=kf_ctrl.atol_xlmda, rtol_xlmda=kf_ctrl.rtol_xlmda,
140+
atol_x=kf_ctrl.atol_x, rtol_x=kf_ctrl.rtol_x,
141+
nested_tolerance_margin=kf_ctrl.nested_tolerance_margin
140142
)
141143
full_w .+= block_w
142144
full_t .+= block_t

src/KineticForces/Compute.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,9 @@ function integrate_psi_quadgk(
137137
tpsi!(thread_tpsi[tid], psi, n, l, zi, mi, wdfac, divxfac,
138138
electron, method, equil, thread_intrs[tid], kinetic_profiles;
139139
op_wmats=w,
140-
atol_xlmda=ctrl.atol_xlmda, rtol_xlmda=ctrl.rtol_xlmda)
140+
atol_xlmda=ctrl.atol_xlmda, rtol_xlmda=ctrl.rtol_xlmda,
141+
atol_x=ctrl.atol_x, rtol_x=ctrl.rtol_x,
142+
nested_tolerance_margin=ctrl.nested_tolerance_margin)
141143
harm_vals[ell_idx] = thread_tpsi[tid][]
142144
is_matrix_method && (harm_elems[ell_idx] .= w)
143145
end

src/KineticForces/KineticForcesStructs.jl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,20 @@ builds a second control for its differing tolerance).
121121
nn::Int = 1 # Toroidal mode number
122122
nl::Int = 1 # Bounce harmonic number
123123

124-
# Tolerances.
125-
# *_xlmda: shared tolerances for inner λ (pitch) and x (energy) integrations
126-
# *_psi: tolerances for outer ψ quadrature
127-
atol_xlmda::Float64 = 1e-8 # Absolute tolerance for inner pitch + energy integrations
128-
rtol_xlmda::Float64 = 1e-5 # Relative tolerance for inner pitch + energy integrations
124+
# Tolerances, outermost to innermost: ψ quadrature ⊃ λ (pitch) ⊃ x (energy).
125+
# Each level must be resolved more tightly than the one enclosing it, or the outer
126+
# integrator chases its integrand's own quadrature noise instead of converging.
127+
# *_xlmda: tolerances for the λ (pitch) integration
128+
# *_x: tolerances for the x (energy) integration nested inside it; NaN ⇒ derive as
129+
# nested_tolerance_margin × the pitch tolerances
130+
# *_psi: tolerances for the outer ψ quadrature
131+
atol_xlmda::Float64 = 1e-8 # Absolute tolerance for the inner pitch integration
132+
rtol_xlmda::Float64 = 1e-5 # Relative tolerance for the inner pitch integration
133+
atol_x::Float64 = NaN # Absolute tolerance for the energy integration (NaN ⇒ derived)
134+
rtol_x::Float64 = NaN # Relative tolerance for the energy integration (NaN ⇒ derived)
135+
# The pitch integrand IS the energy integral, so the energy level is resolved this much
136+
# tighter than the pitch level by default.
137+
nested_tolerance_margin::Float64 = 1e-2 # Factor relating derived energy tolerances to the pitch ones
129138
# rtol_psi is the primary convergence knob: ~2 significant figures matches the validity
130139
# of the NTV model approximations. Do not set it tighter than the noise floor of the
131140
# inner integrals (keep rtol_psi ≳ 10 × rtol_xlmda).

src/KineticForces/Torque.jl

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,14 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int,
3535
op_wmats::Union{Nothing,Array{ComplexF64,3}}=nothing,
3636
rex_override::Union{Nothing,Float64}=nothing,
3737
imx_override::Union{Nothing,Float64}=nothing,
38-
atol_xlmda::Float64=1e-9, rtol_xlmda::Float64=1e-6)
38+
atol_xlmda::Float64=1e-9, rtol_xlmda::Float64=1e-6,
39+
atol_x::Float64=NaN, rtol_x::Float64=NaN,
40+
nested_tolerance_margin::Float64=1e-2)
41+
42+
# The pitch integrand is itself the energy integral, so the energy level is resolved
43+
# tighter than the pitch level (explicit atol_x/rtol_x override the derived values).
44+
atol_energy = isnan(atol_x) ? nested_tolerance_margin * atol_xlmda : atol_x
45+
rtol_energy = isnan(rtol_x) ? nested_tolerance_margin * rtol_xlmda : rtol_x
3946

4047
# Enforce bounds
4148
if psi > 1
@@ -233,7 +240,7 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int,
233240
B_vpar=B_vpar,
234241
smat=smat_f, tmat=tmat_f, xmat=xmat_f,
235242
ymat=ymat_f, zmat=zmat_f,
236-
energy_atol=atol_xlmda, energy_rtol=rtol_xlmda,
243+
energy_atol=atol_energy, energy_rtol=rtol_energy,
237244
pitch_atol=atol_xlmda, pitch_rtol=rtol_xlmda,
238245
rex_override=rex_override, imx_override=imx_override)
239246
end
@@ -897,7 +904,9 @@ function compute_kinetic_matrices_at_psi!(
897904
electron::Bool, equil, intr::KineticForcesInternal,
898905
kinetic_profiles::Equilibrium.KineticProfileSplines;
899906
nutype::String="harmonic", f0type::String="maxwellian", nufac::Float64=1.0,
900-
atol_xlmda::Float64=1e-9, rtol_xlmda::Float64=1e-6)
907+
atol_xlmda::Float64=1e-9, rtol_xlmda::Float64=1e-6,
908+
atol_x::Float64=NaN, rtol_x::Float64=NaN,
909+
nested_tolerance_margin::Float64=1e-2)
901910

902911
# Bypass ψ > 1 (no kinetic contribution outside plasma)
903912
if psi > 1
@@ -906,13 +915,17 @@ function compute_kinetic_matrices_at_psi!(
906915
return nothing
907916
end
908917

918+
# See tpsi!: the energy integral is the pitch integrand, so it is resolved tighter.
919+
atol_energy = isnan(atol_x) ? nested_tolerance_margin * atol_xlmda : atol_x
920+
rtol_energy = isnan(rtol_x) ? nested_tolerance_margin * rtol_xlmda : rtol_x
921+
909922
state = _setup_surface_state(psi, zi, mi, electron,
910923
equil, intr, kinetic_profiles)
911924

912925
kinetic_energy_matrices_for_euler_lagrange!(
913926
kwmat, ktmat, state, psi, n, l, wdfac, intr;
914927
nutype, f0type, nufac,
915-
energy_atol=atol_xlmda, energy_rtol=rtol_xlmda,
928+
energy_atol=atol_energy, energy_rtol=rtol_energy,
916929
pitch_atol=atol_xlmda, pitch_rtol=rtol_xlmda)
917930

918931
return nothing

0 commit comments

Comments
 (0)