Methods - EMB

Index

Extension methods

EnergyModelsBase.variables_nodeFunction
EMB.variables_node(m, 𝒩ⁿᵈʳ::Vector{<:AbstractNonDisRES}, 𝒯, modeltype::EnergyModel)

Creates the following additional variables for ALL AbstractNonDisRES nodes:

  • :curtailment[n, t] is the unused energy within operational period t.
source
EMB.variables_node(m, 𝒩::Vector{<:HydroStorage}, 𝒯, modeltype::EnergyModel)

Creates the following additional variables for ALL HydroStorage nodes:

  • :hydro_spill[n, t] is the spilled energy from node n in operational period t without pproducing energy. It is included to avoid infeasible models.
source
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 gate n in operational period t for resource p.
  • gate_penalty_down[n, t, p] is the down penalty variable of hydro gate n in operational period t for resource p.

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.

source
EMB.variables_node(m, 𝒩::Vector{<:HydroReservoir}, 𝒯, modeltype::EnergyModel)

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 reservoir n in operational period t for resource p.
  • rsv_penalty_down[n, t, p] is the down penalty variable of hydro reservoir n in operational period t for resource p.

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.

source
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 unit n in operational period t for resource p.
  • rsv_penalty_down[n, t, p] is the down penalty variable of hydro unit n in operational period t for resource p.
  • discharge_segment[n, t, q] is the discharge segment variable of hydro unit n in operational period t for discharge segment q The capacity of the discharge_segments 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.

source
EMB.variables_node(m, 𝒩::Vector{<:AbstractBattery}, 𝒯, modeltype::EnergyModel)

Creates the following additional variables for ALL AbstractBattery nodes

  • bat_prev_use[n, t] is the accumulated charge effect of an AbstractBattery up to operational period t.
  • bat_prev_use_sp[n, t_inv] is the accumulated charge effect of an AbstractBattery up to investment period t_inv.
  • bat_use_sp[n, t_inv] is the accummulated charge effect of an AbstractBattery in investment period t_inv.
  • bat_use_rp[n, t_rp] is the accummulated charge effect of an AbstractBattery in representative period t_rp. It is only declared if the TimeStructure includes RepresentativePeriods.
  • 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 an AbstractBatteryLife that includes degradation.
source
EMB.variables_node(m, 𝒩::Vector{<:ReserveBattery}, 𝒯, modeltype::EnergyModel)

Creates the following additional variables for ALL ReserveBattery nodes

  • bat_res_up[n, t] is the upwards reserve of battery storage n in operational period t.
  • bat_res_down[n, t] is the upwards reserve of battery of storage n in operational period t.
source
EnergyModelsBase.create_nodeFunction
EMB.create_node(m, n::HydroStorage, 𝒯, 𝒫, modeltype::EnergyModel)

Sets all constraints for the regulated hydro storage node.

It differs from the function for a standard RefStorage node through not calling the function constraints_flow_out but incorporating the outflow constraints directly.

Called constraint functions

source
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

source

Constraint methods

EnergyModelsBase.constraints_capacityFunction
EMB.constraints_capacity(m, n::AbstractNonDisRES, 𝒯::TimeStructure, modeltype::EnergyModel)

Method for creating the constraint on the maximum capacity of an AbstractNonDisRES.

The difference to the default method is the inclusion of :curtailment within the energy balance.

source
EMB.constraints_capacity(m, n::AbstractBattery, 𝒯::TimeStructure, modeltype::EnergyModel)

Method for creating the constraints on the maximum capacity of a generic 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.

source
EMB.constraints_capacity(m, n::HydroUnit, 𝒯::TimeStructure, modeltype::EnergyModel)

Methods 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.

Dispatching on this function

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.

source
EnergyModelsBase.constraints_flow_inFunction
EMB.constraints_flow_in(m, n::HydroStor, 𝒯::TimeStructure, modeltype::EnergyModel)
EMB.constraints_flow_in(m, n::PumpedHydroStor, 𝒯::TimeStructure, modeltype::EnergyModel)

Methods for creating the constraints on the inlet flow to a HydroStor or PumpedHydroStor.

When n::HydroStor, the variable :flow_in is fixed to 0 for all potential inputs.

When n::PumpedHydroStor, the variable :flow_in is multiplied with the inputs value to calculate the variable :stor_charge_use.

source
EMB.constraints_flow_in(m, n::HydroGenerator, 𝒯::TimeStructure, modeltype::EnergyModel)
EMB.constraints_flow_in(m, n::HydroPump, 𝒯::TimeStructure, modeltype::EnergyModel)

Method for creating the constraints on the inlet flow of a HydroGenerator and HydroPump.

`HydroGenerator`
  • 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.
`HydroPump`
  • The electricity flow to the unit is equal to the capacity utilization.
  • The water inlet flow is included in the function EMB.constraints_flow_out.
source
EnergyModelsBase.constraints_flow_outFunction
EMB.constraints_flow_out(m, n::ReserveBattery, 𝒯::TimeStructure, modeltype::EnergyModel)

Function for creating the constraint on the outlet flow from a ReserveBattery.

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.

source
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 of a HydroGenerator and HydroPump.

