osier.DispatchModel#
- class osier.DispatchModel(technology_list, net_demand, time_delta=None, solver='cbc', lower_bound=0.0, oversupply=0.0, undersupply=0.0, verbosity=50, penalty=1e-10, power_units=MW, curtailment=True, allow_blackout=False, **kwargs)[source]#
Bases:
objectThe
DispatchModelclass creates and solves a basic dispatch model from the perspective of a “grid operator.” The model uses pyomo to create and solve a linear programming model. The mathematical formulation for this problem is:Minimize
\[\text{C}_{\text{total}} = \sum_t^T \sum_u^U \left[c^{\text{fuel}}_{u,t} + c^{\text{om,var}}_{u,t}\right]x_{u,t}\]Such that,
1. The generation meets demand within a user-specified tolerance (undersupply and oversupply)
\[ \begin{align}\begin{aligned}\sum_u^Ux_{u,t} &\geq \left(1-\text{undersupply}\right)\text{D}_t \ \forall \ t \in T\\\sum_u^Ux_{u,t} &\leq \left(1+\text{oversupply}\right)\text{D}_t \ \forall \ t \in T\end{aligned}\end{align} \]2. A technology’s generation (\(x_u\)) does not exceed its capacity to generate at any time, \(t\).
\[x_{u,t} \leq \textbf{CAP}_{u}\Delta t \ \forall \ u,t \in U,T\]Technologies may not exceed their ramp up rate,
\[\frac{x_{r,t} - x_{r,t-1}}{\Delta t} = \Delta P_{r,t} \leq (\text{ramp up})\textbf{CAP}_u\Delta t \ \forall \ r,t \in R \subset U, T\]or ramp down rate,
\[\frac{x_{r,t} - x_{r,t-1}}{\Delta t} = \Delta P_{r,t} \leq -(\text{ramp down})\textbf{CAP}_u\Delta t \ \forall \ r,t \in R \subset U, T .\]- Parameters:
technology_list (list of
osier.Technology) – The list ofTechnologyobjects to dispatch – i.e. decide how much energy each technology should produce.net_demand (list,
numpy.ndarray,unyt.array.unyt_array,pandas.DataFrame) – The remaining energy demand to be fulfilled by the technologies intechnology_list. The values of an object passed as net_demand are used to create a supply constraint. Seeoversupplyandundersupply. If apandas.DataFrameis passed,osierwill try inferring a time_delta from the dataframe index. Otherwise, thetime_deltamust be passed or the default is used.time_delta (str,
unyt.unyt_quantity, float, int) –Specifies the amount of time between two time slices. The default is one hour. Can be overridden by specifying a unit with the value. For example:
>>> time_delta = "5 minutes" >>> from unyt import days >>> time_delta = 30*days
would both work.
power_units (str,
unyt.unit_object) – Specifies the units for the power demand. The default isMW. Can be overridden by specifying a unit with the value.solver (str) – Indicates which solver to use. May require separate installation. Accepts: [‘cplex’, ‘cbc’, ‘appsi_highs’]. Other solvers will be added in the future.
lower_bound (float) – The minimum amount of energy each technology can produce per time period. Default is 0.0.
oversupply (float) – The amount of allowed oversupply as a percentage of demand. Default is 0.0 (no oversupply allowed).
undersupply (float) – The amount of allowed undersupply as a percentage of demand. Default is 0.0 (no undersupply allowed).
verbosity (Optional, int) – Sets the logging level for the simulation. Accepts logging.LEVEL or integer where LEVEL is {10:DEBUG, 20:INFO, 30:WARNING, 40:ERROR, 50:CRITICAL}.
curtailment (boolean) – Indicates if the model should enable a curtailment option.
allow_blackout (boolean) – If True, a “reliability” technology is added to the model that will fulfill the mismatch in supply and demand. This reliability technology has a variable cost of 1e4 $/MWh. The value must be higher than the variable cost of any other technology to prevent a pathological preference for blackouts. Default is False.
- model#
The
pyomomodel class that converts python code into a set of linear equations.- Type:
pyomo.environ.ConcreteModel
- objective#
The result of the model’s objective function. Only instantiated after
DispatchModel.solve()is called.- Type:
- upper_bound#
The upper bound for all decision variables. Chosen to be equal to the maximum capacity of all technologies in
tech_set.- Type:
- penalty#
The penalty applied to the objective function to eliminate simultaneous charging and discharging. Users may need to tune this parameter. Default is 1e-10.
- Type:
- model_initialized#
Indicates whether
DispatchModel.modelhas been populated with equations yet. This is set toTrueafterDispatchModel._write_model_equations()has been called.- Type:
- indices#
The list of tuples representing the product of the
tech_setandtime_setattributes.- Type:
list of tuples
- time_set#
The result of
range(self.n_timesteps).- Type:
iterable
- cost_params#
The set of cost parameters for each technology. Corresponds to a list of values. Size is equal to the product of the number of timesteps and the number of technologies in the model.
- Type:
- ramp_up_params#
The set of ramp_up parameters. Only initialized if there is a ramping technology.
- Type:
- ramp_down_params#
The set of ramp_down parameters. Only initialized if there is a ramping technology.
- Type:
Notes
1. Technically,
solverwill accept any solver thatpyomocan use. We only list two solvers because those are the only solvers in theosiertest suite.2. The default value for
time_deltain__init__is None. This is replaced by a setter method inDispatch.3. This formulation uses a
penaltyparameter to prevent unphysical behavior because it preserves the problem’s linearity. Some formulations may use a binary variable to prevent simultaneous charging and discharing. However, this changes the problem to a mixed-integer linear program which requires a more sophisticated solver such asgurobi.4.
_write_model_equations()may be called beforesolve()if users wish to add their own constraints or parameters to the problem.Methods
solve([solver])Executes the model solve.