Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/extract/objectives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,35 @@ end
# ========================= #
const ObjectiveFunctionsLibrary = OrderedCollections.OrderedDict{Symbol,ObjectiveFunction}()

function calculate_greenwald_fraction(dd::IMAS.dd)
try
eqt = dd.equilibrium.time_slice[]
cp1d = dd.core_profiles.profiles_1d[]
ne_line = IMAS.ne_line(eqt, cp1d)
Ip_MA = eqt.global_quantities.ip / 1e6 # Convert to MA
a_minor = eqt.boundary.minor_radius # Get minor radius from equilibrium
n_Greenwald = (Ip_MA / (π * a_minor^2)) * 1e20 # Greenwald limit [m⁻³]
return ne_line / n_Greenwald
catch
return 0.0
end
end

function calculate_bootstrap_fraction(dd::IMAS.dd)
try
I_bootstrap = @ddtime(dd.summary.global_quantities.current_bootstrap.value)
I_p = dd.equilibrium.time_slice[].global_quantities.ip
return I_bootstrap / I_p
catch
return 0.0
end
end

function update_ObjectiveFunctionsLibrary!()
empty!(ObjectiveFunctionsLibrary)
#! format: off

# Original FUSE objectives
ObjectiveFunction(:min_levelized_CoE, "\$/kWh", dd -> dd.costing.levelized_CoE, -Inf)
ObjectiveFunction(:min_log10_levelized_CoE, "log₁₀(\$/kW)", dd -> log10(dd.costing.levelized_CoE), -Inf)
ObjectiveFunction(:min_capital_cost, "\$B", dd -> dd.costing.cost_direct_capital.cost / 1E3, -Inf)
Expand All @@ -97,6 +123,14 @@ function update_ObjectiveFunctionsLibrary!()
ObjectiveFunction(:min_βn, "", dd -> dd.equilibrium.time_slice[].global_quantities.beta_normal, -Inf)
ObjectiveFunction(:min_R0, "m", dd -> dd.equilibrium.time_slice[].boundary.geometric_axis.r, -Inf)
ObjectiveFunction(:max_zeff, "", dd -> @ddtime(dd.summary.volume_average.zeff.value), Inf)

# New physics objectives for my studies
ObjectiveFunction(:max_βp, "", dd -> dd.equilibrium.time_slice[].global_quantities.beta_pol, Inf)
ObjectiveFunction(:max_h98, "", dd -> @ddtime(dd.summary.global_quantities.h_98.value), Inf)
ObjectiveFunction(:max_tau_e, "s", dd -> @ddtime(dd.summary.global_quantities.tau_energy.value), Inf)
ObjectiveFunction(:max_fbs, "", dd -> calculate_bootstrap_fraction(dd), Inf)
ObjectiveFunction(:max_greenwald_fraction, "", dd -> calculate_greenwald_fraction(dd), Inf)

#! format: on
return ObjectiveFunctionsLibrary
end
Expand Down
16 changes: 16 additions & 0 deletions src/get_from.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ function get_from(dd::IMAS.dd{T}, what::Val{:zeff_ped}, from_where::Symbol, rho_
return error("`get_from(dd, $what, Val(:$from_where))` doesn't exist yet")
end

# ne_sep [m^-3]
function get_from(dd::IMAS.dd{T}, what::Val{:ne_sep}, from_where::Symbol; time0::Float64=dd.global_time)::T where {T<:Real}
if from_where == :core_profiles
cp1d = dd.core_profiles.profiles_1d[time0]
return cp1d.electrons.density_thermal[end]
elseif from_where == :pulse_schedule
if !ismissing(dd.pulse_schedule.density_control.n_e_separatrix, :reference)
return get_time_array(dd.pulse_schedule.density_control.n_e_separatrix, :reference, time0, :linear)
end
error("`get_from(dd, $what, Val(:$from_where))` does not have data")
end
return error("`get_from(dd, $what, Val(:$from_where))` doesn't exist yet")
end

Base.Docs.@doc """
get_from(dd::IMAS.dd, what::Symbol, from_where::Symbol; time0::Float64=dd.global_time)

Expand All @@ -141,6 +155,8 @@ Supported quantities for `what`:
- Possible sources (`from_where`): `:core_profiles`, `:summary`, `:pulse_schedule`
- `:zeff_ped` - Effective charge at the pedestal [-]
- Possible sources (`from_where`): `:core_profiles`, `:summary`, `:pulse_schedule`
- `:ne_sep` - Electron density at the separatrix [m^-3]
- Possible sources (`from_where`): `:core_profiles`, `:pulse_schedule`

`time0` defines the time point at which to retrieve the value, default is `dd.global_time`.

Expand Down