From 457d112c31d84f13cd781c575fa4a5dd045c44d6 Mon Sep 17 00:00:00 2001 From: StuartBenjamin Date: Tue, 13 Oct 2026 04:41:29 -0700 Subject: [PATCH] sawteeth_source!: exclude_indexes keyword Defaults to IMASdd.index_no_sawtooth, so callers can choose which sources are flattened instead of editing that global list. Co-Authored-By: Claude Opus 5.5 --- src/physics/sources.jl | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/physics/sources.jl b/src/physics/sources.jl index f9170485..c610146a 100644 --- a/src/physics/sources.jl +++ b/src/physics/sources.jl @@ -566,22 +566,23 @@ push!(document[Symbol("Physics sources")], :total_radiation_sources) """ - sawteeth_source!(dd::IMAS.DD; qmin_desired::Union{Float64, Nothing}=nothing, flat_factor::Real=0.5) + sawteeth_source!(dd::IMAS.DD; qmin_desired::Union{Float64, Nothing}=nothing, flat_factor::Real=0.5, exclude_indexes::AbstractVector{Int}=IMASdd.index_no_sawtooth) Model sawteeth by flattening all sources where abs(q) drops below qmin_desired. - `qmin_desired`: Safety factor threshold for sawteeth inversion. If `nothing`, uses `dd.sawteeth.diagnostics.rho_tor_norm_inversion` if available, otherwise falls back to `1.0` - `flat_factor`: Relaxation factor for flattening, from 0.0 (no change) to 1.0 (full flattening) + - `exclude_indexes`: Source indexes that are not flattened (default: those that come from profiles, not external drive) """ -function sawteeth_source!(dd::IMAS.DD; qmin_desired::Union{Float64, Nothing}=nothing, flat_factor::Real=0.5) +function sawteeth_source!(dd::IMAS.DD; qmin_desired::Union{Float64, Nothing}=nothing, flat_factor::Real=0.5, exclude_indexes::AbstractVector{Int}=IMASdd.index_no_sawtooth) if qmin_desired === nothing if !ismissing(dd.sawteeth.diagnostics, :rho_tor_norm_inversion) rho0 = @ddtime(dd.sawteeth.diagnostics.rho_tor_norm_inversion) - return sawteeth_source!(dd, rho0; flat_factor) + return sawteeth_source!(dd, rho0; flat_factor, exclude_indexes) else - return sawteeth_source!(dd; qmin_desired=1.0, flat_factor) + return sawteeth_source!(dd; qmin_desired=1.0, flat_factor, exclude_indexes) end else cp1d = dd.core_profiles.profiles_1d[] @@ -589,29 +590,30 @@ function sawteeth_source!(dd::IMAS.DD; qmin_desired::Union{Float64, Nothing}=not # update core_sources with sawteeth i_qdes = findlast(q -> (abs(q) < qmin_desired), cp1d.q) #rho_qdes = (i_qdes === nothing) ? 0.0 : cp1d.grid.rho_tor_norm[i_qdes] - return sawteeth_source!(dd, i_qdes; flat_factor) + return sawteeth_source!(dd, i_qdes; flat_factor, exclude_indexes) end end -function sawteeth_source!(dd::IMAS.DD{T}, ::Nothing; flat_factor::Real=0.5) where {T<:Real} +function sawteeth_source!(dd::IMAS.DD{T}, ::Nothing; flat_factor::Real=0.5, exclude_indexes::AbstractVector{Int}=IMASdd.index_no_sawtooth) where {T<:Real} # no inversion radius, so call with rho0 = 0.0 - return sawteeth_source!(dd, 0.0; flat_factor) + return sawteeth_source!(dd, 0.0; flat_factor, exclude_indexes) end -function sawteeth_source!(dd::IMAS.DD{T}, i_qdes::Int; flat_factor::Real=0.5) where {T<:Real} +function sawteeth_source!(dd::IMAS.DD{T}, i_qdes::Int; flat_factor::Real=0.5, exclude_indexes::AbstractVector{Int}=IMASdd.index_no_sawtooth) where {T<:Real} cp1d = dd.core_profiles.profiles_1d[] - return sawteeth_source!(dd, cp1d.grid.rho_tor_norm[i_qdes]; flat_factor) + return sawteeth_source!(dd, cp1d.grid.rho_tor_norm[i_qdes]; flat_factor, exclude_indexes) end """ - sawteeth_source!(dd::IMAS.DD{T}, rho0::T; flat_factor::Real=0.5) where {T<:Real} + sawteeth_source!(dd::IMAS.DD{T}, rho0::T; flat_factor::Real=0.5, exclude_indexes::AbstractVector{Int}=IMASdd.index_no_sawtooth) where {T<:Real} Model sawteeth by flattening all sources within the inversion radius rho0 - `rho0`: Normalized toroidal flux coordinate of the inversion radius - `flat_factor`: Relaxation factor for flattening (0 = no change, 1 = full flattening) + - `exclude_indexes`: Source indexes that are not flattened (default: those that come from profiles, not external drive) """ -function sawteeth_source!(dd::IMAS.DD{T}, rho0::T; flat_factor::Real=0.5) where {T<:Real} +function sawteeth_source!(dd::IMAS.DD{T}, rho0::T; flat_factor::Real=0.5, exclude_indexes::AbstractVector{Int}=IMASdd.index_no_sawtooth) where {T<:Real} @assert rho0 <= 1.0 cp1d = dd.core_profiles.profiles_1d[] @@ -638,7 +640,7 @@ function sawteeth_source!(dd::IMAS.DD{T}, rho0::T; flat_factor::Real=0.5) where # identify sawteeth inversion radius if rho0 > 0.0 # exclude sources that come from profiles, not external drive - total_source1d = total_sources(dd.core_sources, cp1d; time0=dd.global_time, exclude_indexes=IMASdd.index_no_sawtooth) + total_source1d = total_sources(dd.core_sources, cp1d; time0=dd.global_time, exclude_indexes) fill!(source1d, total_source1d) else # this will return an empty source