kernel_pyomo#

This module defines kernel functions for shipp.

The functions defined in this module are used to analyze or compute data for the classes defined in shipp.

Functions:

solve_lp_pyomo: Build and solve a linear program (LP) for NPV maximization with pyomo. run_storage_operation: Run a series of online dispatch optimization problems. solve_dispatch_pyomo: Build and solve a MILP for the dispatch optimization of storage systems considering reliability.

Module Contents#

Functions#

solve_lp_pyomo

Build and solve an integrated dispatch NPV maximization with pyomo as a linear program.

run_storage_operation

Execute a storage operation simulation.

solve_dispatch_pyomo

Build and solve a MILP for the dispatch optimization of storage systems, with dispatch constraints.

Data#

API#

kernel_pyomo.TIME_LIMIT_SHORT = 2#
kernel_pyomo.TIME_LIMIT_LONG = 180#
kernel_pyomo.DEFAULT_ALPHA_OBJ = None#
kernel_pyomo.solve_lp_pyomo(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_max: float, n: int, p_min: float = 0, dp_min=None, dp_max=None, options: dict = None) → shipp.components.OpSchedule#

Build and solve an integrated dispatch NPV maximization with pyomo 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 input for the power production represented by two Production objects. The problem can be constrained by a baseload power production constraint or a ramp limitation constraint.

Parameters:
  • price_ts (TimeSeries) – Time series of the price of electricity on the day-ahead market [currency/MWh].

  • prod1 (Production) – Object representing the first power production asset.

  • prod2 (Production) – Object representing the second power 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_max (float) – Maximum power requirement [MW].

  • n (int) – Number of time steps to consider in the optimization.

  • p_min (float or np.ndarray) – Minimum power requirement [MW].

  • dp_min (float) – Limit for the ramp limitation [MW/h] (down, should be negative)

  • dp_max (float) – Limit for the ramp limitation [MW/h] (up, should be positive)

  • options (dict) –

    list of options for the problem formulation

    • name_solver (str): Name of optimization solver to be used with pyomo. Default is ‘mosek’.

    • fixed_cap (bool): True if the storage capacity is fixed during the optimization. Default is False.

    • alpha_obj (float): penalty factor for the curtailed power in the objective function proportional to the price. Default is (1+1e-6)

    • beta_obj (float): penalty factor for the curtailed power in the objective function. Default is 0

    • e_start1 (float): initial state-of-charge for storage 1. If None, the initial state-of-charge is not constrained. Default is None.

    • e_start2 (float): initial state-of-charge for storage 2. If None, the initial state-of-charge is not constrained. Default is None.

    • verbose (bool): If true, prints the output of the optimization algorithm.

    • return_duals (bool): If true, the function returns the dual variable of the linear optimization (in OpSchedule.dual_prices).

Returns:

Object describing the optimal operational schedule and storage size.

Return type:

OpSchedule

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_pyomo.run_storage_operation(run_type: str, power: list, price: list, p_max: float, stor: shipp.components.Storage, e_start: float, n: int, nt: int, dt: float, forecast: list = None, p_min: float = 0, dp_min=None, dp_max=None, rel: float = 1.0, options: dict = None) → dict#

Execute a storage operation simulation.

This function simulates the dispatch operation of a storage system. It supports rule-based operation, and dispatch optimization based on point and ensemble forecast as well as unlimited information to determine the power and energy levels of the storage system over a given time horizon. The problem can be constrained by a baseload power production constraint or a down-ramp limitation constraint.

Parameters:
  • run_type (str) –

    The type of operation to run. Options are ‘unlimited’, ‘rule-based’, or ‘forecast’.

    • ’unlimited’: Solves a optimization problem with unlimited and perfect information to maximize revenues, over a defined time window.

    • ’rule-based’: Uses predefined rules for storage operation based on thresholds for power and price.

    • ’forecast’: Considers a rolling horizon with a new power forecast at each time step.

  • power (list) – A list of power values (e.g., renewable generation) over the time horizon [MW]

  • price (list) – A list of price values over the time horizon. [currency/MW]

  • p_max (float) – Maximum power threshold for the storage operation. [MW]

  • stor (Storage) – The storage object containing storage parameters (e.g., capacity, efficiency).

  • e_start (float) – Initial energy level in the storage [MWh].

  • n (int) – Number of time steps for the forecast.

  • nt (int) – Number of time steps in the simulation.

  • dt (float) – Time step duration in hours.

  • forecast (list, optional) – Forecasted power scenarios for the ‘forecast’ run type [MW]. Default is None.

  • p_min (float, optional) – Minimum power threshold for the storage operation. [MW]

  • dp_min (float, optional) – Limit for the ramp-limitation constraint (down) [MW/h]

  • dp_max (float, optional) – Limit for the ramp-limitation constraint (up) [MW/h]

  • rel (float, optional) – Reliability threshold for the operation. Default is 1.0.

  • options (dict) –

    list of options for the optimization problem formulation

    • name_solver (str): Name of optimization solver to be used with pyomo. Default is ‘mosek’.

    • alpha_obj (float): factor in the objective function to adjust the relative weight of curtailement and storage power.

    • beta_obj (float): penalty term in the objective function for the energy level at the last time step.

    • mu (float): penalty term in the objective function for the reliability penalties.

    • n_hist (int): Number of historical time steps to consider for reliability in the ‘forecast’ run type. Default is 0.

    • verbose (bool, optional): If True, enables verbose output during the simulation. Default is False.

