-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add derived quantities and calculations
- Loading branch information
Showing
3 changed files
with
199 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# File for holding calculations for derived quantities. The inputs should come from | ||
# basic inputs/boundary conditions (like injected power) or from synthetic diagnostic | ||
# outputs (like line average density). | ||
|
||
""" | ||
References | ||
[Eldon 2022 PPCF] D. Eldon, et al., Plasma Phys. Control. Fusion 64 (2022) 075002 https://doi.org/10.1088/1361-6587/ac6ff9 | ||
[Eich 2013 JNM] | ||
[Eich 2013 NF] | ||
""" | ||
|
||
export get_powr_from_dd, calc_conducted_loss_power, calc_loss_power, calc_heat_flux_width, calc_q_cyl | ||
|
||
function get_power_from_dd(dd::IMASDD.dd) | ||
time = dd.summary.time | ||
W = dd.summary.global_quantities.energy_mhd.value | ||
P_rad_core = dd.summary.global_quantities.power_radiated_inside_lcfs.value | ||
P_OHM = dd.summary.global_quantities.power_ohm.value | ||
P_NBI = dd.summary.heating_current_drive.power_nbi.value | ||
P_ECH = dd.summary.heating_current_drive.power_ec.value | ||
P_ICH = dd.summary.heating_current_drive.power_ic.value | ||
P_LH = dd.summary.heating_current_drive.power_lh.value | ||
P_fusion = dd.summary.fusion.power.value.value | ||
P_other = dd.summary.heating_current_drive.power_additional | ||
return time, W, P_rad_core, P_OHM, P_NBI, P_ECH, P_ICH, P_LH, P_fusion, P_other | ||
end | ||
|
||
function set_default_power_arrays(nt::Int64; P_NBI=nothing, P_ECH=nothing, P_ICH=nothing, P_LH=nothing, P_fusion=nothing, P_other=nothing) | ||
if P_NBI == nothing | ||
P_NBI = zeros(nt) | ||
end | ||
if P_ECH == nothing | ||
P_ECH = zeros(nt) | ||
end | ||
if P_ICH == nothing | ||
P_ICH = zeros(nt) | ||
end | ||
if P_LH == nothing | ||
P_LH = zeros(nt) | ||
end | ||
if P_fusion == nothing | ||
P_fusion = zeros(nt) | ||
end | ||
if P_other == nothing | ||
P_other = zeros(nt) | ||
end | ||
return P_NBI, P_ECH, P_ICH, P_LH, P_fusion, P_other | ||
end | ||
|
||
function calc_conducted_loss_power( | ||
time::Array{Float64}, | ||
W::Array{Float64}, | ||
P_OHM::Array{Float64}; | ||
P_NBI=nothing, | ||
P_ECH=nothing, | ||
P_ICH=nothing, | ||
P_LH=nothing, | ||
P_fusion=nothing, | ||
P_other=nothing, | ||
)::Array{Float64} | ||
nt = length(time) | ||
P_NBI, P_ECH, P_ICH, P_LH, P_fusion, P_other = set_default_power_arrays(nt, P_NBI=P_NBI, P_ECH=P_ECH; P_ICH=P_ICH, P_LH=P_LH, P_fusion=P_fusion, P_other=P_other) | ||
dWdt = IMASDD.gradient(time, W) | ||
P_cond = [calc_conducted_loss_power(dWdt[i], P_OHM[i], P_NBI=P_NBI[i], P_ECH=P_ECH[i], P_ICH=P_ICH[i], P_LH=P_LH[i], P_fusion=P_fusion[i], P_other=P_other[i]) for i in 1:nt] | ||
return P_cond | ||
end | ||
|
||
function calc_conducted_loss_power(dWdt::Float64, P_OHM::Float64; P_NBI::Float64=0.0, P_ECH::Float64=0.0, P_ICH::Float64=0.0, P_LH::Float64=0.0, P_fusion::Float64=0.0, P_other::Float64=0.0)::Float64 | ||
P_input = P_NBI + P_OHM + P_ECH + P_ICH + P_LH + P_fusion + P_other | ||
P_cond = P_input - dWdt | ||
return P_cond | ||
end | ||
|
||
function calc_loss_power(time::Array{Float64}, W::Array{Float64}, P_rad_core::Array{Float64}, P_OHM::Array{Float64}; P_NBI=nothing, P_ECH=nothing, P_ICH=nothing, P_LH=nothing, P_fusion=nothing, P_other=nothing)::Array{Float64} | ||
dWdt = IMASDD.gradient(time, W) | ||
nt = length(time) | ||
P_NBI, P_ECH, P_ICH, P_LH, P_fusion, P_other = set_default_power_arrays(nt, P_NBI=P_NBI, P_ECH=P_ECH; P_ICH=P_ICH, P_LH=P_LH, P_fusion=P_fusion, P_other=P_other) | ||
P_cond = [calc_conducted_loss_power(dWdt[i], P_OHM[i], P_NBI=P_NBI[i], P_ECH=P_ECH[i], P_ICH=P_ICH[i], P_LH=P_LH[i], P_fusion=P_fusion[i], P_other=P_other[i]) for i in 1:nt] | ||
P_SOL = P_cond - P_rad_core | ||
return P_SOL | ||
end | ||
|
||
function calc_loss_power(dWdt::Float64, P_rad_core::Float64, P_OHM::Float64; P_NBI::Float64=0.0, P_ECH::Float64=0.0, P_ICH::Float64=0.0, P_LH::Float64=0.0, P_fusion::Float64=0.0, P_other::Float64=0.0)::Float64 | ||
P_cond = calc_conducted_loss_power(dWdt, P_OHM, P_NBI=P_NBI, P_ECH=P_ECH; P_ICH=P_ICH, P_LH=P_LH, P_fusion=P_fusion, P_other=P_other) | ||
P_SOL = P_cond - P_rad_core | ||
return P_SOL | ||
end | ||
|
||
function calc_loss_power(dd::IMASDD.dd)::Array{Float64} | ||
time, W, P_rad_core, P_OHM, P_NBI, P_ECH, P_ICH, P_LH, P_fusion, P_other = get_power_from_dd(dd) | ||
P_SOL = calc_loss_power(time, W, P_rad_core, P_OHM, P_NBI=P_NBI, P_ECH=P_ECH; P_ICH=P_ICH, P_LH=P_LH, P_fusion=P_fusion, P_other=P_other) | ||
return P_SOL | ||
end | ||
|
||
function calc_q_cyl(B_ϕ_axis::Float64, Iₚ::Float64, aₘᵢₙₒᵣ::Float64, R_geo::Float64, κ::Float64)::Float64 | ||
# Copied from Equation 19 of [Eldon 2022 PPCF] | ||
ε = aₘᵢₙₒᵣ / R_geo | ||
μ₀ = π * 4e-7 # H / m | ||
q_cyl = π * aₘᵢₙₒᵣ * ε * B_ϕ_axis / (μ₀ * Iₚ) * (1 + κ^2) | ||
return q_cyl # unitless | ||
end | ||
|
||
function calc_heat_flux_width(dd::IMASDD.dd)::Array{Float64} | ||
B_ϕ_axis = dd.equilibrium.time_slice[:].global_quantities.magnetic_axis.b_field_tor | ||
P_SOL = calc_loss_power(dd) | ||
R_geo = dd.summary.boundary.geometric_axis_r.value | ||
aₘᵢₙₒᵣ = dd.summary.boundary.minor_radius.value | ||
κ = dd.summary.boundary.elongation.value | ||
Iₚ = dd.summary.global_quantities.ip.value | ||
λq = calc_heat_flux_width.(B_ϕ_axis, P_SOL, R_geo, aₘᵢₙₒᵣ, κ, Iₚ) | ||
return λq | ||
end | ||
|
||
function calc_heat_flux_width(B_ϕ_axis::Float64, P_SOL::Float64, R_geo::Float64, aₘᵢₙₒᵣ::Float64, κ::Float64, Iₚ::Float64)::Float64 | ||
q_cyl = calc_q_cyl(B_ϕ_axis, Iₚ, aₘᵢₙₒᵣ, R_geo, κ) # Unitless | ||
λq = calc_heat_flux_width(B_ϕ_axis, P_SOL, R_geo, q_cyl) | ||
return λq | ||
end | ||
|
||
function calc_heat_flux_width(B_ϕ_axis::Float64, P_SOL::Float64, R_geo::Float64, q_cyl::Float64)::Float64 | ||
# Copied from Equation 18 of [Eldon 2022 PPCF] which came from [Eich 2013 JNM] and [Eich 2013 NF] | ||
λq = 0.86 * abs(B_ϕ_axis)^(-0.8) * abs(q_cyl)^(1.11) * abs(P_SOL)^0.11 * abs(R_geo)^(-0.13) | ||
return λq | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters