Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply review suggestions for economic representation calculation #1130

Merged
merged 1 commit into from
Nov 19, 2024
Merged
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
256 changes: 104 additions & 152 deletions src/data_structure/economic_structure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,130 +27,91 @@
elseif model_type(model=m.ext[:spineopt].instance) === :spineopt_benders
error("Using economic representation with Benders' decomposition is currently not supported.")
end
!isempty(
[
model__default_investment_temporal_block()
node__investment_temporal_block()
unit__investment_temporal_block()
connection__investment_temporal_block()
],
) || return
# use_economic_representation == true without defining investment temporal blocks will break the investment cost calculation
# in such cases, user would only need to discount operational costs manually
if isempty(model__default_investment_temporal_block()) &&
isempty(node__investment_temporal_block()) &&
isempty(unit__investment_temporal_block()) &&
isempty(connection__investment_temporal_block())
error("Using economic representation without defining investment temporal blocks is currently not supported.")

Check warning on line 36 in src/data_structure/economic_structure.jl

View check run for this annotation

Codecov / codecov/patch

src/data_structure/economic_structure.jl#L36

Added line #L36 was not covered by tests
end
economic_parameters = _create_set_parameters_and_relationships()
for (obj, name) in [(unit, :unit), (node, :storage), (connection, :connection)]
@timelog log_level 3 "- [Generated discounted durations for $(obj)s]" generate_discount_timeslice_duration!(
m,
obj,
economic_parameters,
)
@timelog log_level 3 "- [Generated capacity transfer factors for $(name)s]" generate_capacity_transfer_factor!(
m,
obj,
economic_parameters,
)
@timelog log_level 3 "- [Generated conversion to discounted investments of $(name)s]" generate_conversion_to_discounted_annuities!(
m,
obj,
economic_parameters,
)
@timelog log_level 3 "- [Generated conversion for discounted decommissioning of $(name)s]" generate_decommissioning_conversion_to_discounted_annuities!(
m,
obj,
economic_parameters,
)
@timelog log_level 3 "- [Generated salvage fraction for $(name)s]" generate_salvage_fraction!(
m,
obj,
economic_parameters,
)
@timelog log_level 3 "- [Generated $(name) technology specific discount factors]" generate_tech_discount_factor!(
m,
obj,
economic_parameters,
)
@timelog log_level 3 "- [Generated discounted durations for $(obj)s]" begin
generate_discount_timeslice_duration!(m, obj, economic_parameters)
end
@timelog log_level 3 "- [Generated capacity transfer factors for $(name)s]" begin
generate_capacity_transfer_factor!(m, obj, economic_parameters)
end
@timelog log_level 3 "- [Generated conversion to discounted investments of $(name)s]" begin
generate_conversion_to_discounted_annuities!(m, obj, economic_parameters)
end
@timelog log_level 3 "- [Generated conversion for discounted decommissioning of $(name)s]" begin
generate_decommissioning_conversion_to_discounted_annuities!(m, obj, economic_parameters)
end
@timelog log_level 3 "- [Generated salvage fraction for $(name)s]" begin
generate_salvage_fraction!(m, obj, economic_parameters)
end
@timelog log_level 3 "- [Generated $(name) technology specific discount factors]" begin
generate_tech_discount_factor!(m, obj, economic_parameters)
end
end
end

