kernel¶
This module defines kernel functions for shipp.
The functions defined in this module are used to solve the dispatch optimization problem with scipy.optimize.linprog or with a rule-based approach. They build the matrices describing the linear optimization from scratch. For complex problems, the use of the functions in kernel_pyomo is prefered.
- Functions:
build_lp_obj_npv: Build objective vector for NPV maximization.
build_lp_cst_sparse: Build sparse constraints for a LP.
solve_lp_sparse: Build and solve a LP for NPV maximization.
os_rule_based: Build the operation schedule with a rule-based EMS
Module Contents¶
Functions¶
Build the objective function vector for NPV maximization for the LP formulation. |
|
Build the sparse constraints for the LP formulation of the dispatch optimization problem. |
|
Build and solve the integrated dispatch optimization problem, formulated as a linear program. |
|
Build the operation schedule following a rule-based control. |
Data¶
API¶
- kernel.TOL = 0.0001¶
- kernel.build_lp_obj_npv(price: numpy.ndarray, n: int, stor1_p_cost: float, stor1_e_cost: float, stor2_p_cost: float, stor2_e_cost: float, discount_rate: float, n_year: int) numpy.ndarray¶
Build the objective function vector for NPV maximization for the LP formulation.
This function returns an objective vector corresponding the maximization of Net Present Value (NPV):
f(x) = - factor*price*power + stor1_e_cost*stor1_e_cap + stor1_p_cost*stor1_p_cap + stor2_e_cost*stor2_e_cap + stor2_p_cost*stor2_p_cap
where factor = sum_n=1^(n_year) (1+discount_rate)**(-n). The objective function vector corresponds to the following design variables:
Power from storage 1, shape-(n,)
Power from storage 2, shape-(n,)
State of charge (energy) of storage 1, shape-(n+1,)
State of charge (energy) of storage 2, shape-(n+1,)
Power capacity of storage 1, shape-(1,)
Energy capacity of storage 1, shape-(1,)
Power capacity of storage 2, shape-(1,)
Energy capacity of storage 2, shape-(1,)
The number of design variables is n_x = 4*n+6
- Parameters:
price (np.array) – An array of electricity price to calculate the revenue [currency/MWh]
n (int) – the number of time steps [-]
stor1_p_cost (float) – cost of storage 1 per power capacity [currency/MW]
stor1_e_cost (float) – cost of storage 1 per energy capacity [currency/MWh]
stor2_p_cost (float) – cost of storage 2 per power capacity [currency/MW]
stor2_e_cost (float) – cost of storage 2 per energy capacity [currency/MWh]
discount_rate (float) – discount rate to calculate the NPV [-]
n_year (int) – number of years of operation of the project [-]
- Returns:
A shape-(n_x,) array representing the objective function of the linear program [-]
- Return type:
np.ndarray
- Raises:
AssertionError – if the length of the price is below n, if any input is not finite
- kernel.build_lp_cst_sparse(power: numpy.ndarray, dt: float, p_min, p_max: float, n: int, stor1_eff: float, stor2_eff: float, stor1_p_cap_max: float = -1.0, stor2_p_cap_max: float = -1.0, stor1_e_cap_max: float = -1.0, stor2_e_cap_max: float = -1.0, fixed_cap=False) tuple[scipy.sparse.coo_matrix, numpy.ndarray, scipy.sparse.coo_matrix, numpy.ndarray, numpy.ndarray, numpy.ndarray]¶
Build the sparse constraints for the LP formulation of the dispatch optimization problem.
Function to build the matrices and vectors for the constraints of the dispatch optimization problem, considering two different storage systems, and as a linear program. A sparse format is used to represent the matrices.
The constraints are made of equality and inequality constraints such that:
mat_eq * x = vec_eq
mat_ineq * x <= vec_ineq
bounds_lower <= x <= bounds_upper
With n the number of time steps, the problem is made of:
n_x = 4*n+6 design variables
n_eq = 2 equality constraints
n_ineq = 12*n+2 inequality constraints
The design variables for the linear problem are:
Power from storage 1, shape-(n,)
Power from storage 2, shape-(n,)
State of charge (energy) of storage 1, shape-(n+1,)
State of charge (energy) of storage 2, shape-(n+1,)
Power capacity of storage 1, shape-(1,)
Energy capacity of storage 1, shape-(1,)
Power capacity of storage 2, shape-(1,)
Energy capacity of storage 2, shape-(1,)
The equality constraints for the problem are:
Constraint to enforce the value of the first stored energy of storage 1 is equal to the last (size 1)
Constraint to enforce the value of the first stored energy of storage 2 is equal to the last (size 1)
The inequality constraints for the problem are:
Constraints on the minimum and maximum combined power from production and storage assets (size 2*n)
Constraints on the stored energy of storage 1 (size 2*n)
Constraints on the stored energy of storage 2 (size 2*n)
Constraints on the maximmum and minimum power to and from storage 1 (size 2*n)
Constraints on the maximmum and minimum power to and from storage 2 (size 2*n)
Constraints on the maximum stored energy in storage 1 (size n+1)
Constraints on the maximum stored energy in storage 2 (size n+1)
- Parameters:
power (np.ndarray) – A shape-(n,) array for the power production from renewables [MW].
dt (float) – time step [s].
p_min (float or np.ndarray) – A float or shape-(n,) array for the minimum required power production [MW].
p_max (float) – maximum power production [MW]
n (int) – number of time steps [-].
stor1_eff (float) – represents the round trip efficiency of storage 1 [-]. The losses are applied in discharge.
stor2_eff (float) – represents the round trip efficiency of storage 2 [-]. The losses are applied in discharge..
stor1_p_cap_max (float) – maximum power capacity for storage 1 [MW]. Default to -1.0 when there is no limit in power rate.
stor2_p_cap_max (float) – maximum power capacity for storage 2 [MW]. Default to -1.0 when there is no limit in power rate.
stor1_e_cap_max (float) – maximum energy capacity for storage 1 [MWh]. Default to -1.0 when there is no limit.
stor2_e_cap_max (float) – maximum energy capacity for storage 2 [MWh]. Default to -1.0 when there is no limit.
- Returns:
[mat_eq, vec_ec, mat_ineq, vec_ineq, bounds_lower, bounds_upper] matrices and vectors representing the inequality, equality and bound constraints of the problem.
- Return type:
tuple[sps.coo_matrix, np.ndarray, sps.coo_matrix, np.ndarray, np.ndarray, np.ndarray]
- Raises:
ValueError – if argument p_min is not a float or a list of floats
AssertionError – if any argument is not finite and if the argument power has a length lower than n
- kernel.solve_lp_sparse(price_ts: shipp.timeseries.TimeSeries, prod1: shipp.components.Production, prod2: shipp.components.Production, stor1: shipp.components.Storage, stor2: shipp.components.Storage, discount_rate: float, n_year: int, p_min, p_max: float, n: int, fixed_cap: bool = False) shipp.components.OpSchedule¶
Build and solve the integrated dispatch optimization problem, formulated as a linear program.
This function builds and solves the hybrid sizing and operation problem as a linear program. The objective is to minimize the Net Present Value of the plant. The optimization problem finds the optimal energy and power capacity of two storage systems and their optimal dispatch. In this function, the power production inputs are represented by two Production objects (e.g. one for wind and one for solar PV).
- Parameters:
price_ts (TimeSeries) – Time series of the price of electricity on the day-ahead market [currency/MWh].
prod1 (Production) – Object representing the power production of the first production asset.
prod2 (Production) – Object representing the power production of the second production asset.
stor1 (Storage) – Object describing storage 1.
stor2 (Storage) – Object describing storage 2.
discount_rate (float) – Discount rate for the NPV calculation [-].
n_year (int) – Number of years for the NPV calculation [-].
p_min (float or np.ndarray) – Minimum power requirement (e.g. baseload) [MW].
p_max (float) – Maximum power requirement [MW].
n (int) – Number of time steps to consider in the optimization.
fixed_cap (bool) – If True, the capacity of the storage is fixed.
- Returns:
Object describing the optimal operational schedule and optimal storage capacities.
- Return type:
- Raises:
AssertionError – if the time step of the power and price time series do not match, if the length of the power in the Production objects is below n.
RuntimeError – if the optimization algorithm fails to solve the problem.
- kernel.os_rule_based(price_ts: shipp.timeseries.TimeSeries, prod1: shipp.components.Production, prod2: shipp.components.Production, stor1: shipp.components.Storage, stor2: shipp.components.Storage, discount_rate: float, n_year: int, p_min, p_rule: float, price_min: float, n: int, e_start: float = 0) shipp.components.OpSchedule¶
Build the operation schedule following a rule-based control.
This function builds the operation schedule for a hybrid power plant following a rule-based approach. The objective of the controller is to satisfy a baseload power represented by p_min. The control rules are as follow:
if the power produced is above a given value (p_rule), the storage systems are charged.
if the power produced is below p_rule but above the baseload, and if the price is above a threshold (price_min), the storage systems should sell power
if the power output is below the required baseload, power is delivered from the storage systems.
This implementation is based on the work by Jasper Kreeft for the sizing of the Baseload Power Hub.
- Parameters:
price_ts (TimeSeries) – Time series of the price of electricity on theday-ahead market [currency/MWh].
prod1 (Production) – Object describing the first production asset.
prod2 (Production) – Object describing the second production asset.
stor1 (Storage) – Object describing storage 1.
stor2 (Storage) – Object describing storage 2.
discount_rate (float) – Discount rate for the NPV calculation [-].
n_year (int) – Number of years for the NPV calculation [-].
p_min (float or np.ndarray) – Minimum power requirement [MW].
p_rule (float) – Power above which the storage should charge [MW].
price_min (float) – Price above which the storage should discharge [currency]
n (int) – Number of time steps to consider simulation.
- Returns:
Object describing the operational schedule.
- Return type:
- Raises:
AssertionError – if the time step of the power and price time series do not match.