Methods - Internal
Index
ConstructionBase.constructorofEnergyModelsRecedingHorizon._add_elements!EnergyModelsRecedingHorizon._create_lens_dictEnergyModelsRecedingHorizon._create_lens_for_fieldEnergyModelsRecedingHorizon._create_updatetypeEnergyModelsRecedingHorizon._dict_keyEnergyModelsRecedingHorizon._find_update_pathsEnergyModelsRecedingHorizon._path_typeEnergyModelsRecedingHorizon._reset_fieldEnergyModelsRecedingHorizon._update_future_value!EnergyModelsRecedingHorizon._update_update_case!EnergyModelsRecedingHorizon.coefficientsEnergyModelsRecedingHorizon.create_future_valueEnergyModelsRecedingHorizon.create_future_value_coupleEnergyModelsRecedingHorizon.cut_rhsEnergyModelsRecedingHorizon.cutsEnergyModelsRecedingHorizon.cuts_timeEnergyModelsRecedingHorizon.element_typeEnergyModelsRecedingHorizon.get_future_value_expressionEnergyModelsRecedingHorizon.get_resultsEnergyModelsRecedingHorizon.get_results_dfEnergyModelsRecedingHorizon.init_levelEnergyModelsRecedingHorizon.save_resultsEnergyModelsRecedingHorizon.time_weightEnergyModelsRecedingHorizon.update_init_data!EnergyModelsRecedingHorizon.update_results!EnergyModelsRecedingHorizon.weight
Extension functions
EnergyModelsRecedingHorizon.update_init_data! — Functionupdate_init_data!(m, ri::AbstractReset, x::AbstractElement, idp::InitDataPath, opers_implᵣₕ)Updates the values of AbstractElement x for the AbstractReset ri with the value specified by the key of the idp.
EMRH.update_init_data!(m, ri::AbstractReset, l::Transmission, idp::TransInitDataPath, opers_implᵣₕ)Updates the initial values of Transmission corridor l for the AbstractReset ri with the value specified by the key of the TransInitDataPath idp.
The mode for the variable is identified through the field idx of TransInitDataPath.
Utility functions
EnergyModelsRecedingHorizon.update_results! — Functionupdate_results!(results, m, 𝒰, opers, 𝒽)Updates results given the optimization results m for the times opers, performed in horizon 𝒽. The results are indexed by the elements in the provided case (here accessed using the UpdateCase 𝒰).
EnergyModelsRecedingHorizon.save_results — Functionsave_results(model::Model; directory=joinpath(pwd(),"csv_files"))
save_results(results::Dict{Symbol, AbstractDataFrame}; directory=joinpath(pwd(),"csv_files"))Saves the model results of all variables as CSV files. The model results are saved in the specified directory. If no directory is specified, it will create, if necessary, a new directory "csv_files" in the current working directory and save the files in said directory.
EnergyModelsRecedingHorizon.get_results — Functionget_results(m::JuMP.Model)Function returning the values of the optimized model m. Prints a warning message for currently unsupported types without extracting their value.
EnergyModelsRecedingHorizon.get_results_df — Functionget_results_df(m::JuMP.Model)Function returning the values of the optimized model m as a DataFrame. Prints a warning message for currently unsupported types without extracting their value.
Miscellaneous functions
EnergyModelsRecedingHorizon.init_level — Functioninit_level(n::Storage{RecedingAccumulating})Gets initialization values for the Storage node n from its data fields.
EnergyModelsRecedingHorizon._create_lens_dict — Function_create_lens_dict(𝒳::Vector{<:AbstractElement}
_create_lens_dict(x::Union{AbstractElement, RecHorEnergyModel})Returns a dictionary with the field id as keys and lenses pointing to fields that are updated in the individual type instances as values. The individual field ids are created through calling the function _find_update_paths, and the lenses are created with _create_lens_for_field.
Lenses are created for
- all
OperationalProfiles, - other
AbstractElement, and InitData.
Example
using EnergyModelsBase
using EnergyModelsRecedingHorizon
using TimeStruct
const EMRH = EnergyModelsRecedingHorizon
# Generate objects
cap_prof = OperationalProfile([20, 300])
em_prof = OperationalProfile([1, 2])
price_prof = OperationalProfile([40, 60])
power = ResourceCarrier("power", 0.0)
co2 = ResourceEmit("co2", 1.0)
source1 = RefSource(
"source1",
cap_prof,
FixedProfile(100),
FixedProfile(0),
Dict(power => 1),
[EmissionsProcess(Dict(co2 => em_prof))]
)
source2 = RefSource(
"source2",
FixedProfile(100),
price_prof,
FixedProfile(0),
Dict(power => 1),
)
# Create a dictionary containing lenses to the OperationalProfile
d_all = EMRH._create_lens_dict([source1, source2])
# Returns Dict{RefSource, Dict{Vector{Any}}} with 2 entries:
n_source1 => Dict{Vector{Any}, Any}([:data, "[1]", :emissions, co2, OperPath()]=>_.data[1].emissions[co2], [:cap, OperPath()]=>_.cap)
n_source2 => Dict{Vector{Any}, PropertyLens{:opex_var}}([:opex_var, OperPath()]=>_.opex_var)
d_s1 = EMRH._create_lens_dict(source1)
# Returns Dict{Vector{Any}, Any} with 2 entries:
[:data, "[1]", :emissions, co2, OperPath()] => _.data[1].emissions[co2]
[:cap, OperPath()] => _.capIdentification functions
EnergyModelsRecedingHorizon._find_update_paths — Method_find_update_paths(x::Union{AbstractElement, Resource, RecHorEnergyModel})
_find_update_paths(x::StorageValueCuts)Returns all paths within an AbstractElement, a Resource, a RecHorEnergyModel, or a StorageValueCuts that must be updated in the receding horizon framework as Vector{Vector}.
The individual subfunctions are given as:
_find_update_paths(field::AbstractElement, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::StorageValueCut, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::Vector{<:Data}, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::T, current_path::Vector{Any}, all_paths::Vector{Any}) where {T<:Union{Data, EMB.AbstractStorageParameters, ElementValue}}
_find_update_paths(field::AbstractDict, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::OperationalProfile, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::StrategicProfile, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::Any, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::AbstractInitData, current_path::Vector{Any}, all_paths::Vector{Any})
_find_update_paths(field::InitData, current_path::Vector{Any}, all_paths::Vector{Any})When introducing a new subtype to AbstractInitData, you must also create a new method for this function as it is not possible to cover all potential cases in which the new data is designed.
Example
power = ResourceCarrier("power", 0.0)
co2 = ResourceEmit("co2", 1.0)
sink = RefSink(
"a_sink", # Field `:id`
FixedProfile(1e5), # Field `:cap`
Dict(:surplus => OperationalProfile(zeros(10)),
:deficit => OperationalProfile(10*ones(10))), # Field `:penalty`
Dict(power => 1), # Field `:input`
[EmissionsProcess(Dict(co2 => OperationalProfile(rand(10))))] # Field `:data`
)
EMRH._find_update_paths(sink)
# returns a 3-element Vector{Any}:
Any[:penalty, "[:deficit]", EnergyModelsRecedingHorizon.OperPath()]
Any[:penalty, "[:surplus]", EnergyModelsRecedingHorizon.OperPath()]
Any[:data, "[1]", :emissions, co2, EnergyModelsRecedingHorizon.OperPath()]
# The function can also be used for checking other `types`:
all_paths = []
current_path = Any[:a_path]
a_dict = Dict(:a => Dict(:b1 => Dict(:c => OperationalProfile([1])),
:b2 => OperationalProfile([1]), :b3 => [1]))
EMRH._find_update_paths(a_dict, current_path, all_paths)
# all_paths is now a 2-element Vector{Any}:
Any[:a_path, "[:a]", "[:b2]", EnergyModelsRecedingHorizon.OperPath()]
Any[:a_path, "[:a]", "[:b1]", "[:c]", EnergyModelsRecedingHorizon.OperPath()]EnergyModelsRecedingHorizon._dict_key — Function_dict_key(key::Symbol)
_dict_key(key::String)
_dict_key(key::Resource)Function for translating a dictionary key type to an input which can be parsed into a lens.
EnergyModelsRecedingHorizon._create_lens_for_field — Function_create_lens_for_field(field_id::Vector{<:Any})Returns a lens, which can be used to inspect or reset variables. The lens is based on the field_id obtained through the function _find_update_paths.
Example:
using Accessors: @reset
using EnergyModelsBase
using EnergyModelsRecedingHorizon
using TimeStruct
const EMRH = EnergyModelsRecedingHorizon
cap_prof = OperationalProfile([20, 300])
em_prof = OperationalProfile([1,2])
power = ResourceCarrier("power", 0.0)
co2 = ResourceEmit("co2", 1.0)
source = RefSource(
"power_source", # Node id or name
cap_prof, # Capacity
FixedProfile(100), # Variable OPEX
FixedProfile(0), # Fixed OPEX
Dict(power => 1), # Output from the node
[EmissionsProcess(Dict(co2 => em_prof))] # Line above: CO2 process emissions
)
paths_oper_source = EMRH._find_update_paths(source)
@assert all(paths_oper_source .== Any[
[:cap, EMRH.OperPath()], [:data, "[1]", :emissions, co2, EMRH.OperPath()]
])
lens_source_cap = EMRH._create_lens_for_field(paths_oper_source[1])
lens_source_data = EMRH._create_lens_for_field(paths_oper_source[2])
# Check that the values returned through the lenses are based on the actual values
@assert all(cap_prof == lens_source_cap(source))
@assert all(em_prof == lens_source_data(source))
# Lenses can also be used for resetting values using @reset
cap_prof_new = OperationalProfile([90,100])
@reset lens_source_cap(source) = cap_prof_new
@assert all(cap_prof_new == lens_source_cap(source))EnergyModelsRecedingHorizon._path_type — Function_path_type(val::Symbol)
_path_type(val::String)
_path_type(val::Resource)
_path_type(val::AbstractPath)Translate the individual value to the required format for creating the lense string.
In the case of a resource, it creates a global variable calles res which can be evaluated in the parse.
Functions for resetting values
EnergyModelsRecedingHorizon._create_updatetype — Function_create_updatetype(model::RecHorEnergyModel)Initialize an UpdateCase based on the provided RecHorEnergyModel model.
EnergyModelsRecedingHorizon._add_elements! — Function_add_elements!(𝒰::UpdateCase, 𝒫::Vector{T}) where {T<:Resource}
_add_elements!(𝒰::UpdateCase, 𝒳::Vector{T}) where {T<:AbstractElement}Add the vector of Resources or AbstractElement substitution types to the UpdateCase 𝒰 for a given Vector{<:Resource} or Vector{<:AbstractElement}.
EnergyModelsRecedingHorizon._update_future_value! — Function_update_future_value!(𝒮ᵛ::Vector{FutureValueSub{T}}, time_elapsed::Real) where {T<:StorageValueCuts}
_update_future_value!(𝒮ᵛ::Vector{FutureValueSub{T}}, time_elapsed::Real) where {T<:TypeFutureValue}Update the value of TimeWeightReset based on the time time_elapsed at the end of the TimeStructure.
If a cut is given at the end time of an operational period, the weight is 1 for the given cut and 0 for other. When the optimization end time is between cuts, the weights scales the weight of the nearest cuts such that they are weighted linearly.
EnergyModelsRecedingHorizon._update_update_case! — Function_update_update_case!(𝒰, opers, 𝒯ᵣₕ)Update the UpdateCase 𝒰 with the new values in the optimization problem given by the time structure 𝒯ᵣₕ.
In addition, the UpdateCase 𝒰 is updated with the new mapping between the operational periods of the optimization (through 𝒯ᵣₕ) and the original (through opers) problem.
EnergyModelsRecedingHorizon._reset_field — Method_reset_field(x_rh, res_type::ElementReset, 𝒰::UpdateCase, opers::Vector{<:TS.TimePeriod})
_reset_field(x_rh, res_type::Union{InitReset, TimeWeightReset}, 𝒰::UpdateCase, opers::Vector{<:TS.TimePeriod})
_reset_field(x_rh, res_type::OperReset, 𝒰::UpdateCase, opers::Vector{<:TS.TimePeriod})Resets the field expressed through res_type of element x_rh with the new value. The type of the new value is depending on the specified res_type:
res_type::ElementResetuses𝒰for identifying the new element,res_type::Union{InitReset, TimeWeightReset}uses the value inres_typedirectly,res_type::OperResetcreates a new operational profile based on the original operational profile inres_typeand the set of operational periodsopers.
The following function is introduced for parametric types in which the type is not deducible from the input and for types with inner constructors:
ConstructionBase.constructorof — FunctionAccessors.ConstructionBase.constructorof(obj::Type{<:Storage})Allows using @reset for an obj <: Storage, which is declared as parametric type without the possibility to deduce the possibility to deduce the type parameter from the provided input.
Dispatch on this function for functions using inner constructors, in order for @reset to work.
Future value functions
EnergyModelsRecedingHorizon.get_future_value_expression — Functionget_future_value_expression(m, 𝒱::Vector{StorageValueCuts}, 𝒯ᴵⁿᵛ::TS.AbstractStratPers, modeltype::EnergyModel)
get_future_value_expression(m, 𝒱::Vector{TypeFutureValue}, 𝒯ᴵⁿᵛ::TS.AbstractStratPers, modeltype::EnergyModel)Returns the cost expression for the individual future values.
In the case of StorageValueCuts, the expression equals the weighted sum of the future_value of all active cuts. Inactive cuts are weighted with 0 but still included to keep the number of variables unchanged.
In the case of TypeFutureValue, the expression equals the sum of all values.
EnergyModelsRecedingHorizon.create_future_value — Functioncreate_future_value(m, v::FutureValue, 𝒯, modeltype)Set all constraints for an FutureValue. Fallback option for all unspecified subtypes of FutureValue.
EnergyModelsRecedingHorizon.create_future_value_couple — Functioncreate_future_value_couple(m, v::StorageValueCuts, 𝒯, modeltype::EnergyModel)
create_future_value_couple(m, v::StorageValueCuts, 𝒩::Vector{<:EMB.Node}, 𝒯, modeltype::EnergyModel)
create_future_value_couple(m, v::TypeFutureValue, 𝒯, modeltype::EnergyModel)
create_future_value_couple(m, v::TypeFutureValue, 𝒩::Vector{<:EMB.Node}, 𝒯, modeltype::EnergyModel)Adds the constraints for the individual future values without the interaction with any other AbstractElement.
In the case of StorageValueCuts:
- If
𝒩is not added, that is in the instance for the single couplings, the function adds the cut constraints for all cuts. - If
𝒩is added, that is in the instance forFutureValue-Nodecouplings, the function returns nothing.
In the case of TypeFutureValue:
- If
𝒩is not added, that is in the instance for the single couplings, the function returns nothing. - If
𝒩is added, that is in the instance forFutureValue-Nodecouplings, the function calculates the future value for the given type.
The following functions for accessing fields of the types are introduced:
EnergyModelsRecedingHorizon.coefficients — Functioncoefficients(svc::StorageValueCut)Returns the cut coefficients associated with the level of the given Storage nodes.
coefficients(v::TypeFutureValue)Returns the the cofficients dictionary of of the future value v.
EnergyModelsRecedingHorizon.cut_rhs — Functioncut_rhs(svc::StorageValueCut)Returns the cut right hand side constant.
EnergyModelsRecedingHorizon.weight — Functionweight(svcs::StorageValueCuts)Returns the weight of the storage value cuts svcs.
EnergyModelsRecedingHorizon.time_weight — Functiontime_weight(svcs::StorageValueCuts)Returns the time weight of the storage value cuts svcs.
EnergyModelsRecedingHorizon.cuts_time — Functioncuts_time(svcs::StorageValueCuts)Returns the time at which the storage value cuts svcs are valid relative to the total horizon.
EnergyModelsRecedingHorizon.cuts — Functioncuts(svcs::StorageValueCuts)Returns the different cuts of StorageValueCuts svcs.
EnergyModelsRecedingHorizon.element_type — Functionelement_type(v::TypeFutureValue)Returns the composite type who possesses a variable with a future value.