function _create_set_parameters_and_relationships()
economic_parameters = Dict(
# defined outside this file
# indices
:set_investment_indices => Dict(
unit => units_invested_available_indices,
node => storages_invested_available_indices,
connection => connections_invested_available_indices,
),
# relationships
:set_invest_temporal_block => Dict(
unit => unit__investment_temporal_block,
node => node__investment_temporal_block,
connection => connection__investment_temporal_block,
),
:set_invest_stoch_struct => Dict(
unit => unit__investment_stochastic_structure,
node => node__investment_stochastic_structure,
connection => connection__investment_stochastic_structure,
unit => Dict(
:set_investment_indices => units_invested_available_indices,
:set_invest_temporal_block => unit__investment_temporal_block,
:set_invest_stoch_struct => unit__investment_stochastic_structure,
:set_lead_time => unit_lead_time,
:set_tech_lifetime => unit_investment_tech_lifetime,
:set_econ_lifetime => unit_investment_econ_lifetime,
:set_discnt_rate_tech => unit_discount_rate_technology_specific,
:set_decom_time => unit_decommissioning_time,
:set_decom_cost => unit_decommissioning_cost,
:set_capacity_transfer_factor => :unit_capacity_transfer_factor,
:set_conversion_to_discounted_annuities => :unit_conversion_to_discounted_annuities,
:set_salvage_fraction => :unit_salvage_fraction,
:set_tech_discount_factor => :unit_tech_discount_factor,
:set_discounted_duration => :unit_discounted_duration,
:set_decommissioning_conversion_to_discounted_annuities => :unit_decommissioning_conversion_to_discounted_annuities,
),
# parameters
:set_lead_time =>
Dict(unit => unit_lead_time, node => storage_lead_time, connection => connection_lead_time),
:set_tech_lifetime => Dict(
unit => unit_investment_tech_lifetime,
node => storage_investment_tech_lifetime,
connection => connection_investment_tech_lifetime,
),
:set_econ_lifetime => Dict(
unit => unit_investment_econ_lifetime,
node => storage_investment_econ_lifetime,
connection => connection_investment_econ_lifetime,
),
:set_discnt_rate_tech => Dict(
unit => unit_discount_rate_technology_specific,
node => storage_discount_rate_technology_specific,
connection => connection_discount_rate_technology_specific,
),
:set_decom_time => Dict(
unit => unit_decommissioning_time,
node => storage_decommissioning_time,
connection => connection_decommissioning_time,
),
:set_decom_cost => Dict(
unit => unit_decommissioning_cost,
node => storage_decommissioning_cost,
connection => connection_decommissioning_cost,
),
# internally calculated parameters in this file
:set_capacity_transfer_factor => Dict(
unit => :unit_capacity_transfer_factor,
node => :storage_capacity_transfer_factor,
connection => :connection_capacity_transfer_factor,
),
:set_conversion_to_discounted_annuities => Dict(
unit => :unit_conversion_to_discounted_annuities,
node => :storage_conversion_to_discounted_annuities,
connection => :connection_conversion_to_discounted_annuities,
),
:set_salvage_fraction => Dict(
unit => :unit_salvage_fraction,
node => :storage_salvage_fraction,
connection => :connection_salvage_fraction,
),
:set_tech_discount_factor => Dict(
unit => :unit_tech_discount_factor,
node => :storage_tech_discount_factor,
connection => :connection_tech_discount_factor,
),
:set_discounted_duration => Dict(
unit => :unit_discounted_duration,
node => :storage_discounted_duration,
connection => :connection_discounted_duration,
),
:set_decommissioning_conversion_to_discounted_annuities => Dict(
unit => :unit_decommissioning_conversion_to_discounted_annuities,
node => :storage_decommissioning_conversion_to_discounted_annuities,
connection => :connection_decommissioning_conversion_to_discounted_annuities,
node => Dict(
:set_investment_indices => storages_invested_available_indices,
:set_invest_temporal_block => node__investment_temporal_block,
:set_invest_stoch_struct => node__investment_stochastic_structure,
:set_lead_time => storage_lead_time,
:set_tech_lifetime => storage_investment_tech_lifetime,
:set_econ_lifetime => storage_investment_econ_lifetime,
:set_discnt_rate_tech => storage_discount_rate_technology_specific,
:set_decom_time => storage_decommissioning_time,
:set_decom_cost => storage_decommissioning_cost,
:set_capacity_transfer_factor => :storage_capacity_transfer_factor,
:set_conversion_to_discounted_annuities => :storage_conversion_to_discounted_annuities,
:set_salvage_fraction => :storage_salvage_fraction,
:set_tech_discount_factor => :storage_tech_discount_factor,
:set_discounted_duration => :storage_discounted_duration,
:set_decommissioning_conversion_to_discounted_annuities => :storage_decommissioning_conversion_to_discounted_annuities,
),
connection => Dict(
:set_investment_indices => connections_invested_available_indices,
:set_invest_temporal_block => connection__investment_temporal_block,
:set_invest_stoch_struct => connection__investment_stochastic_structure,
:set_lead_time => connection_lead_time,
:set_tech_lifetime => connection_investment_tech_lifetime,
:set_econ_lifetime => connection_investment_econ_lifetime,
:set_discnt_rate_tech => connection_discount_rate_technology_specific,
:set_decom_time => connection_decommissioning_time,
:set_decom_cost => connection_decommissioning_cost,
:set_capacity_transfer_factor => :connection_capacity_transfer_factor,
:set_conversion_to_discounted_annuities => :connection_conversion_to_discounted_annuities,
:set_salvage_fraction => :connection_salvage_fraction,
:set_tech_discount_factor => :connection_tech_discount_factor,
:set_discounted_duration => :connection_discounted_duration,
:set_decommissioning_conversion_to_discounted_annuities => :connection_decommissioning_conversion_to_discounted_annuities,
)
)
return economic_parameters
end

"""
Expand All @@ -163,11 +124,11 @@
function generate_capacity_transfer_factor!(m::Model, obj_cls::ObjectClass, economic_parameters::Dict)
instance = m.ext[:spineopt].instance
capacity_transfer_factor = Dict()
investment_indices = economic_parameters[:set_investment_indices][obj_cls]
lead_time = economic_parameters[:set_lead_time][obj_cls]
tech_lifetime = economic_parameters[:set_tech_lifetime][obj_cls]
invest_temporal_block = economic_parameters[:set_invest_temporal_block][obj_cls]
param_name = economic_parameters[:set_capacity_transfer_factor][obj_cls]
investment_indices = economic_parameters[obj_cls][:set_investment_indices]
lead_time = economic_parameters[obj_cls][:set_lead_time]
tech_lifetime = economic_parameters[obj_cls][:set_tech_lifetime]
invest_temporal_block = economic_parameters[obj_cls][:set_invest_temporal_block]
param_name = economic_parameters[obj_cls][:set_capacity_transfer_factor]

for id in invest_temporal_block(temporal_block=anything)
if (
Expand All @@ -190,10 +151,7 @@
)...,
)
map_indices = []
count = 0 # count the element; this is to avoid using collect
for _ in investment_indices_vector
count += 1
end
count = length(collect(investment_indices_vector))
sizehint!(map_indices, count)
timeseries_array = []
sizehint!(timeseries_array, count)
Expand Down Expand Up @@ -279,10 +237,10 @@
instance = m.ext[:spineopt].instance
discnt_year = discount_year(model=instance)
conversion_to_discounted_annuities = Dict()
investment_indices = economic_parameters[:set_investment_indices][obj_cls]
lead_time = economic_parameters[:set_lead_time][obj_cls]
econ_lifetime = economic_parameters[:set_econ_lifetime][obj_cls]
param_name = economic_parameters[:set_conversion_to_discounted_annuities][obj_cls] # this is MARKUP^AN
investment_indices = economic_parameters[obj_cls][:set_investment_indices]
lead_time = economic_parameters[obj_cls][:set_lead_time]
econ_lifetime = economic_parameters[obj_cls][:set_econ_lifetime]
param_name = economic_parameters[obj_cls][:set_conversion_to_discounted_annuities] # this is MARKUP^AN

for id in obj_cls()
if (discount_rate(model=model()[1]) == 0 || isnothing(discount_rate(model=model()[1])))
Expand All @@ -296,10 +254,7 @@
for s in stochastic_map_vector
time_series_vector = investment_indices(m; Dict(obj_cls.name => id, :stochastic_scenario => s)...)
timeseries_ind = []
count = 0 # count the element; this is to avoid using collect
for _ in time_series_vector
count += 1
end
count = length(collect(time_series_vector))
sizehint!(timeseries_ind, count)
timeseries_val = []
sizehint!(timeseries_val, count)
Expand Down Expand Up @@ -406,11 +361,11 @@
discnt_year = discount_year(model=instance)
p_eoh = model_end(model=instance)
salvage_fraction = Dict()
investment_indices = economic_parameters[:set_investment_indices][obj_cls]
lead_time = economic_parameters[:set_lead_time][obj_cls]
econ_lifetime = economic_parameters[:set_econ_lifetime][obj_cls]
invest_temporal_block = economic_parameters[:set_invest_temporal_block][obj_cls]
param_name = economic_parameters[:set_salvage_fraction][obj_cls]
investment_indices = economic_parameters[obj_cls][:set_investment_indices]
lead_time = economic_parameters[obj_cls][:set_lead_time]
econ_lifetime = economic_parameters[obj_cls][:set_econ_lifetime]
invest_temporal_block = economic_parameters[obj_cls][:set_invest_temporal_block]
param_name = economic_parameters[obj_cls][:set_salvage_fraction]

for id in invest_temporal_block(temporal_block=anything)
if id in indices(econ_lifetime)
Expand Down Expand Up @@ -476,11 +431,11 @@
"""
function generate_tech_discount_factor!(m::Model, obj_cls::ObjectClass, economic_parameters::Dict)
instance = m.ext[:spineopt].instance
investment_indices = economic_parameters[:set_investment_indices][obj_cls]
econ_lifetime = economic_parameters[:set_econ_lifetime][obj_cls]
discnt_rate_tech = economic_parameters[:set_discnt_rate_tech][obj_cls]
invest_stoch_struct = economic_parameters[:set_invest_stoch_struct][obj_cls]
param_name = economic_parameters[:set_tech_discount_factor][obj_cls]
investment_indices = economic_parameters[obj_cls][:set_investment_indices]
econ_lifetime = economic_parameters[obj_cls][:set_econ_lifetime]
discnt_rate_tech = economic_parameters[obj_cls][:set_discnt_rate_tech]
invest_stoch_struct = economic_parameters[obj_cls][:set_invest_stoch_struct]
param_name = economic_parameters[obj_cls][:set_tech_discount_factor]

for id in obj_cls()
if (
Expand Down Expand Up @@ -536,9 +491,9 @@
instance = m.ext[:spineopt].instance
discnt_year = discount_year(model=instance)
discounted_duration = Dict()
invest_stoch_struct = economic_parameters[:set_invest_stoch_struct][obj_cls]
invest_temporal_block = economic_parameters[:set_invest_temporal_block][obj_cls]
param_name = economic_parameters[:set_discounted_duration][obj_cls]
invest_stoch_struct = economic_parameters[obj_cls][:set_invest_stoch_struct]
invest_temporal_block = economic_parameters[obj_cls][:set_invest_temporal_block]
param_name = economic_parameters[obj_cls][:set_discounted_duration]

if use_milestone_years(model=instance)
for id in obj_cls()
Expand Down Expand Up @@ -604,10 +559,7 @@
time_slice(m; temporal_block=invest_temporal_block),
TimeSlice(last_timestep, last_timestep),
))
count = 0 # count the element; this is to avoid using collect
for _ in timeseries_vector
count += 1
end
count = length(collect(timeseries_vector)) # count the element; this is to avoid using collect
timeseries_ind = []
sizehint!(timeseries_ind, count)
timeseries_val = []
Expand Down Expand Up @@ -643,10 +595,10 @@
instance = m.ext[:spineopt].instance
discnt_year = discount_year(model=instance)
decommissioning_conversion_to_discounted_annuities = Dict()
investment_indices = economic_parameters[:set_investment_indices][obj_cls]
decom_time = economic_parameters[:set_decom_time][obj_cls]
decom_cost = economic_parameters[:set_decom_cost][obj_cls]
param_name = economic_parameters[:set_decommissioning_conversion_to_discounted_annuities][obj_cls]
investment_indices = economic_parameters[obj_cls][:set_investment_indices]
decom_time = economic_parameters[obj_cls][:set_decom_time]
decom_cost = economic_parameters[obj_cls][:set_decom_cost]
param_name = economic_parameters[obj_cls][:set_decommissioning_conversion_to_discounted_annuities]

for id in indices(decom_cost)
stochastic_map_vector = unique([x.stochastic_scenario for x in investment_indices(m)])
Expand Down
Loading