diff --git a/src/model/resources/fusion/fusion.jl b/src/model/resources/fusion/fusion.jl index 05380ced9d..3cfba800c4 100644 --- a/src/model/resources/fusion/fusion.jl +++ b/src/model/resources/fusion/fusion.jl @@ -448,6 +448,7 @@ function fusion_max_fpy_per_year_constraint!( ) T = inputs["T"] y = r_id + @info "Applying FPY constraint for $r_id" capacity = sum(EP[component_capacity][r_id]) max_fpy_per_year = reactor.max_fpy_per_year diff --git a/src/model/resources/maintenance.jl b/src/model/resources/maintenance.jl index 11e88a0788..ea907e4651 100644 --- a/src/model/resources/maintenance.jl +++ b/src/model/resources/maintenance.jl @@ -232,16 +232,10 @@ end # This also works for plants where they need maintenance every year: # cap_maint * 0 = cap_nomain * 5 → 0 == cap_nomain #### -function capacity_proportional_link!(EP::Model, id_a, id_b, proportion_a, proportion_b) - @info "Linking capacities $id_a and $id_b in $proportion_a : $proportion_b" - cap = EP[:eTotalCap] - @constraint(EP, cap[id_a] * proportion_b == cap[id_b] * proportion_a) -end - function may_have_pairwise_capacity_links(df::DataFrame) columns = names(df) paired_resource = :Paired_Resource - proportion = :Resource_Pair_Proportion + proportion = :Paired_Resource_Proportion return string(paired_resource) in columns && string(proportion) in columns end @@ -272,7 +266,7 @@ function find_paired_resources(df::DataFrame) return linked end - pairs = Pair{Int,Int}[] + _pairs = Pair{Int,Int}[] has_link = findall(df[!, paired_resource] .!= "None") for id_a in has_link id_b = find_id_of_linked(id_a) @@ -280,17 +274,23 @@ function find_paired_resources(df::DataFrame) error("Resources $id_a and $id_b must link to each other, via $paired_resource.") end if id_a < id_b # no need to create the constraint twice. - push!(pairs, Pair(id_a, id_b)) + push!(_pairs, Pair(id_a, id_b)) end end - return pairs + return _pairs +end + +function capacity_proportional_link!(EP::Model, id_a, id_b, proportion_a, proportion_b) + @info "Linking capacities $id_a and $id_b in $proportion_a : $proportion_b" + cap = EP[:eTotalCap] + @constraint(EP, cap[id_a] * proportion_b == cap[id_b] * proportion_a) end function link_capacities!(EP::Model, df::DataFrame) - proportion = :Resource_Pair_Proportion + proportion = :Paired_Resource_Proportion - pairs = find_paired_resources(df) - for p in pairs + _pairs = find_paired_resources(df) + for p in _pairs id_a = p.first id_b = p.second proportion_a = df[id_a, proportion] diff --git a/src/model/resources/thermal/thermal_commit.jl b/src/model/resources/thermal/thermal_commit.jl index 81484abe04..380b8b4417 100644 --- a/src/model/resources/thermal/thermal_commit.jl +++ b/src/model/resources/thermal/thermal_commit.jl @@ -413,6 +413,11 @@ function fusion_formulation_thermal_commit!(EP::Model, inputs::Dict, setup::Dict FUSION = resources_with_fusion(dfGen) + pairdict = Dict{Int, Int}[] + if may_have_pairwise_capacity_links(dfGen) + pairdict = Dict(find_paired_resources(dfGen)) + end + resource_name(y) = dfGen[y, :Resource] resource_component(y) = resource_name(y) @@ -435,7 +440,13 @@ function fusion_formulation_thermal_commit!(EP::Model, inputs::Dict, setup::Dict fusion_pulse_status_linking_constraints!(EP, inputs, name, y, reactor, :vCOMMIT) fusion_pulse_thermal_power_generation_constraint!(EP, inputs, name, y, reactor, power_like) fusion_parasitic_power!(EP, inputs, name, y, reactor, :eTotalCap) - fusion_max_fpy_per_year_constraint!(EP, inputs, y, reactor, :eTotalCap, EP[:vP]) + + if y in keys(pairdict) + second = pairdict[y] + fusion_max_fpy_per_year_constraint!(EP, inputs, [y, second], reactor, :eTotalCap, EP[:vP]) + elseif y ∉ values(pairdict) + fusion_max_fpy_per_year_constraint!(EP, inputs, y, reactor, :eTotalCap, EP[:vP]) + end add_fusion_component_to_zone_listing(inputs, y, name) end