Methods - EMB
Index
EnergyModelsBase.check_nodeEnergyModelsBase.check_node_dataEnergyModelsBase.constraints_capacityEnergyModelsBase.constraints_ext_dataEnergyModelsBase.constraints_flow_inEnergyModelsBase.constraints_flow_outEnergyModelsBase.constraints_level_auxEnergyModelsBase.constraints_opex_fixedEnergyModelsBase.constraints_opex_varEnergyModelsBase.create_nodeEnergyModelsBase.inputsEnergyModelsBase.levelEnergyModelsBase.outputsEnergyModelsBase.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 gatenin operational periodtfor resourcep.gate_penalty_down[n, t, p]is the down penalty variable of hydro gatenin operational periodtfor 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}, 𝒯, 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 reservoirnin operational periodtfor resourcep.rsv_penalty_down[n, t, p]is the down penalty variable of hydro reservoirnin operational periodtfor 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 unitnin operational periodtfor resourcep.rsv_penalty_down[n, t, p]is the down penalty variable of hydro unitnin operational periodtfor resourcep.discharge_segment[n, t, q]is the discharge segment variable of hydro unitnin operational periodtfor discharge segmentqThe capacity of thedischarge_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.
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 anAbstractBatteryup to operational periodt.bat_prev_use_sp[n, t_inv]is the accumulated charge effect of anAbstractBatteryup to investment periodt_inv.bat_use_sp[n, t_inv]is the accummulated charge effect of anAbstractBatteryin investment periodt_inv.bat_use_rp[n, t_rp]is the accummulated charge effect of anAbstractBatteryin representative periodt_rp. It is only declared if theTimeStructureincludesRepresentativePeriods.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 anAbstractBatteryLifethat 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 storagenin operational periodt.bat_res_down[n, t]is the upwards reserve of battery of storagenin 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)Returns the vol parameter field of the HydroReservoir n.
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.
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 water inlet flow is included in the function
EMB.constraints_flow_out.
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::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 water inlet flow is included in the function
EMB.constraints_flow_out.
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::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.
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.
EnergyModelsBase.constraints_ext_data — FunctionEMB.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:
MaxSchedulecorresponds to minimum constraints,MinSchedulecorresponds to maximum constraints, andEqualSchedulecorresponds to equality constraints.
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
capis required to be non-negative (similar to theSourcecheck). - The value of the field
fixed_opexis required to be non-negative and accessible through aStrategicPeriodas outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles). - The values of the dictionary
outputare required to be non-negative (similar to theSourcecheck). - The field
profileis 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
TimeProfileof the fieldcapacityin the type in the fieldchargeis required to be non-negative if the chosen composite type has the fieldcapacity. - The
TimeProfileof the fieldcapacityin the type in the fieldlevelis required to be non-negative`. - The
TimeProfileof the fieldcapacityin the type in the fielddischargeis required to be non-negative if the chosen composite type has the fieldcapacity. - The
TimeProfileof the fieldfixed_opexis required to be non-negative and accessible through aStrategicPeriodas outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)for the chosen composite type . - The field
outputcan only include a singleResource. - The value of the field
outputis required to be in the range $[0, 1]$. - The value of the field
inputis required to be in the range $[0, 1]$. - The value of the field
level_initis 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_initis required to be in the range $[0, 1]$. - The value of the field
level_minis 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
TimeProfileof thecapacityof theHydroReservoirlevelis required to be non-negative. - The
TimeProfileof the fieldfixed_opexis required to be non-negative and accessible through aStrategicPeriodas outlined in the function functionEMB.check_fixed_opex()for the fieldlevel, if included. - The
TimeProfileof thevol_inflowof theHydroReservoiris 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
capis required to be non-negative. - The value of the field
fixed_opexis 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
capis required to be non-negative. - The
PqPointsvectors are required to have the same length. - The
PqPointsvectors should start at 0. - The
PqPointsvectors are required to be increasing. - One of the
PqPointsvectors should have values between 0 and 1. - The
PqPointscurve should be concave for generators and convex for pumps. - The value of the field
fixed_opexis required to be non-negative and accessible through aStrategicPeriodas 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
TimeProfileof the fieldcapacityin the type in the fieldchargeis required to be non-negative. - The
TimeProfileof the fieldcapacityin the type in the fieldlevelis required to be non-negative`. - The
TimeProfileof the fieldcapacityin the type in the fielddischargeis required to be non-negative. - The
TimeProfileof the fieldfixed_opexis required to be non-negative and accessible through aStrategicPeriodas outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)for the chosen composite type . - The field
outputcan only include a singleResource. - The value of the field
inputis required to be in the range $[0, 1]$. - The value of the field
outputis required to be in the range $[0, 1]$ - The
AbstractBatteryLifemust 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
TimeProfileof the fieldcapacityin the type in the fieldchargeis required to be non-negative. - The
TimeProfileof the fieldcapacityin the type in the fieldlevelis required to be non-negative`. - The
TimeProfileof the fieldcapacityin the type in the fielddischargeis required to be non-negative. - The
TimeProfileof the fieldfixed_opexis required to be non-negative and accessible through aStrategicPeriodas outlined in the functioncheck_fixed_opex(n, 𝒯ᴵⁿᵛ, check_timeprofiles)for the chosen composite type . - The field
outputcan only include a singleResource. - The value of the field
inputis required to be in the range $[0, 1]$. - The value of the field
outputis required to be in the range $[0, 1]$ - The resources in the array
reserve_upcannot be part of the resources in the dictionaries dictionariesinputandoutput. - The resources in the array
reserve_downcannot be part of the resources in the dictionariesinputandoutput.
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
resourceis 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.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.