Methods - EnergyModelsBase
Index
EnergyModelsBase.capacity
EnergyModelsBase.check_node
EnergyModelsBase.check_node_data
EnergyModelsBase.constraints_capacity
EnergyModelsBase.constraints_flow_in
EnergyModelsBase.constraints_flow_out
EnergyModelsBase.constraints_level_aux
EnergyModelsBase.constraints_opex_fixed
EnergyModelsBase.constraints_opex_var
EnergyModelsBase.create_node
EnergyModelsBase.inputs
EnergyModelsBase.level
EnergyModelsBase.outputs
EnergyModelsBase.variables_node
Extension methods
EnergyModelsBase.variables_node
— FunctionEMB.variables_node(m, 𝒩ⁿᵈʳ::Vector{<:AbstractNonDisRES}, 𝒯, modeltype::EnergyModel)
Create the optimization variable :curtailment
for every AbstractNonDisRES
node. This method is called from EnergyModelsBase.jl
.
EMB.variables_node(m, 𝒩::Vector{<:HydroStorage}, 𝒯, modeltype::EnergyModel)
Create the optimization variable :hydro_spill
for every HydroStorage node. This variable enables hydro storage nodes to spill water from the reservoir without producing energy. Wihtout this slack variable, parameters with too much inflow would else lead to an infeasible model.
EMB.variables_node(m, 𝒩::Vector{HydroGate}, 𝒯, modeltype::EnergyModel)
Creates the following additional variables for ALL HydroGate
nodes that have additional constraints through ScheduleConstraint
:
gate_penalty_up[n, t, p]
is the up penalty variable of hydro gaten
in operational periodt
for resourcep
.gate_penalty_down[n, t, p]
is the down penalty variable of hydro gaten
in operational periodt
for resourcep
.
These variables enable HydroGate
nodes to penalize a violation of the discharge constraint instead of providing a strict upper bound. They hence transform the constraint to a soft constraint. Without these penalty variables, too strict discharge restrictions may cause an infeasible model.
EMB.variables_node(m, 𝒩::Vector{HydroReservoir{T}}, 𝒯, modeltype::EnergyModel) where {T <: EMB.StorageBehavior}
Creates the following additional variables for ALL HydroReservoir
nodes that have additional constraints through ScheduleConstraint
:
rsv_penalty_up[n, t, p]
is the up penalty variable of hydro reservoirn
in operational periodt
for resourcep
.rsv_penalty_down[n, t, p]
is the down penalty variable of hydro reservoirn
in operational periodt
for resourcep
.
These variables enable HydroReservoir
nodes to penalize a violation of the volume constraint instead of providing a strict bound. They hence transform the constraint to a soft constraint. Without these penalty variables, too strict volume restrictions may cause an infeasible model.
EMB.variables_node(m, 𝒩::Vector{:<HydroUnit}, 𝒯, modeltype::EnergyModel)
Creates the following additional variables for ALL HydroUnit
nodes that have additional constraints through ScheduleConstraint
:
gen_penalty_up[n, t, p]
is the up penalty variable of hydro unitn
in operational periodt
for resourcep
.rsv_penalty_down[n, t, p]
is the down penalty variable of hydro unitn
in operational periodt
for resourcep
.discharge_segment[n, t, q]
is the discharge segment variable of hydro unitn
in operational periodt
for discharge segmentq
The capacity of thedischarge_segment
s sums up to the total discharge capacity.
The first two variables enable HydroUnit
nodes to penalize a violation of the generation/pumping constraints instead of providing a strict bound. They hence transform the constraint to a soft constraint. Without these penalty variables, too strict generation/pumping constraints may cause an infeasible model.
EMB.variables_node(m, 𝒩::Vector{<:AbstractBattery}, 𝒯, modeltype::EnergyModel)
Declaration of reserve variables for all AbstractBattery
nodes. The following reserve variables are declared:
bat_prev_use[n, t]
is the accumulated charge effect of anAbstractBattery
up to operational periodt
.bat_prev_use_sp[n, t_inv]
is the accumulated charge effect of anAbstractBattery
up to investment periodt_inv
.bat_use_sp[n, t_inv]
is the accummulated charge effect of anAbstractBattery
in investment periodt_inv
.bat_use_rp[n, t_rp]
is the accummulated charge effect of anAbstractBattery
in representative periodt_rp
. It is only declared if theTimeStructure
includesRepresentativePeriods
.bat_stack_replace_b[n, t_inv]
is a binary variable for identification of battery battery stack replacement. Stack replacement occurs before the first operational period of a strategic period. It is only declared for batterys which utilize anAbstractBatteryLife
that includes degradation.
EMB.variables_node(m, 𝒩::Vector{<:ReserveBattery}, 𝒯, modeltype::EnergyModel)
Declaration of reserve variables for ReserveBattery
nodes. The following reserve variables are declared:
bat_res_up[n, t]
is the upwards reserve of battery storagen
in operational periodt
.bat_res_down[n, t]
is the upwards reserve of battery of storagen
in operational periodt
.
EnergyModelsBase.create_node
— FunctionEMB.create_node(m, n::HydroStorage, 𝒯, 𝒫, modeltype::EnergyModel)
Sets all constraints for the regulated hydro storage node.
EMB.create_node(m, n::AbstractBattery, 𝒯, 𝒫, modeltype::EnergyModel)
Set all constraints for a AbstractBattery
. Can serve as fallback option for all unspecified subtypes of AbstractBattery
. It differs from the function for a standard Storage
node through calling the constraint function constraints_usage
for calculating the cycles of the node.
Called constraint functions
EnergyModelsBase.level
— Functionlevel(n::HydroReservoir)
level(n::HydroReservoir, t)
Returns the vol
parameter field of the HydroReservoir n
either as TimeProfile
or in operational period t
.
Constraint methods
EnergyModelsBase.constraints_capacity
— Functionconstraints_capacity(m, n::AbstractNonDisRES, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the maximum capacity of a AbstractNonDisRES
. Also sets the constraint defining curtailment.
constraints_capacity(m, n::AbstractBattery, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the maximum capacity of an AbstractBattery
.
Its function flow is changed from the standard approach through calling the function capacity_reduction
to identify the reduced storage capacity, depending on the chosen AbstractBatteryLife
type.
EMB.constraints_capacity(m, n::HydroUnit, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraints on the maximum capacity of a HydroUnit
node. It differs from the base functions through incorporating the PQ Curve through the function max_normalized_power
Furthermore, the function build_pq_constaints
is called for creating additional constraints on the capacity utilization.
If you create a new method for this function, it is crucial to call within said function the function constraints_capacity_installed(m, n, 𝒯, modeltype)
if you want to include investment options.
EnergyModelsBase.constraints_flow_in
— Functionconstraints_flow_in(m, n::HydroStor, 𝒯::TimeStructure, modeltype::EnergyModel)
When n::HydroStor
, the variable :flow_in
is fixed to 0 for all potential inputs.
constraints_flow_in(m, n::PumpedHydroStor, 𝒯::TimeStructure, modeltype::EnergyModel)
When n::PumpedHydroStor
, the variable :flow_in
is multiplied with the inputs
value to calculate the variable :stor_charge_use
.
EMB.constraints_flow_in(m, n::HydroGenerator, 𝒯::TimeStructure, modeltype::EnergyModel)
EMB.constraints_flow_in(m, n::HydroPump, 𝒯::TimeStructure, modeltype::EnergyModel)
Method for creating the constraint on the inlet flow of a node n
.
The constraints enforce that the water inlet flow is equal to the outlet flow at each operational period t
, and hence, preserve conservation of mass.
The electricity flow to the unit is equal to the capacity utilization The flow of the inlet resources can be constrained through calling the function build_schedule_constraint
.
EnergyModelsBase.constraints_flow_out
— Functionconstraints_flow_out(m, n::ReserveBattery, 𝒯::TimeStructure, modeltype::EnergyModel)
When n::ReserveBattery
, the variable :flow_out
is also declared for the different reserve resources as identified through the functions reserve_up
and reserve_down
.
EMB.constraints_flow_out(m, n::HydroGate, 𝒯::TimeStructure, modeltype::EnergyModel)
Function for creating the constraint on the outlet flow from a HydroGate
. This function implements the schedule and min/max constraints if present.
EMB.constraints_flow_out(m, n::HydroGenerator, 𝒯::TimeStructure, modeltype::EnergyModel)
EMB.constraints_flow_out(m, n::HydroPump, 𝒯::TimeStructure, modeltype::EnergyModel)
Method for creating the constraint on the oulet flow of a node n
.
- The electricity flow from the unit is equal to the capacity utilization.
- The flow of the inlet resources can be constrained through calling the function
build_schedule_constraint
.
- The constraints enforce that the water outlet flow is equal to the inlet flow at each operational period
t
, and hence, preserve conservation of mass.
EnergyModelsBase.constraints_level_aux
— Functionconstraints_level_aux(m, n::HydroStorage, 𝒯, 𝒫, modeltype)
Function for creating the Δ constraint for the level of a HydroStorage
node as well as the specification of the initial level in a strategic period.
The change in storage level in the reservoir at operational periods t
is the inflow through :level_inflow
plus the input :stor_charge_use
minus the production :stor_discharge_use
and the spillage of water due to overflow :hydro_spill
.
constraints_level_aux(m, n::AbstractBattery, 𝒯, 𝒫, modeltype::EnergyModel)
Function for creating the Δ constraint for the level of an AbstractBattery
node utilizing the efficiencies declared in inputs and outputs of the storage resource.
EMB.constraints_level_aux(m, n::HydroReservoir, 𝒯, 𝒫, modeltype::EnergyModel)
Create the Δ constraint for the level of the HydroReservoir
node. The change in storage level in the reservoir at operational periods t
is the flow into the reservoir through the variable stor_charge_use
and inflow (through the function vol_inflow
) minus the flow out of the reservoir through the variable stor_discharge_use
.
In addition, it creates the volume constraints if data is provided.
EnergyModelsBase.constraints_opex_var
— FunctionEMB.constraints_opex_var(m, n::HydroResevoir{T}, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
EMB.constraints_opex_var(m, n::HydroGate, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
EMB.constraints_opex_var(m, n::HydroUnit, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
Method for creating the constraint on the variable OPEX. The individual methods extend the functions of EnergyModelsBase
through incorporating the penalty term for constraint violation.
EnergyModelsBase.constraints_opex_fixed
— Functionconstraints_opex_fixed(m, n::AbstractBattery, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)
Function for creating the constraint on the fixed OPEX of a generic AbstractBattery
.
The functions nodes includes fixed OPEX for charge
, level
, and discharge
if the node has the corresponding storage parameter. The individual contributions are in all situations calculated based on the installed capacities.
In addition, battery stack replacement is included if the battery_life
has a limited cycle lifetime. The division by durationstrat(tinv) for the battery stack replacement is required due to the multiplication with the duration in the objective function calculation.
Check methods
EnergyModelsBase.check_node
— FunctionEMB.check_node(n::NonDisRES, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
This method checks that the NonDisRES
node is valid.
It reuses the standard checks of a Source
node through calling the function EMB.check_node_default
, but adds an additional check on the data.
Checks
- The field
cap
is required to be non-negative (similar to theSource
check). - The value of the field
fixed_opex
is required to be non-negative and accessible through aStrategicPeriod
as outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)
. - The values of the dictionary
output
are required to be non-negative (similar to theSource
check). - The field
profile
is required to be in the range $[0, 1]$ for all time steps $t ∈ \mathcal{T}$.
EMB.check_node(n::HydroStorage, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
This method checks that the HydroStorage
node is valid.
It reuses the standard checks of a Storage
node through calling the function EMB.check_node_default
, but adds an additional check on the data.
Checks
- The
TimeProfile
of the fieldcapacity
in the type in the fieldcharge
is required to be non-negative if the chosen composite type has the fieldcapacity
. - The
TimeProfile
of the fieldcapacity
in the type in the fieldlevel
is required to be non-negative`. - The
TimeProfile
of the fieldcapacity
in the type in the fielddischarge
is required to be non-negative if the chosen composite type has the fieldcapacity
. - The
TimeProfile
of the fieldfixed_opex
is required to be non-negative and accessible through aStrategicPeriod
as outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)
for the chosen composite type . - The field
output
can only include a singleResource
. - The value of the field
output
is required to be in the range $[0, 1]$. - The value of the field
input
is required to be in the range $[0, 1]$. - The value of the field
level_init
is required to be in the range $[level\_min, 1] \cdot stor\_cap(t)$ for all time steps $t ∈ \mathcal{T}$. - The value of the field
level_init
is required to be in the range $[0, 1]$. - The value of the field
level_min
is required to be in the range $[0, 1]$.
EMB.check_node(n::HydroReservoir, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
This method checks that the HydroReservoir
node is valid.
Checks
- The
TimeProfile
of thecapacity
of theHydroReservoir
level
is required to be non-negative. - The
TimeProfile
of the fieldfixed_opex
is required to be non-negative and accessible through aStrategicPeriod
as outlined in the function functionEMB.check_fixed_opex()
for the fieldlevel
, if included. - The
TimeProfile
of thevol_inflow
of theHydroReservoir
is required to be non-negative.
EMB.check_node(n::HydroGate, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
This method checks that the HydroGate
node is valid.
Checks
- The field
cap
is required to be non-negative. - The value of the field
fixed_opex
is required to be non-negative and accessible through
a StrategicPeriod
as outlined in the function EMB.check_fixed_opex()
.
EMB.check_node(n::HydroUnit, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
This method checks that the HydroGenerator
and HydroPump
nodes are valid.
Checks
- The field
cap
is required to be non-negative. - The
PqPoints
vectors are required to have the same length. - The
PqPoints
vectors should start at 0. - The
PqPoints
vectors are required to be increasing. - One of the
PqPoints
vectors should have values between 0 and 1. - The
PqPoints
curve should be concave for generators and convex for pumps. - The value of the field
fixed_opex
is required to be non-negative and accessible through aStrategicPeriod
as outlined in the functionEMB.check_fixed_opex()
.
EMB.check_node(n::AbstractBattery, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
This method checks that the AbstractBattery
node is valid.
It reuses the standard checks of a Storage
node through calling the function EMB.check_node_default
, but adds an additional check on the data.
Checks
- The
TimeProfile
of the fieldcapacity
in the type in the fieldcharge
is required to be non-negative. - The
TimeProfile
of the fieldcapacity
in the type in the fieldlevel
is required to be non-negative`. - The
TimeProfile
of the fieldcapacity
in the type in the fielddischarge
is required to be non-negative. - The
TimeProfile
of the fieldfixed_opex
is required to be non-negative and accessible through aStrategicPeriod
as outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)
for the chosen composite type . - The field
output
can only include a singleResource
. - The value of the field
input
is required to be in the range $[0, 1]$. - The value of the field
output
is required to be in the range $[0, 1]$ - The
AbstractBatteryLife
must follow the provided values as outlined in the functioncheck_battery_life
.
EMB.check_node(n::ReserveBattery, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
This method checks that the ReserveBattery
node is valid.
It reuses the standard checks of a Storage
node through calling the function EMB.check_node_default
, but adds an additional check on the data.
Checks
- The
TimeProfile
of the fieldcapacity
in the type in the fieldcharge
is required to be non-negative. - The
TimeProfile
of the fieldcapacity
in the type in the fieldlevel
is required to be non-negative`. - The
TimeProfile
of the fieldcapacity
in the type in the fielddischarge
is required to be non-negative. - The
TimeProfile
of the fieldfixed_opex
is required to be non-negative and accessible through aStrategicPeriod
as outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)
for the chosen composite type . - The field
output
can only include a singleResource
. - The value of the field
input
is required to be in the range $[0, 1]$. - The value of the field
output
is required to be in the range $[0, 1]$ - The resources in the array
reserve_up
cannot be part of the resources in the dictionaries dictionariesinput
andoutput
. - The resources in the array
reserve_down
cannot be part of the resources in the dictionariesinput
andoutput
.
EnergyModelsBase.check_node_data
— FunctionEMB.check_node_data(n::EMB.Node, data::ScheduleConstraint, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)
Performs various checks on ScheduleConstraint
data for all nodes.
Checks
- The the field
resource
is required to be a valid resource of the node. - The value of constraints are required to be in the range $[0, 1]$ for all time steps $t ∈ \mathcal{T}$.
- The penalty of constraints are required to be non-negative for all time steps $t ∈ \mathcal{T}$.
Field extraction methods
EnergyModelsBase.capacity
— Functioncapacity(n::HydroUnit, t, p::Resource)
capacity(n::HydroGate, t, p::Resource)
Returns the capacity of HydroUnit n
in operational period t
for a given resource p
. In the case of a HydroGate
, this function reverts to capacity(n, t)
to allow its application in multiple methods.
The resource p
must be either the electricity_resource
or water_resource
. Otherwise, an error is raised.
EnergyModelsBase.inputs
— Functioninputs(n::HydroReservoir)
inputs(n::HydroReservoir, p::Resource)
Returns the input resources of a HydroReservoir n
, specified via the field stor_res
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
inputs(n::HydroGate)
inputs(n::HydroGate, p::Resource)
Returns the input resources of a HydroGate n
, specified via the field resource
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
inputs(n::HydroGenerator)
inputs(n::HydroGenerator, p::Resource)
Returns the input resources of a HydroGenerator n
, specified via the field water_resource
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
inputs(n::HydroPump)
inputs(n::HydroPump, p::Resource)
Returns the input resources of a HydroPump n
, specified via the fields water_resource
and electricity_resource
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
EnergyModelsBase.outputs
— Functionoutputs(n::HydroReservoir)
outputs(n::HydroReservoir, p::Resource)
Returns the output resources of a HydroReservoir n
, specified via the field stor_res
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
outputs(n::HydroGate)
outputs(n::HydroGate, p::Resource)
Returns the output resources of a HydroGate n
, specified via the field resource
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
outputs(n::HydroGenerator)
outputs(n::HydroGenerator, p::Resource)
Returns the output resources of a HydroGenerator n
, specified via the fields water_resource
and electricity_resource
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
outputs(n::HydroPump)
outputs(n::HydroPump, p::Resource)
Returns the output resources of a HydroPump n
, specified via the field water_resource
.
If the resource p
is specified, it returns a value of 1. This behaviour should in theory not occur.
EMB.outputs(n::ReserveBattery)
EMB.outputs(n::ReserveBattery, p::Resource)
When the node is an ReserveBattery
, it returns both the output and reserve resources.
If the resource p
is specified, it returns the value if the resource is in the output dictionary. Otherwise, it returns a value of 0.