`HydroGenerator`
  • The electricity flow from the unit is equal to the capacity utilization.
  • The water inlet flow is included in the function EMB.constraints_flow_out.
`HydroPump`
  • 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.
source
EnergyModelsBase.constraints_level_auxFunction
EMB.constraints_level_aux(m, n::HydroStorage, 𝒯, 𝒫, modeltype)

Method for creating the Δ constraint for the level of a HydroStorage node.

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.

It furthermore uses the specification of the initial level in a strategic period.

source
EMB.constraints_level_aux(m, n::AbstractBattery, 𝒯, 𝒫, modeltype::EnergyModel)

Method for creating the Δ constraint for the level of a generic AbstractBattery.

It utilizes the efficiencies declared in inputs and outputs of the storage resource.

source
EMB.constraints_level_aux(m, n::HydroReservoir, 𝒯, 𝒫, modeltype::EnergyModel)

Method for creating the Δ constraint for the level of a HydroReservoir.

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.

source
EnergyModelsBase.constraints_opex_varFunction
EMB.constraints_opex_var(m, n::HydroReservoir{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 of the nodes used in the detailed hydro power modelling.

The individual methods extend the functions of EnergyModelsBase through incorporating the penalty term for constraint violation.

source
EnergyModelsBase.constraints_opex_fixedFunction
EMB.constraints_opex_fixed(m, n::AbstractBattery, 𝒯ᴵⁿᵛ, modeltype::EnergyModel)

Method 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.

source
EnergyModelsBase.constraints_ext_dataFunction
EMB.constraints_ext_data(m, n::HydroNode, 𝒯, 𝒫, modeltype::EnergyModel, data::ScheduleConstraint{MinSchedule})
EMB.constraints_ext_data(m, n::HydroNode, 𝒯, 𝒫, modeltype::EnergyModel, data::ScheduleConstraint{MaxSchedule})
EMB.constraints_ext_data(m, n::HydroNode, 𝒯, 𝒫, modeltype::EnergyModel, data::ScheduleConstraint{EqualSchedule})

Constraint functions for creating constraints regarding production schedule for the individual units within a waterway as declared through HydroNode. The constraints can either be hard (if the penalty is set to Inf) or soft (for any other value).

The chosen scheduling variables are identified using the function get_var_schedule while the capacity to which the profile should apply is identified through the function get_var_inst.

There exist several configurations:

source

Check methods

EnergyModelsBase.check_nodeFunction
EMB.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 the Source check).
  • The value of the field fixed_opex is required to be non-negative and accessible through a StrategicPeriod as outlined in the function check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles).
  • The values of the dictionary output are required to be non-negative (similar to the Source check).
  • The field profile is required to be in the range $[0, 1]$ for all time steps $t ∈ \mathcal{T}$.
source
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 field capacity in the type in the field charge is required to be non-negative if the chosen composite type has the field capacity.
  • The TimeProfile of the field capacity in the type in the field level is required to be non-negative`.
  • The TimeProfile of the field capacity in the type in the field discharge is required to be non-negative if the chosen composite type has the field capacity.
  • The TimeProfile of the field fixed_opex is required to be non-negative and accessible through a StrategicPeriod as outlined in the function check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles) for the chosen composite type .
  • The field output can only include a single Resource.
  • 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]$.
source
EMB.check_node(n::HydroReservoir, 𝒯, modeltype::EnergyModel, check_timeprofiles::Bool)

This method checks that the HydroReservoir node is valid.

Checks

  • The TimeProfile of the capacity of the HydroReservoir level is required to be non-negative.
  • The TimeProfile of the field fixed_opex is required to be non-negative and accessible through a StrategicPeriod as outlined in the function function EMB.check_fixed_opex() for the field level, if included.
  • The TimeProfile of the vol_inflow of the HydroReservoir is required to be non-negative.
source
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().

source
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 a StrategicPeriod as outlined in the function EMB.check_fixed_opex().
source
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 field capacity in the type in the field charge is required to be non-negative.
  • The TimeProfile of the field capacity in the type in the field level is required to be non-negative`.
  • The TimeProfile of the field capacity in the type in the field discharge is required to be non-negative.
  • The TimeProfile of the field fixed_opex is required to be non-negative and accessible through a StrategicPeriod as outlined in the function check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles) for the chosen composite type .
  • The field output can only include a single Resource.
  • 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 function check_battery_life.
source
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 field capacity in the type in the field charge is required to be non-negative.
  • The TimeProfile of the field capacity in the type in the field level is required to be non-negative`.
  • The TimeProfile of the field capacity in the type in the field discharge is required to be non-negative.
  • The TimeProfile of the field fixed_opex is required to be non-negative and accessible through a StrategicPeriod as outlined in the function check_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles) for the chosen composite type .
  • The field output can only include a single Resource.
  • 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 dictionaries input and output.
  • The resources in the array reserve_down cannot be part of the resources in the dictionaries input and output.
source
EnergyModelsBase.check_node_dataFunction
EMB.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}$.
source

Field extraction methods

EnergyModelsBase.inputsFunction
inputs(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.

source
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.

source
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.

source
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.

source
EnergyModelsBase.outputsFunction
outputs(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.

source
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.

source
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.

source
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.

source
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.

source