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
12 changes: 12 additions & 0 deletions src/expressions/dynamic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,18 @@ dyexp["pulse_schedule.ic.power.reference"] =
dyexp["pulse_schedule.lh.power.reference"] =
(time; lh, _...) -> sum(antenna.power.reference for antenna in lh.antenna)

#= ==== =#
# risk #
#= ==== =#
dyexp["risk.engineering.loss[:].risk"] =
(; loss, _...) -> (sum((fm.probability * fm.weight) for fm in loss.failure_mode) * loss.severity)

dyexp["risk.plasma.risk"] =
(; dd, _...) -> isempty(dd.risk.plasma) ? 0.0 : sum(loss.risk for loss in dd.risk.plasma.loss)

dyexp["risk.engineering.risk"] =
(; dd, _...) -> isempty(dd.risk.engineering) ? 0.0 : sum(loss.risk for loss in dd.risk.engineering.loss)

#= ====== =#
# limits #
#= ====== =#
Expand Down
5 changes: 4 additions & 1 deletion src/extract/extract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ function print_tiled(io::IO, xtract::AbstractDict{Symbol,ExtractFunction}; termi
end
end

function select_direct_captial_cost(dd::IMAS.dd, what::String)
function select_direct_capital_cost(dd::IMAS.dd, what::String)
for sys in dd.costing.cost_direct_capital.system
idx = findfirst(x -> x.name == what, sys.subsystem)
if !isnothing(idx)
Expand Down Expand Up @@ -380,6 +380,9 @@ function update_ExtractFunctionsLibrary!()
ExtractLibFunction(:costing, :blanket_of_total, "%", dd -> 100 * select_direct_captial_cost(dd,"blanket") / dd.costing.cost_direct_capital.cost)
ExtractLibFunction(:costing, :cryostat_of_total, "%", dd -> 100 * select_direct_captial_cost(dd,"cryostat") / dd.costing.cost_direct_capital.cost)

ExtractLibFunction(:risk, :total_engineering_risk, "\$M", dd -> dd.risk.engineering.risk)
ExtractLibFunction(:risk, :total_plasma_risk, "\$/kWh", dd -> dd.risk.plasma.risk)

#! format: on

return EFL
Expand Down
3 changes: 3 additions & 0 deletions src/extract/objectives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ 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)
ObjectiveFunction(:min_engineering_risk, "\$M", dd -> dd.risk.engineering.risk, -Inf)
ObjectiveFunction(:min_plasma_risk, "\$/kWh", dd -> dd.risk.plasma.risk, -Inf)

#! format: on
return ObjectiveFunctionsLibrary
end
Expand Down
97 changes: 97 additions & 0 deletions src/plot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,103 @@ end
end
end

# ==== #
# risk #
# ==== #

@recipe function plot_risk(rsk::IMAS.risk)
eng_loss = rsk.engineering.loss
eng_names = ["$(sys_loss.description)" for sys_loss in reverse(eng_loss)]
eng_risks = [sys_loss.risk for sys_loss in reverse(eng_loss)]
eng_perc = ["$(round(sys_loss.risk/sum(eng_risks)*100))%" for sys_loss in reverse(eng_loss)]

plasma_loss = rsk.plasma.loss
plasma_names = ["$(sys_loss.description)" for sys_loss in reverse(plasma_loss)]
plasma_risks = [sys_loss.risk for sys_loss in reverse(plasma_loss)]
plasma_perc = ["$(round(sys_loss.risk/sum(plasma_risks)*100))%" for sys_loss in reverse(plasma_loss)]

dd = parent(rsk)
direct_capital_cost = dd.costing.cost_direct_capital.cost
levelized_cost = dd.costing.levelized_CoE

size --> (800, 800)
layout := RecipesBase.@layout (2, 2)

@series begin
subplot := 1
seriestype := :bar
orientation := :horizontal
title := "Engineering risk" * " " * @sprintf("[Total = %.3g \$M]", sum(eng_risks))
titlefontsize := 10
ylim := (0, length(eng_risks))
label := ""
annotation := [(0.0, kk - 0.5, (" $x $(titlecase(n,strict=false))", :left, 8)) for (kk, (c, x, n)) in enumerate((collect(zip(eng_risks, eng_perc, eng_names))))]
annotationvalign := :center
label := ""
xticks := 0:round(maximum(eng_risks) / 4, digits = 1):round(maximum(eng_risks), digits = 1)
xlim := (0, maximum(eng_risks))
xlabel := "[\$M]"
showaxis := :x
yaxis := nothing
alpha := 0.5
linecolor := :match
color := PlotUtils.palette(:tab10)[1]
eng_names, eng_risks
end

@series begin
subplot := 2
seriestype := :bar
orientation := :horizontal
title := "Plasma risk" * " " * @sprintf("[Total = %.3g \$/kWh]", sum(plasma_risks))
titlefontsize := 10
ylim := (0, length(plasma_risks))
label := ""
annotation := [(0.0, kk - 0.5, (" $x $(titlecase(n,strict=false))", :left, 8)) for (kk, (c, x, n)) in enumerate((collect(zip(plasma_risks, plasma_perc, plasma_names))))]
annotationvalign := :center
label := ""
xticks := 0:round(maximum(plasma_risks) / 4, digits = 1):round(maximum(plasma_risks), digits = 1)
xlim := (0, maximum(plasma_risks))
xlabel := "[\$/kWh]"
showaxis := :x
yaxis := nothing
alpha := 0.5
linecolor := :match
color := PlotUtils.palette(:tab10)[2]
plasma_names, plasma_risks
end

@series begin
subplot := 3
seriestype := :bar
label := "Direct capital cost with error"
ylabel := "Direct capital cost (\$M)"
orientation := :vertical
legend := :bottomleft
title := "Error on direct capital cost"
alpha := 0.5
yerror := [rsk.engineering.risk]
color := PlotUtils.palette(:tab10)[1]
[""], [direct_capital_cost]
end

@series begin
subplot := 4
seriestype := :bar
label := "Levelized cost with error"
ylabel := "Levelized cost of electricity (\$/kWh)"
orientation := :vertical
legend := :bottomleft
title := "Error on levelized cost"
right_ylabel := "Levelized cost of electricity with error"
alpha := 0.5
yerror := [rsk.plasma.risk]
color := PlotUtils.palette(:tab10)[2]
[""], [levelized_cost]
end

end

# =========== #
# equilibrium #
# =========== #
Expand Down
Loading