A Fusion Systems Code
Reactor | Affiliation | Info | ||||
---|---|---|---|---|---|---|
Scylla | – | Steady-State Prototype | ||||
Charybdis | – | Pulsed Prototype | ||||
ARC | MIT | Compact Steady-State Tokamak | ||||
ACT I | ARIES (US) | Optimistic Design | ||||
ACT II | ARIES (US) | Conservative Design | ||||
DEMO Steady | PROCESS (EU) | Steady-State Machine | ||||
DEMO Pulsed | PROCESS (EU) | Pulsed Machine |
cur_script = """
<style class="js-load-remove-tag">
.cs-loading:after {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
-webkit-animation: cs-ellipsis steps(3,end) 3250ms infinite;
animation: cs-ellipsis steps(3,end) 3250ms infinite;
content: "\\2026";
width: 0px;
}
@keyframes cs-ellipsis { to { width: 0.9em; } }
@-webkit-keyframes cs-ellipsis { to { width: 0.9em; } }
</style>
<script class="js-load-remove-tag">
\$(".js-load-remove-tag").parent(".output_subarea").css("padding", "0");
</script>
"""
display(HTML(cur_script))
using Fussy
using FileIO
using JLD2
using Plots
using Interact
using DataStructures
using StringCases
pyplot()
return
function toggle_buttons(show_buttons, hide_buttons)
cur_script = """
<script class="js-toggle">
"""
for cur_index in hide_buttons
if cur_index < 0
cur_string = """
\$(".jupyter-widgets").closest(".output_area").length
"""
else
cur_string = "0"
end
cur_script *= """
\$(".jupyter-widgets").closest(".output_area").eq($(cur_string)+($(cur_index))).hide()
\$(".jupyter-widgets").closest(".output_area").eq($(cur_string)+($(cur_index))).next().hide()
"""
end
for cur_index in show_buttons
if cur_index < 0
cur_string = """
\$(".jupyter-widgets").closest(".output_area").length
"""
else
cur_string = "0"
end
cur_script *= """
\$(".jupyter-widgets").closest(".output_area").eq($(cur_string)+($(cur_index))).show()
\$(".jupyter-widgets").closest(".output_area").eq($(cur_string)+($(cur_index))).next().show()
"""
end
cur_script *= """
\$(".js-toggle").parent(".output_subarea").parent(".output_area").remove();
</script>
"""
display(HTML(cur_script))
end
return
@manipulate for loading=[true,false]
end
toggle_buttons([],[0])
return
cur_scans = load("data/comparisons.jld2", "cur_scans")
cur_studies = load("data/sensitivities.jld2", "cur_studies")
cur_samplings = load("data/samplings.jld2", "cur_samplings")
return
cur_decks = [
:proteus, # pulsed
:charybdis, # steady state
:arc, :act_1, :act_2,
:demo_steady, :demo_pulsed
]
cur_params = [
:T_bar, :n_bar, :I_P, :R_0, :B_0,
:tau_E, :p_bar, :eta_CD, :P_F,
:beta_N, :q_95, :q_DV, :P_W,
:norm_beta_N, :norm_q_95, :norm_P_E, :norm_P_W,
:f_BS, :f_CD, :f_IN, :W_M, :cost,
:a, :b, :c, :d, :h_CS, :R_CS
]
expanded_params = deepcopy(cur_params)
append!(
expanded_params,
[
:H, :Q, :wave_theta,
:epsilon, :delta_95,
:nu_n, :nu_T, :l_i,
:N_G, :f_D, :Z_eff,
:eta_CD, :B_CS, :tau_FT
]
)
x_list = deepcopy(cur_params)
y_list = deepcopy(cur_params)
xx_list = deepcopy(expanded_params)
yy_list = deepcopy(expanded_params)
xxx_list = [
:H, :Q, :wave_theta,
:epsilon, :kappa_95, :delta_95,
:nu_n, :nu_T, :l_i,
:N_G, :f_D, :Z_eff,
:max_beta_N, :max_q_95, :max_P_W,
:eta_CD, :B_CS, :tau_FT
]
Fussy.sort_lists!(map(lowercase, map(string,x_list)), x_list)
Fussy.sort_lists!(map(lowercase, map(string,xx_list)), xx_list)
Fussy.sort_lists!(map(lowercase, map(string,y_list)), y_list)
Fussy.sort_lists!(map(lowercase, map(string,yy_list)), yy_list)
filter!(tmp_x -> tmp_x != :B_0, x_list)
filter!(tmp_y -> tmp_y != :R_0, y_list)
unshift!(x_list, :B_0)
unshift!(y_list, :R_0)
filter!(tmp_x -> tmp_x != :B_0, xx_list)
filter!(tmp_y -> tmp_y != :cost, yy_list)
unshift!(xx_list, :B_0)
unshift!(yy_list, :cost)
return
function fix_lims!(cur_lims, x, y, xscale, yscale)
cur_lims[1:2:3] /= 1.2
cur_lims[2:2:4] *= 1.2
if x == :cost
cur_lims[1:2] = [0.001, 0.1]
end
if y == :cost
cur_lims[3:4] = [0.001, 0.1]
end
if x == :W_M
cur_lims[1:2] = [0.01, 100]
end
if y == :W_M
cur_lims[3:4] = [0.01, 100]
end
if x == :B_0 || x == :R_0
cur_lims[1:2] = [0.05, 20]
end
if y == :B_0 || y == :R_0
cur_lims[3:4] = [0.05, 20]
end
if in(x, [:f_IN, :f_BS, :f_CD, :norm_P_W, :norm_beta_N, :norm_q_95])
cur_lims[2] = 1.25
end
if in(y, [:f_IN, :f_BS, :f_CD, :norm_P_W, :norm_beta_N, :norm_q_95])
cur_lims[4] = 1.25
end
if xscale == "log"
iszero(cur_lims[1]) || plot!( xscale = :log )
else
cur_lims[1] = 0
end
if yscale == "log"
iszero(cur_lims[3]) || plot!( yscale = :log )
else
cur_lims[3] = 0
end
end
return
function filter_reactors!(reactor_list)
filter!(Fussy.is_present, reactor_list)
filter!(tmp_reactor -> tmp_reactor.is_valid, reactor_list)
filter!(tmp_reactor -> tmp_reactor.is_good, reactor_list)
filter!(tmp_reactor -> tmp_reactor.R_0 < 50, reactor_list)
filter!(tmp_reactor -> tmp_reactor.B_0 < 50, reactor_list)
filter!(tmp_reactor -> tmp_reactor.cost < 1, reactor_list)
isempty(reactor_list) && return
( reactor_list[1].deck == :demo_steady ) && return
( reactor_list[1].deck == :act_1 ) && return
filter!(tmp_reactor -> tmp_reactor.norm_P_E < 0.8, reactor_list)
end
return
function make_comparisons(deck, x, y, xscale, yscale)
is_pulsed = deck == :proteus || startswith(string(deck), "demo")
if is_pulsed
other_label = "simple"
else
other_label = "steady"
end
other_type = Symbol("$(deck)_$(other_label)")
min_x, max_x = Inf, -Inf
min_y, max_y = Inf, -Inf
scan_types = [deck, other_type]
is_pulsed || reverse!(scan_types)
for scan_type in scan_types
cur_scan = deepcopy(cur_scans[scan_type])
cur_dict = OrderedDict()
cur_dict[:kink] = cur_scan.kink_reactors
cur_dict[:beta] = cur_scan.beta_reactors
cur_dict[:wall] = cur_scan.wall_reactors
for (cur_key, cur_value) in cur_dict
filter_reactors!(cur_value)
isempty(cur_value) && continue
min_branch_id = minimum(map(tmp_reactor -> tmp_reactor.branch_id, cur_value))
max_branch_id = maximum(map(tmp_reactor -> tmp_reactor.branch_id, cur_value))
for cur_branch_id in min_branch_id:max_branch_id
tmp_value = filter(tmp_reactor -> tmp_reactor.branch_id == cur_branch_id, cur_value)
( length(tmp_value) > 1 ) || continue
tmp_tt = map(tmp_reactor -> tmp_reactor.T_bar, tmp_value)
tmp_xx = map(tmp_reactor -> getfield(tmp_reactor, x), tmp_value)
tmp_yy = map(tmp_reactor -> getfield(tmp_reactor, y), tmp_value)
Fussy.sort_lists!(tmp_tt, tmp_xx, tmp_yy)
cur_label = string(cur_key)
if scan_type == other_type
cur_label = "$(other_label) - $(cur_label)"
cur_style = is_pulsed ? :dash : :solid
else
cur_label = "pulsed - $(cur_label)"
cur_style = is_pulsed ? :solid : :dash
end
min_x = min(min_x, minimum(tmp_xx))
min_y = min(min_y, minimum(tmp_yy))
max_x = max(max_x, maximum(tmp_xx))
max_y = max(max_y, maximum(tmp_yy))
plot!(tmp_xx, tmp_yy, label=cur_label, style=cur_style)
end
end
end
cur_lims = [min_x, max_x, min_y, max_y]
fix_lims!(cur_lims, x, y, xscale, yscale)
if isdefined(Fussy, Symbol("$(deck)_solution"))
cur_solution = getfield(Fussy, Symbol("$(deck)_solution"))()
tmp_x = getfield(cur_solution, x)
tmp_y = getfield(cur_solution, y)
( tmp_x == nothing ) && ( tmp_x = NaN )
( tmp_y == nothing ) && ( tmp_y = NaN )
plot!(cur_lims[1:2], [tmp_y, tmp_y], color=:black, opacity=0.5, label="", style=:dot, width=2)
plot!([tmp_x, tmp_x], cur_lims[3:4], color=:black, opacity=0.5, label="", style=:dot, width=2)
scatter!([tmp_x], [tmp_y], color=:black, opacity=0.5, label="")
end
return cur_lims
end
return
function make_sensitivities(deck, x, y, xscale, yscale)
cur_study = deepcopy(cur_studies[x][deck])
min_x, max_x = Inf, -Inf
min_y, max_y = Inf, -Inf
cur_dict = OrderedDict()
cur_dict[:kink] = cur_study.kink_reactors
cur_dict[:wall] = cur_study.wall_reactors
cur_dict[:cost] = cur_study.cost_reactors
cur_dict[:W_M] = cur_study.W_M_reactors
for (cur_index, (cur_key, cur_value)) in enumerate(cur_dict)
filter_reactors!(cur_value)
isempty(cur_value) && continue
tmp_xx = map(tmp_reactor -> getfield(tmp_reactor, x), cur_value)
tmp_yy = map(tmp_reactor -> getfield(tmp_reactor, y), cur_value)
min_x = min(min_x, minimum(tmp_xx))
min_y = min(min_y, minimum(tmp_yy))
max_x = max(max_x, maximum(tmp_xx))
max_y = max(max_y, maximum(tmp_yy))
if cur_index < 3
cur_width = 3
cur_style = :dot
else
cur_width = 1
cur_style = :solid
end
plot!(tmp_xx, tmp_yy, label=cur_key, color=cur_index, width=cur_width, style=cur_style)
end
study_mid_x = cur_study.default
study_min_x = cur_study.default * ( 1 - cur_study.sensitivity )
study_max_x = cur_study.default * ( 1 + cur_study.sensitivity )
min_x = min(min_x, study_min_x)
max_x = min(max_x, study_max_x)
cur_lims = [min_x, max_x, min_y, max_y]
fix_lims!(cur_lims, x, y, xscale, yscale)
plot!([study_mid_x, study_mid_x], cur_lims[3:4], color=length(cur_dict)+1, style=:dash, label="")
plot!([study_min_x, study_min_x], cur_lims[3:4], color=length(cur_dict)+2, style=:dash, label="")
plot!([study_max_x, study_max_x], cur_lims[3:4], color=length(cur_dict)+2, style=:dash, label="")
return cur_lims
end
return
function make_samplings(deck, x, y, xscale, yscale, simple)
cur_sampling = deepcopy(cur_samplings[deck])
min_x, max_x = Inf, -Inf
min_y, max_y = Inf, -Inf
for (cur_key, cur_value) in cur_samplings
for cur_index in 1:cur_value.study_count
if Fussy.is_present(cur_value.wall_reactors[cur_index]) && Fussy.is_present(cur_value.cost_reactors[cur_index])
cur_error = abs(cur_value.wall_reactors[cur_index].cost-cur_value.cost_reactors[cur_index].cost)
( cur_error < 1e-4 ) && ( cur_value.cost_reactors[cur_index] = nothing )
end
if Fussy.is_present(cur_value.cost_reactors[cur_index]) && Fussy.is_present(cur_value.W_M_reactors[cur_index])
cur_error = abs(cur_value.cost_reactors[cur_index].cost-cur_value.W_M_reactors[cur_index].cost)
( cur_error < 1e-4 ) && ( cur_value.cost_reactors[cur_index] = nothing )
end
if Fussy.is_present(cur_value.kink_reactors[cur_index]) && Fussy.is_present(cur_value.W_M_reactors[cur_index])
cur_error = abs(cur_value.kink_reactors[cur_index].cost-cur_value.W_M_reactors[cur_index].cost)
( cur_error < 1e-4 ) && ( cur_value.W_M_reactors[cur_index] = nothing )
end
if Fussy.is_present(cur_value.kink_reactors[cur_index]) && Fussy.is_present(cur_value.cost_reactors[cur_index])
cur_error = abs(cur_value.kink_reactors[cur_index].cost-cur_value.cost_reactors[cur_index].cost)
( cur_error < 1e-4 ) && ( cur_value.cost_reactors[cur_index] = nothing )
end
if Fussy.is_present(cur_value.wall_reactors[cur_index]) && Fussy.is_present(cur_value.W_M_reactors[cur_index])
cur_error = abs(cur_value.wall_reactors[cur_index].cost-cur_value.W_M_reactors[cur_index].cost)
( cur_error < 1e-4 ) && ( cur_value.W_M_reactors[cur_index] = nothing )
end
if Fussy.is_present(cur_value.wall_reactors[cur_index]) && Fussy.is_present(cur_value.kink_reactors[cur_index])
cur_error = abs(cur_value.wall_reactors[cur_index].cost-cur_value.kink_reactors[cur_index].cost)
( cur_error < 1e-4 ) && ( cur_value.wall_reactors[cur_index] = nothing )
end
end
end
markers = [:diamond, :square,:circle, :pentagon]
z = :W_M
w = :P_F
limits = true
constraints = true
cur_list = [:kink, :wall, :cost, :W_M]
this_xx = []
this_yy = []
this_zz = []
this_ww = []
this_ss = []
this_mm = []
this_oo = []
for (tmp_index, kind) in enumerate(cur_list)
tmp_reacs = deepcopy(getfield(cur_samplings[deck], Symbol("$(kind)_reactors")))
filter_reactors!(tmp_reacs)
isempty(tmp_reacs) && continue
cur_xx = map(tmp_reac -> getfield(tmp_reac, x), tmp_reacs)
cur_yy = map(tmp_reac -> getfield(tmp_reac, y), tmp_reacs)
cur_zz = map(tmp_reac -> getfield(tmp_reac, z), tmp_reacs)
cur_ww = map(tmp_reac -> getfield(tmp_reac, w), tmp_reacs)
cur_mm = []
for tmp_reac in tmp_reacs
if simple
if isapprox(tmp_reac.norm_beta_N,1.0,rtol=1e-4)
tmp_m = markers[3] #:beta
elseif isapprox(tmp_reac.norm_P_W,1.0,rtol=1e-4)
tmp_m = markers[2] #:wall
else
@assert isapprox(tmp_reac.norm_q_95,1.0,rtol=1e-4)
tmp_m = markers[1] #:kink
end
else
tmp_m = markers[tmp_index]
end
push!(cur_mm, tmp_m)
end
append!(this_oo, (tmp_index < 3 ? Int(limits) : Int(constraints))*ones(length(cur_zz)))
append!(this_mm, cur_mm)
append!(this_ss, map(tmp_m -> tmp_m ==:square ? 4/sqrt(2) : 4, cur_mm))
append!(this_xx, cur_xx)
append!(this_zz, cur_zz)
append!(this_yy, cur_yy)
append!(this_ww, cur_ww)
end
max_x = maximum(this_xx)
max_y = maximum(this_yy)
min_x = minimum(this_xx)
min_y = minimum(this_yy)
this_ww = -log10.(this_ww)
this_ww -= minimum(this_ww)
this_ww /= maximum(this_ww)
this_ss += 2 * this_ww - 1
this_ss += 2
this_zz = -log10.(this_zz)
Fussy.sort_lists!(this_zz,this_xx,this_yy,this_ss,this_mm,this_oo,this_ww)
this_oo .*= (ceil.((0.6+0.4*this_ww)*10)/10)
this_ss = map(round,this_ss)
plot!([],[],label="size = a - b * log( $w )", opacity=0)
plot!([],[],label=" ", opacity=0)
for (tmp_index, tmp_label) in enumerate(cur_list)
cur_label = nothing
if simple
( tmp_index == 4 ) && continue
cur_label = tmp_index == 3 ? :beta : tmp_label
else
cur_label = tmp_index < 3 ? "$(tmp_label)-beta" : tmp_label
end
scatter!([],[],color=tmp_index < 3 ? tmp_index : tmp_index < 4 ? tmp_index + 1 : tmp_index + 3,label=cur_label,marker=markers[tmp_index])
end
scatter!(this_xx, this_yy,zcolor=this_zz, color=:viridis,markersize=this_ss, markershapes=this_mm, label="",opacity=this_oo, colorbar_title="-log( $z )")#, markersize=marker_size),marker=markers[tmp_index], label=kind
cur_lims = [min_x, max_x, min_y, max_y]
fix_lims!(cur_lims, x, y, xscale, yscale)
return cur_lims
end
return
@manipulate for mode=["comparisons", "sensitivities", "samplings"], legend=[true, false], xscale=["lin", "log"], yscale=["lin", "log"], simple=[true,false], Χ=x_list, X=xx_list, Х=xxx_list, y=y_list, у=yy_list, deck = cur_decks, dummy=[true,false]
x = Χ
xx = X
xxx = Х
yy = у
plot(legend=legend, html_output_format=:svg)
hide_buttons = [-1,-5,-6,-7,-8,-3,-4]
if mode == "comparisons"
cur_lims = make_comparisons(deck, x, y, xscale, yscale)
xlabel!(string(x))
ylabel!(string(y))
show_buttons = [-7,-4]
elseif mode == "sensitivities"
cur_lims = make_sensitivities(deck, xxx, y, xscale, yscale)
xlabel!(string(xxx))
ylabel!(string(y))
show_buttons = [-5,-4]
else
@assert mode == "samplings"
cur_lims = make_samplings(deck, xx, yy, xscale, yscale, simple)
xlabel!(string(xx))
ylabel!(string(yy))
show_buttons = [-6,-3,-8]
end
toggle_buttons(show_buttons, hide_buttons)
cur_title = string(deck)
cur_title = join(map(capitalize, split(cur_title, "_")), " ")
title!(cur_title)
xlims!(cur_lims[1:2]...)
ylims!(cur_lims[3:4]...)
plot!()
end
cur_script = """
<script class="js-load-remove-tag">
\$(".js-load-message").remove();
\$("#appmode-busy").css("opacity","0");
\$('pre:contains("WebIO: setting up")').parent(".output_subarea").remove();
\$(".js-load-remove-tag").parent(".output_subarea").remove();
</script>
"""
display(HTML(cur_script))