Returns:

A dictionary containing the results of the storage operation simulation:

  • ’power’ (list): Power output of the storage over the time horizon.

  • ’energy’ (list): Energy levels of the storage over the time horizon.

  • ’reliability’ (float): Reliability of the operation (fraction of time steps meeting the power threshold).

  • ’revenues’ (float): Total revenues from the storage operation.

  • ’p_cur’ (list): Curtailed power over the time horizon.

  • ’bin’ (list): Binary indicators for whether the power constraint (baseload and/or ramp-limitation) was met at each time step.

Return type:

dict

Raises:
  • RuntimeError – If an invalid run_type is provided.

  • AssertionError – If forecast is None when run_type is ‘forecast’.

kernel_pyomo.solve_dispatch_pyomo(price: list, m: int, rel: float, n: int, power_forecast: list, p_max: float, e_start1: float, e_start2: float, dt: float, stor1: shipp.components.Storage, stor2: shipp.components.Storage, p_min: float = 0, dp_min: float = None, dp_max: float = None, cnt_hist: int = 0, p_hist_res: float = 0, p_hist_stor: float = 0, options: dict = None) → tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, pyomo.environ.SolverStatus]#

Build and solve a MILP for the dispatch optimization of storage systems, with dispatch constraints.

This function builds and solves the dispatch optimization problem for two storage systems operating with dispatch constraints (baseload or ramp limitation) as a mixed integer linear program. The objective is to maximize the income of the storage system (i.e. revenues on the spot market). Constraints are set to respect the dispatch constraints. In order to ensure feasibility of the problem, the reliability of the dispatch constraints is added as a design variable to relax the constraints. A term in the objective function is added to maximize reliability.

Parameters:
  • price (list) – Price of electricity on the day-ahead market [currency/MWh].

  • m (int) – Number of forecast scenarios.

  • rel (float) – Percentage of baseload reliability required.

  • n (int) – Number of time steps to consider in the optimization (i.e. forecast lead-time)

  • power_forecast (list) – Forecasted power scenarios for the optimization.

  • p_max (float) – Maximum power [MW].

  • e_start1 (float) – Initial energy level in the first storage system [MWh].

  • e_start2 (float) – Initial energy level in the second storage system [MWh].

  • dt (float) – Time step duration in hours.

  • stor1 (Storage) – Object describing the first storage system (e.g., battery storage).

  • stor2 (Storage) – Object describing the second storage system (e.g., hydrogen storage).

  • cnt_hist (int, optional) – Number of time steps meeting the dispatch constraint within the time window for past operation. Default is 0.

  • p_min (float) – Minimum baseload power requirement [MW].

  • dp_min (float) – Limit for the ramp limitation [MW/h] (down)

  • dp_max (float) – Limit for the ramp limitation [MW/h] (up)

  • p_hist_res (float) – value of the power produced at the previous time step.

  • p_hist_stor (float) – value of the storage power at the previous time step.

  • options (dict) –

    list of options for the problem formulation

    • name_solver (str): Name of optimization solver to be used with pyomo. Default is ‘mosek’.

    • verbose (bool): If true, prints the output of the optimization algorithm. Default is False.

    • alpha_obj (float): penalty factor for the curtailed power in the objective function proportional to the price. Default is (1-1e-6).

    • beta_obj (float): penalty factor for the curtailed power in the objective function. Default is 0.

    • mu1_obj (float): penalty term in the objective function for the reliability penalty. Default is 1.

    • mu2_obj (float): penalty term in the objective function for the mismatch to the baseload constraint at first time step. Default is None.

    • mu3_obj (float): penalty term in the objective function for the mismatch to the ramp constraint at first time step. Default is None.

    • gamma_obj (float): penalty term in the objective function for the energy level at the last time step. Default is 1e-6.

    • tol (float): tolerance for checking the input validity and storage losses.

    • n_hist (int): Number of time steps for the time window for past operation. Default is 0.

Returns:

A tuple containing the following elements:
  • p_vec1 (np.ndarray): Power output of the first storage system over the time horizon.

  • e_vec1 (np.ndarray): Energy levels of the first storage system over the time horizon.

  • p_vec2 (np.ndarray): Power output of the second storage system over the time horizon.

  • e_vec2 (np.ndarray): Energy levels of the second storage system over the time horizon.

  • p_cur (np.ndarray): Curtailed power over the time horizon.

  • bin (np.ndarray): Binary indicators for whether the power threshold was met at each time step.

  • results.solver.status: Solver status indicating the outcome of the optimization.

Return type:

tuple

Raises:

RuntimeError – If the optimization algorithm fails to solve the problem.