diff --git a/src/model/resources/fusion/fusion.jl b/src/model/resources/fusion/fusion.jl index 5feb5cc2f2..83a8e5010c 100644 --- a/src/model/resources/fusion/fusion.jl +++ b/src/model/resources/fusion/fusion.jl @@ -380,10 +380,21 @@ function fusion_pulse_thermal_power_generation_constraint!( @constraint( EP, [t in 1:T], - power_like[y, t] <= ePulseUnderway[t] - dwell_time * ePulseStart[t] + power_like[y, t] <= ePulseUnderway[t] - _fusion_dwell_avoided_operation(dwell_time, ePulseStart[t]) ) end +@doc raw""" + _fusion_dwell_avoided_operation(dwell_time::Float64, + ePulseStart::AffExpr) + + dwell_time in fractions of a timestep + ePulseStart is the number of MW starting. Typically component_size * vPulseStart +""" +function _fusion_dwell_avoided_operation(dwell_time::Float64, ePulseStart::AffExpr) + return dwell_time * ePulseStart +end + function fusion_parasitic_power!( EP::Model, inputs::Dict, diff --git a/src/model/resources/fusion/fusion_maintenance.jl b/src/model/resources/fusion/fusion_maintenance.jl index 136622ea27..5c395d014e 100644 --- a/src/model/resources/fusion/fusion_maintenance.jl +++ b/src/model/resources/fusion/fusion_maintenance.jl @@ -12,7 +12,7 @@ function fusion_maintenance_adjust_parasitic_power!(EP, df::DataFrame) reactor = FusionReactorData(parasitic_passive_fraction = by_rid(y, :Parasitic_Passive), eff_down = 1.0, component_size = by_rid(y, :Cap_Size), - maintenance_remaining_parasitic_power_fraction = float(by_rid(y, :Parasitic_Passive_Maintenance_Remaining))) + maintenance_remaining_parasitic_power_fraction = float(by_rid(y, :Parasitic_Passive_Maintenance_Remaining))) _fusion_maintenance_parasitic_power_adjustment!(EP, resource_component, reactor) end diff --git a/src/model/resources/fusion/fusion_policy_adjustments.jl b/src/model/resources/fusion/fusion_policy_adjustments.jl index 26a1bc59e0..b0f7e7936b 100644 --- a/src/model/resources/fusion/fusion_policy_adjustments.jl +++ b/src/model/resources/fusion/fusion_policy_adjustments.jl @@ -31,29 +31,30 @@ function _fusion_capacity_reserve_margin_adjustment!(EP::Model, y::Int) T = inputs["T"] - timesteps = collect(1:T) + timesteps = collect(1:T) ncapres = inputs["NCapacityReserveMargin"] eCapResMarBalance = EP[:eCapResMarBalance] - for capres_zone in 1:ncapres - adjustment = fusion_capacity_reserve_margin_adjustment(EP, inputs, resource_component, y, capres_zone, timesteps) - add_similar_to_expression!(eCapResMarBalance[capres_zone, :], adjustment) - end - return + for capres_zone in 1:ncapres + adjustment = fusion_capacity_reserve_margin_adjustment(EP, inputs, resource_component, y, capres_zone, timesteps) + add_similar_to_expression!(eCapResMarBalance[capres_zone, :], adjustment) + end + return end # Get the amount for one resource component in one CRM zone function fusion_capacity_reserve_margin_adjustment(EP::Model, inputs::Dict, - resource_component::AbstractString, + resource_component::AbstractString, y::Int, capres_zone::Int, - timesteps::Vector{Int}) + timesteps::Vector{Int}) dfGen = inputs["dfGen"] + by_rid(rid, sym) = by_rid_df(rid, sym, dfGen) - capresfactor = dfGen[y, Symbol("CapRes_" * string(capres_zone))] + capresfactor = dfGen[y, Symbol("CapRes_" * string(capres_zone))] get_from_model(f::Function) = EP[Symbol(f(resource_component))] @@ -61,8 +62,13 @@ function fusion_capacity_reserve_margin_adjustment(EP::Model, eActive = get_from_model(fusion_parasitic_active_name) eStartPower = get_from_model(fusion_pulse_start_power_name) - fusion_adj = _fusion_crm_parasitic_adjustment.(capresfactor, ePassive[timesteps], eActive[timesteps], eStartPower[timesteps]) - return fusion_adj + dwell_time = Float64(by_rid(y, :Dwell_Time)) + component_size = by_rid(y, :Cap_Size) + ePulseStart = component_size * get_from_model(fusion_pulse_start_name) + + parasitic_adj = _fusion_crm_parasitic_adjustment.(capresfactor, ePassive[timesteps], eActive[timesteps], eStartPower[timesteps]) + dwell_adj = - capresfactor * _fusion_dwell_avoided_operation.(dwell_time, ePulseStart[timesteps]) + return parasitic_adj + dwell_adj end @@ -103,19 +109,19 @@ end ################################# function fusion_parasitic_power_adjust_energy_share_requirement!(EP, inputs) - eESR = EP[:eESR] - nESR = inputs["nESR"] - weights = inputs["omega"] - dfGen = inputs["dfGen"] - FUSION = resources_with_fusion(dfGen) - - for y in FUSION, p in 1:nESR - esr_derating = dfGen[y, Symbol("ESR_" * string(p))] - if esr_derating > 0 - resource_component = dfGen[y, :Resource] - adjustment = -esr_derating * fusion_annual_parasitic_power(EP, inputs, resource_component) - add_similar_to_expression!(eESR[p], adjustment) - end - end + eESR = EP[:eESR] + nESR = inputs["nESR"] + weights = inputs["omega"] + dfGen = inputs["dfGen"] + FUSION = resources_with_fusion(dfGen) + + for y in FUSION, p in 1:nESR + esr_derating = dfGen[y, Symbol("ESR_" * string(p))] + if esr_derating > 0 + resource_component = dfGen[y, :Resource] + adjustment = -esr_derating * fusion_annual_parasitic_power(EP, inputs, resource_component) + add_similar_to_expression!(eESR[p], adjustment) + end + end end