generated from NREL-Sienna/Sienna-Template
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add functions for variables, expressions, and constraints for Transpo…
…rtTechnology
- Loading branch information
1 parent
b6d4e91
commit b3f0d51
Showing
2 changed files
with
256 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,242 @@ | ||
#! format: off | ||
get_variable_upper_bound(::BuildCapacity, d::PSIP.ACTransportTechnology, ::InvestmentTechnologyFormulation) = PSIP.get_maximum_new_capacity(d) | ||
get_variable_lower_bound(::BuildCapacity, d::PSIP.ACTransportTechnology, ::InvestmentTechnologyFormulation) = 0.0 | ||
get_variable_binary(::BuildCapacity, d::PSIP.ACTransportTechnology, ::ContinuousInvestment) = false | ||
|
||
get_variable_lower_bound(::ActivePowerVariable, d::PSIP.ACTransportTechnology, ::OperationsTechnologyFormulation) = 0.0 | ||
get_variable_upper_bound(::ActivePowerVariable, d::PSIP.ACTransportTechnology, ::OperationsTechnologyFormulation) = nothing | ||
|
||
get_variable_multiplier(::ActivePowerVariable, ::Type{PSIP.ACTransportTechnology{PSY.Branch}}) = 1.0 | ||
|
||
#! format: on | ||
|
||
function get_default_time_series_names( | ||
::Type{U}, | ||
::Type{V}, | ||
::Type{W}, | ||
::Type{X}, | ||
) where { | ||
U<:PSIP.ACTransportTechnology, | ||
V<:InvestmentTechnologyFormulation, | ||
W<:OperationsTechnologyFormulation, | ||
X<:FeasibilityTechnologyFormulation, | ||
} | ||
return Dict{Type{<:TimeSeriesParameter},String}() | ||
end | ||
|
||
function get_default_attributes( | ||
::Type{U}, | ||
::Type{V}, | ||
::Type{W}, | ||
::Type{X}, | ||
) where { | ||
U<:PSIP.ACTransportTechnology, | ||
V<:InvestmentTechnologyFormulation, | ||
W<:OperationsTechnologyFormulation, | ||
X<:FeasibilityTechnologyFormulation, | ||
} | ||
return Dict{String,Any}() | ||
end | ||
|
||
################### Variables #################### | ||
|
||
################## Expressions ################### | ||
|
||
function add_expression!( | ||
container::SingleOptimizationContainer, | ||
expression_type::T, | ||
devices::U, | ||
formulation::AbstractTechnologyFormulation, | ||
tech_model::String | ||
) where { | ||
T<:CumulativeCapacity, | ||
U<:Union{D, Vector{D}, IS.FlattenIteratorWrapper{D}}, | ||
} where {D<:PSIP.ACTransportTechnology} | ||
#@assert !isempty(devices) | ||
time_steps = get_time_steps_investments(container) | ||
binary = false | ||
|
||
var = get_variable(container, BuildCapacity(), D, tech_model) | ||
|
||
expression = add_expression_container!( | ||
container, | ||
expression_type, | ||
D, | ||
[PSIP.get_name(d) for d in devices], | ||
time_steps, | ||
meta=tech_model | ||
) | ||
|
||
# TODO: Move to add_to_expression? | ||
for t in time_steps, d in devices | ||
name = PSIP.get_name(d) | ||
init_cap = PSIP.get_existing_line_capacity(d) | ||
expression[name, t] = JuMP.@expression( | ||
get_jump_model(container), | ||
init_cap + sum(var[name, t_p] for t_p in time_steps if t_p <= t), | ||
#binary = binary | ||
) | ||
#ub = get_variable_upper_bound(expression_type, d, formulation) | ||
#ub !== nothing && JuMP.set_upper_bound(variable[name, t], ub) | ||
|
||
#lb = get_variable_lower_bound(expression_type, d, formulation) | ||
#lb !== nothing && JuMP.set_lower_bound(variable[name, t], lb) | ||
end | ||
|
||
return | ||
end | ||
|
||
function add_to_expression!( | ||
container::SingleOptimizationContainer, | ||
expression_type::T, | ||
devices::U, | ||
formulation::BasicDispatch, | ||
tech_model::String, | ||
transport_model::TransportModel{V} | ||
) where { | ||
T<:EnergyBalance, | ||
U<:Union{D, Vector{D}, IS.FlattenIteratorWrapper{D}}, | ||
V<:MultiRegionBalanceModel | ||
} where {D<:PSIP.ACTransportTechnology} | ||
#@assert !isempty(devices) | ||
time_steps = get_time_steps(container) | ||
#binary = false | ||
#var = get_variable(container, ActivePowerVariable(), D) | ||
|
||
variable = get_variable(container, ActivePowerVariable(), D, tech_model) | ||
expression = get_expression(container, T(), PSIP.Portfolio) | ||
# expression = add_expression_container!(container, expression_type, D, time_steps) | ||
# Assuming that energy travels from start to end, so if dispatch of Branch is positive, it is subtracted from start_region | ||
for d in devices, t in time_steps | ||
name = PSIP.get_name(d) | ||
start_region = PSIP.get_start_region(d) | ||
end_region = PSIP.get_end_region(d) | ||
losses = PSIP.get_line_loss(d) | ||
#bus_no = PNM.get_mapped_bus_number(radial_network_reduction, PSY.get_bus(d)) | ||
_add_to_jump_expression!( | ||
expression[start_region, t], | ||
variable[name, t], | ||
-1.0, #get_variable_multiplier(U(), V, W()), | ||
) | ||
_add_to_jump_expression!( | ||
expression[end_region, t], | ||
variable[name, t], | ||
(1.0-losses), #get_variable_multiplier(U(), V, W()), | ||
) | ||
end | ||
|
||
return | ||
end | ||
|
||
function add_constraints!( | ||
container::SingleOptimizationContainer, | ||
::T, | ||
::V, | ||
devices::U, | ||
tech_model::String | ||
) where { | ||
T<:ActivePowerLimitsConstraint, | ||
U<:Union{D, Vector{D}, IS.FlattenIteratorWrapper{D}}, | ||
V<:ActivePowerVariable, | ||
} where {D<:PSIP.ACTransportTechnology} | ||
time_steps = get_time_steps(container) | ||
# Hard Code Mapping # | ||
# TODO: Remove | ||
@warn("creating hard code mapping. Remove it later") | ||
mapping_ops = Dict(("2030", 1) => 1:24, ("2035", 1) => 25:48) | ||
mapping_inv = Dict("2030" => 1, "2035" => 2) | ||
device_names = PSIP.get_name.(devices) | ||
con_ub = add_constraints_container!(container, T(), D, device_names, time_steps, meta=tech_model) | ||
|
||
installed_cap = get_expression(container, CumulativeCapacity(), D, tech_model) | ||
active_power = get_variable(container, V(), D, tech_model) | ||
|
||
for d in devices | ||
name = PSIP.get_name(d) | ||
ts_name = "ops_variable_cap_factor" | ||
ts_keys = filter(x -> x.name == ts_name, IS.get_time_series_keys(d)) | ||
for ts_key in ts_keys | ||
ts_type = ts_key.time_series_type | ||
features = ts_key.features | ||
year = features["year"] | ||
#rep_day = features["rep_day"] | ||
ts_data = TimeSeries.values( | ||
#IS.get_time_series(ts_type, d, ts_name; year=year, rep_day=rep_day).data, | ||
IS.get_time_series(ts_type, d, ts_name; year=year).data, | ||
) | ||
#time_steps_ix = mapping_ops[(year, rep_day)] | ||
time_steps_ix = mapping_ops[(year, 1)] | ||
time_step_inv = mapping_inv[year] | ||
for (ix, t) in enumerate(time_steps_ix) | ||
con_ub[name, t] = JuMP.@constraint( | ||
get_jump_model(container), | ||
active_power[name, t] <= installed_cap[name, time_step_inv] | ||
) | ||
end | ||
end | ||
end | ||
end | ||
|
||
# Maximum cumulative capacity | ||
function add_constraints!( | ||
container::SingleOptimizationContainer, | ||
::T, | ||
::V, | ||
devices::U, | ||
tech_model::String | ||
#::NetworkModel{X}, | ||
) where { | ||
T<:MaximumCumulativeCapacity, | ||
U<:Union{D, Vector{D}, IS.FlattenIteratorWrapper{D}}, | ||
V<:CumulativeCapacity, | ||
#X <: PM.AbstractPowerModel, | ||
} where {D<:PSIP.ACTransportTechnology} | ||
time_steps = get_time_steps_investments(container) | ||
|
||
device_names = PSIP.get_name.(devices) | ||
con_ub = add_constraints_container!(container, T(), D, device_names, time_steps, meta=tech_model) | ||
|
||
installed_cap = get_expression(container, CumulativeCapacity(), D, tech_model) | ||
|
||
for d in devices | ||
name = PSIP.get_name(d) | ||
max_capacity = PSIP.maximum_new_capacity(d) | ||
init_cap = PSIP.existing_line_capacity(d) | ||
for t in time_steps | ||
con_ub[name, t] = JuMP.@constraint( | ||
get_jump_model(container), | ||
installed_cap[name, t] <= max_capacity+init_cap | ||
) | ||
end | ||
end | ||
end | ||
|
||
########################### Objective Function Calls############################################# | ||
# These functions are custom implementations of the cost data. In the file objective_functions.jl there are default implementations. Define these only if needed. | ||
#= | ||
function objective_function!( | ||
container::SingleOptimizationContainer, | ||
devices::Union{Vector{T}, IS.FlattenIteratorWrapper{T}}, | ||
#DeviceModel{T, U}, | ||
formulation::BasicDispatch, #Type{<:PM.AbstractPowerModel}, | ||
tech_model::String, | ||
) where {T<:PSIP.ACTransportTechnology}#, U <: ActivePowerVariable} | ||
add_variable_cost!(container, ActivePowerVariable(), devices, formulation, tech_model) #U() | ||
#add_start_up_cost!(container, StartVariable(), devices, U()) | ||
#add_shut_down_cost!(container, StopVariable(), devices, U()) | ||
#add_proportional_cost!(container, OnVariable(), devices, U()) | ||
return | ||
end | ||
=# | ||
|
||
function objective_function!( | ||
container::SingleOptimizationContainer, | ||
devices::Union{Vector{T}, IS.FlattenIteratorWrapper{T}}, | ||
#DeviceModel{T, U}, | ||
formulation::ContinuousInvestment, #Type{<:PM.AbstractPowerModel}, | ||
tech_model::String, | ||
) where {T<:PSIP.ACTransportTechnology}#, U <: BuildCapacity} | ||
add_capital_cost!(container, BuildCapacity(), devices, formulation, tech_model) #U() | ||
#add_fixed_om_cost!(container, CumulativeCapacity(), devices, formulation, tech_model) | ||
return | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters