Renewables Case Study: Double Loop Optimization

[1]:
import pyomo.environ as pyo
import idaes

from dispatches_sample_data import rts_gmlc
from dispatches.case_studies.renewables_case.wind_battery_double_loop import MultiPeriodWindBattery
from dispatches.case_studies.renewables_case.double_loop_utils import *

for solver in ('xpress_direct', 'gurobi', 'cbc'):
    if pyo.SolverFactory(solver).available(exception_flag=False):
        milp_solver = solver
        break

Creating the Co-simulation of the Wind and Battery IES within the Production Cost Model with Bidder and Tracker Models

In the Conceptual Design Optimization Example Notebook, the design of a Wind + Battery + Hydrogen integrated energy system was optimized using the RTS-GMLC outputs with a “price taker” assumption. Here, we take one of the possible results, a Wind + Battery IES with no Hydrogen, and evaluate its performance in an electricity market by co-simulating its bidding and operation decisions within the production cost model, Prescient, in a “double-loop” optimization.

This double-loop is performed by embedding the multiperiod Wind + Battery flowsheet model as a MultiPeriodWindBattery within a Bidder and a Tracker model, whose functions are to optimize the Day-ahead or Real-time energy market bids, and to optimize the operation of the IES to follow the cleared market’s dispatch, respectively. These functions are coordinated in order and with the correct data transfers with Prescient by a DoubleLoopCoordinator class. Prescient is then able to evaluate the economic performance of the designed IES within the grid with market interactions and forecast uncertainty. The steps are as shown in this diagram:

DoubleLoopOptimization.png

In the Day-ahead loop, the Unit Commitment Problem is solved by forecasting loads and obtaining generator bids, and produces hourly schedules and LMPs. The Bidder will use forecasts and plant information to optimize the DA bid to Prescient.

In the Real-time loop, the Economic Dispatch Problem is solved using real-time loads and resources to produce updated generator dispatch points and commitments. The Bidder will use forecasts, DA dispatch and prices, and plant information to optimize the updated RT bid. Once the Real-time market is cleared, the Tracker controls the IES to implement the dispatch at lowest cost.

The market participants are paid on energy and/or reserve provided based on the two-settlement system:

\[R = Q_{DA} \times P_{DA} + (Q_{RT} - Q_{DA}) \times P_{RT}\]

where \(R\) is revenue, \(Q_{DA}\) is power sold to DA market at \(P_{DA}\) price, and \(Q_{RT}\) is power delivered to RT market at \(P_{RT}\) price.

First, we define the electricity grid for the double-loop simulation via options to Prescient: the directory to the RTS-GMLC source data, the time horizons for the UC and ED problems, the start date and length of the simulation, how much reserves should be procured, etc. The full-year PCM simulation was completed prior and the outputs were collected into a 309_WIND_1-SimulationOutputs.csv in order to provide “historical” LMPs and Wind resource capacity factors for the Conceptual Design Optimization.

In this example, we will repeat the Prescient simulation with no reserves for a single week, where the Wind + Battery IES will replace the 309_WIND_1 Wind plant at the “Carter” bus.

[2]:
from prescient.simulator import Prescient
import os

TESTING_MODE = bool(os.environ.get("DISPATCHES_TESTING_MODE", None))

sim_days = 7
start_date = "01-02-2020"
day_ahead_horizon = 28
real_time_horizon = 4
output_dir = Path(f"double_loop_results")

wind_bus = 309
wind_bus_name = "Carter"
wind_generator = f"{wind_bus}_WIND_1"

prescient_options = {
    "data_path": rts_gmlc.source_data_path,
    "input_format": "rts-gmlc",
    "simulate_out_of_sample": True,
    "run_sced_with_persistent_forecast_errors": True,
    "output_directory": output_dir,
    "start_date": start_date,
    "num_days": 7 if not TESTING_MODE else 1,
    "sced_horizon": real_time_horizon,
    "ruc_horizon": day_ahead_horizon,
    "ruc_every_hours": 24,
    "compute_market_settlements": True,
    "day_ahead_pricing": "LMP",
    "ruc_mipgap": 0.05 if not TESTING_MODE else 0.5,
    "symbolic_solver_labels": True,
    "reserve_factor": 0,
    "deterministic_ruc_solver": milp_solver,
    "sced_solver": milp_solver,
    "plugin": {
        "doubleloop": {
            "module": None,                                          # to be added below
            "bidding_generator": wind_generator,
        }
    }
}

# collect "historical" full-year wind forecast and first-day LMPs
prescient_outputs_df = pd.read_csv(Path(os.path.realpath("__file__")).parent / "data" / "309_WIND_1-SimulationOutputs.csv")
prescient_outputs_df.index = pd.to_datetime(prescient_outputs_df['Unnamed: 0'])
prescient_outputs_df = prescient_outputs_df[prescient_outputs_df.index >= pd.Timestamp(f'{start_date} 00:00:00')]
gen_capacity_factor = prescient_outputs_df[f"{wind_generator}-RTCF"].values.tolist()
historical_da_prices = {
    wind_bus_name: prescient_outputs_df[f"LMP DA"].values[0:24].tolist()
}
historical_rt_prices = {
    wind_bus_name: prescient_outputs_df[f"LMP"].values[0:24].tolist()
}
Interactive Python mode detected; using default matplotlib backend for plotting.
[3]:
from matplotlib.ticker import MultipleLocator
import matplotlib.pyplot as plt
plt.rcParams.update({'font.size': 16, 'axes.titlesize': 16, 'axes.labelsize': 14})

def format_plt(fig, ax, titles, suptitle=None, mod_ticks=True, y_labels=None):
    if not y_labels:
        y_labels = ["Power [MW]"] * len(ax)
    for i in range(len(ax)):
        if mod_ticks:
            ax[i].xaxis.set_minor_locator(MultipleLocator(4))
            ax[i].xaxis.set_major_locator(MultipleLocator(24))
            ax[i].tick_params(axis='both', which='major', labelsize="small")
            ax[i].tick_params(axis='both', which='minor', labelsize="small")
        ax[i].legend()
        ax[i].set_ylabel(y_labels[i])
        ax[i].set_xlabel("Time [hr]")
        ax[i].set_title(titles[i])
    fig.autofmt_xdate(rotation=45)
    if suptitle:
        fig.suptitle(suptitle)
    fig.tight_layout()

time_index = prescient_outputs_df[prescient_outputs_df.index <= prescient_outputs_df.index[24 * sim_days]].index
orig_outputs_df = prescient_outputs_df[prescient_outputs_df.index.isin(time_index)].copy()
orig_outputs_df['Penalized DA Underdelivered [MW]'] = (orig_outputs_df['Output DA'] - orig_outputs_df['Output']) * (orig_outputs_df['LMP'] > orig_outputs_df['LMP DA'])
orig_outputs_df.loc[:, 'Penalized DA Underdelivered [MW]'].clip(lower=0, inplace=True)
orig_outputs_df['Curtailment'] *= -1

fig, ax = plt.subplots(2, 1, figsize=(24, 10), sharex=True)
ax[0].plot(orig_outputs_df['Output DA'].values, drawstyle="steps-mid", label='DA Dispatch [MW]', color='grey')
ax[0].plot(orig_outputs_df['Output'].values, drawstyle="steps-mid", label='RT Dispatch [MW]', color='k')
cols = ['Output', 'Penalized DA Underdelivered [MW]']
orig_outputs_df[cols].plot(kind='bar', width=1, stacked=True, ax=ax[0], color=['b', 'r'])
orig_outputs_df['Curtailment'].plot(kind='bar', width=1, stacked=True, ax=ax[1])
format_plt(fig, ax, titles=["Wind Output vs Dispatch", "Wind Curtailment"], suptitle="Original RTS-GMLC Simulation")
../_images/examples_DoubleLoopOptimization_4_0.png

The above plot shows the wind plant’s DA Dispatch, RT Dispatch, Wind Power Output, Penalized DA Underdelivered, and Wind Curtailment in MW for the first week. The DA and RT Dispatch profiles are from the final solution of Prescient’s staggered and forward-rolling UC and ED problems, and are based on the day-ahead and real-time wind forecast, respectively.

The Wind Power Output is the real-time wind production of the wind plant, and matches the RT Dispatch exactly. However, since there was uncertainty of the RT wind resource during the DA bid, the DA Dispatch is different. According to the two-settlement system revenue equation above, the wind plant will be charged the RT LMP for the difference between the promised DA Dispatch and the delivered RT power. The Penalized DA Underdelivered profile show the power that was underdelivered when RT LMPs were higher than DA LMPs and resulted in some negative revenue for the plant.

The second plot below shows the Hourly and Cumulative revenue of the wind plant.

[4]:
fig, ax = plt.subplots(2, 1, figsize=(24, 10), sharex=True)

orig_outputs_df['Penalized DA Underdelivered [MW]'].plot(ax=ax[0], color='r', kind='bar', width=1)
ax0 = ax[0].twinx()
ax0.set_yscale('symlog')
ax0.plot(orig_outputs_df['LMP DA'].values, label="LMP DA [$/MWh]")
ax0.plot(orig_outputs_df['LMP'].values, label='LMP RT [$/MWh]')
ax0.legend(loc='upper right')
ax0.grid(None)
ax0.set_ylabel("LMP [$/MWh]")
ax[1].set_yscale('symlog')
ax[1].plot(orig_outputs_df['Unit Market Revenue'].values, color='k', linestyle=':', label="Market Revenue [$]")
ax[1].plot(orig_outputs_df['Unit Market Revenue'].cumsum().values, color='k', label="Cumulative Market Revenue [$]")

format_plt(fig, ax, y_labels=['Power [MW]', 'Revenue [$]'], titles=["LMPs at Missed DA Promises", "Market Revenue"], suptitle="Original RTS-GMLC Simulation")
ax[0].legend(loc='upper left')
[4]:
<matplotlib.legend.Legend at 0x7f9611a6cdc0>
../_images/examples_DoubleLoopOptimization_6_1.png

Creating the IES Generator within the RTS-GMLC

First, the location, type, capacity, and other parameters of the IES needs to be defined in order to situate the generator within the electricity market. In this example, the IES’ bid will be represented as that of a thermal generator, with parameters such as min power, max power, ramping constraints, startup and shutdown capacity, even though the IES will not need them all. The wind resource at the chosen location, at the “Carter” bus, is read from the RTS-GMLC Source Data.

The information is passed to the MultiPeriodWindBattery class, which enables the Bidder and Tracker to construct a Wind + Battery multiperiod model within its bidding and tracking optimization problems via populate_model, and to update the state of the Wind + Battery IES as the double-loop steps forward in time via update_model.

[5]:
from idaes.apps.grid_integration.model_data import ThermalGeneratorModelData

p_min = 0
wind_pmax = 147.6
battery_pmax = 25
battery_emax = battery_pmax * 4

# for descriptions on what each parameter means, see `help(ThermalGeneratorModelData)`
thermal_generator_params = {
    "gen_name": wind_generator,
    "bus": wind_bus_name,
    "p_min": p_min,
    "p_max": wind_pmax,
    "min_down_time": 0,
    "min_up_time": 0,
    "ramp_up_60min": wind_pmax + battery_pmax,
    "ramp_down_60min": wind_pmax + battery_pmax,
    "shutdown_capacity": wind_pmax + battery_pmax,
    "startup_capacity": 0,
    "initial_status": 1,
    "initial_p_output": 0,
    "production_cost_bid_pairs": [(p_min, 0), (wind_pmax, 0)],
    "startup_cost_pairs": [(0, 0)],
    "fixed_commitment": 1,
}
model_data = ThermalGeneratorModelData(**thermal_generator_params)

mp_wind_battery_bid = MultiPeriodWindBattery(
    model_data=model_data,
    wind_capacity_factors=gen_capacity_factor,
    wind_pmax_mw=wind_pmax,
    battery_pmax_mw=battery_pmax,
    battery_energy_capacity_mwh=battery_emax,
)

Creating the Forecaster, Tracker, and Bidder for the DoupleLoopCoordinator

The Bidder requires a forecast of the DA and RT prices in order to plan out its energy bid: at what time to sell how much energy and at what price, given the anticipated wind resource and the evolution of the battery state-of-charge. In contrast to the price-taker assumption in the Conceptual Design phase where the Wind + Battery IES took the historical LMPs for however much energy it sold, here, the Bidder does not know what the final LMP will be, nor that its bid for energy at a certain marginal cost will be accepted by the market.

The Backcaster class stores historical DA and RT LMPs in order to generate forecast scenarios. The first day of simulated DA and RT LMPs initializes the Backcaster, which continues to collect resolved LMPs as the simulation steps forward in time.

Within the DoubleLoopCoordinator, there are two Tracker objects, the first tracker follows the real-time market signals whereas the second projection_tracker projects the latest real-time dispatch onto the next day-ahead bidding problem.

[6]:
from idaes.apps.grid_integration.forecaster import Backcaster
from idaes.apps.grid_integration import Tracker, Bidder
from dispatches.workflow.coordinator import DoubleLoopCoordinator

# Backcaster
# help(Backcaster)
backcaster = Backcaster(historical_da_prices, historical_rt_prices)
[7]:
n_price_scenario = 3
solver = pyo.SolverFactory(milp_solver)

# Bidder
# help(Bidder)
bidder_mp_wind_battery = MultiPeriodWindBattery(
    model_data=model_data,
    wind_capacity_factors=gen_capacity_factor,
    wind_pmax_mw=wind_pmax,
    battery_pmax_mw=battery_pmax,
    battery_energy_capacity_mwh=battery_emax,
)

bidder_object = Bidder(
    bidding_model_object=bidder_mp_wind_battery,
    day_ahead_horizon=day_ahead_horizon,
    real_time_horizon=real_time_horizon,
    n_scenario=n_price_scenario,
    solver=solver,
    forecaster=backcaster,
)
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.24] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:48 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:48 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.31] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.25] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.23] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.10] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:49 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.14] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:50 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:50 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[8]:
tracking_horizon = 4
n_tracking_hour = 1

# Tracker
# help(Tracker)
tracker_mp_wind_battery = MultiPeriodWindBattery(
    model_data=model_data,
    wind_capacity_factors=gen_capacity_factor,
    wind_pmax_mw=wind_pmax,
    battery_pmax_mw=battery_pmax,
    battery_energy_capacity_mwh=battery_emax,
)

tracker_object = Tracker(
    tracking_model_object=tracker_mp_wind_battery,
    tracking_horizon=tracking_horizon,
    n_tracking_hour=n_tracking_hour,
    solver=solver,
)

# Projection Tracker
projection_mp_wind_battery = MultiPeriodWindBattery(
    model_data=model_data,
    wind_capacity_factors=gen_capacity_factor,
    wind_pmax_mw=wind_pmax,
    battery_pmax_mw=battery_pmax,
    battery_energy_capacity_mwh=battery_emax,
)

projection_tracker_object = Tracker(
    tracking_model_object=projection_mp_wind_battery,
    tracking_horizon=tracking_horizon,
    n_tracking_hour=n_tracking_hour,
    solver=solver,
)
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.10] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:50 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:50 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[+   0.00] Beginning the formulation of the multiperiod optimization problem.
[+   0.09] Completed the formulation of the multiperiod optimization problem.
2022-11-11 10:24:50 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: Initialization function is not provided. Returning the multiperiod model without initialization.
2022-11-11 10:24:50 [WARNING] idaes.apps.grid_integration.multiperiod.multiperiod: unfix_dof function is not provided. Returning the model without unfixing degrees of freedom
[9]:
# Compose into Coordinator
# help(DoubleLoopCoordinator)
coordinator = DoubleLoopCoordinator(
    bidder=bidder_object,
    tracker=tracker_object,
    projection_tracker=projection_tracker_object,
)

Running the Double-Loop Plugin

The prescient_options are updated with the DoubleLoopCoordinator. The simulation results will be written to the output_dir folder.

[10]:
import shutil

prescient_options['plugin']['doubleloop']['module'] = coordinator.prescient_plugin_module

if output_dir.exists():
    shutil.rmtree(output_dir)

Prescient().simulate(**prescient_options)
Initializing simulation...
Did not find reserves.csv; assuming no reserves
/Users/dguittet/miniconda3/envs/dispatches/lib/python3.8/site-packages/pandas/io/parsers/base_parser.py:1055: FutureWarning:
        Use pd.to_datetime instead.

  return generic_parser(date_parser, *date_cols)
Setting default t0 state in RTS-GMLC parser
Dates to simulate: 2020-01-02 to 2020-01-02
RUC activation hours: 0
Final RUC date: 2020-01-02
Using current day's forecasts for RUC solves
Using persistent forecast error model when projecting demand and renewables in SCED


Extracting scenario to simulate
FICO Xpress v8.12.4, Hyper, solve started 10:24:55, Nov 11, 2022
Heap usage: 953KB (peak 1073KB, 1176KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
      1506 rows         1260 cols         2583 elements
Presolved problem has:
       249 rows          336 cols          831 elements
Presolve finished in 0 seconds
Heap usage: 1050KB (peak 1969KB, 1178KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 1.56e-02,  1.60e+01]
  RHS and bounds [min,max] : [ 7.71e+02,  1.00e+08] / [ 7.71e+02,  8.00e+08]
  Objective      [min,max] : [ 1.50e-02,  1.89e+01] / [ 7.50e-03,  1.20e-01]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 21 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       16961.67995      D      1     3        .720000     0
   182      -19382.55330      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  182 simplex iterations in 0.00 seconds at time 0

Final objective                       : -1.938255330232465e+04
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0
Calculating PTDF Matrix Factorization

Pyomo model construction time:         4.03


User solution (_) stored.

User solution (_) stored.

User solution (_) stored.

User solution (_) stored.

User solution (_) stored.

Pyomo model solve time: 46.95074200630188


Deterministic RUC Cost: 1005560.56

Fixed costs:       768089.61
Variable costs:    237470.95


Renewables curtailment summary (time-period, aggregate_quantity):
2020-01-02 07:00       134.47
2020-01-02 08:00       664.90
2020-01-02 09:00       960.49
2020-01-02 10:00      1106.21
2020-01-02 11:00      1144.95
2020-01-02 12:00      1094.63
2020-01-02 13:00       892.91
2020-01-02 14:00       496.39
2020-01-02 15:00         7.93
Solving day-ahead market
Computing day-ahead prices using method LMP.

Simulating time_step  2020-01-02 00:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:25:55, Nov 11, 2022
Heap usage: 405KB (peak 405KB, 545KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          351 elements
Presolved problem has:
        33 rows           48 cols          111 elements
Presolve finished in 0 seconds
Heap usage: 405KB (peak 537KB, 547KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 1.56e-02,  1.60e+01]
  RHS and bounds [min,max] : [ 8.29e+02,  1.00e+08] / [ 8.29e+02,  8.00e+08]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  1.20e-01]
Autoscaling applied Curtis-Reid scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -3424.293692      D      1     3        .720000     0
    21      -6025.244240      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  21 simplex iterations in 0.00 seconds at time 0

Final objective                       : -6.025244239573585e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0
Solving for LMPs


Fixed costs:        24417.83
Variable costs:     14905.86

Number on/offs:                 61
Sum on/off ramps:             0.00
Sum nominal ramps:          763.36

Simulating time_step  2020-01-02 01:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:25:57, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2802KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        27 rows           42 cols           96 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2804KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 1.56e-02,  1.60e+01]
  RHS and bounds [min,max] : [ 4.15e+02,  1.00e+08] / [ 3.94e+02,  2.00e+08]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 2.30e-02,  1.20e-01]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0        596.583931      D     15     0        .000000     0
    15      -3937.432651      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  15 simplex iterations in 0.00 seconds at time 0

Final objective                       : -3.937432651454484e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

User solution (_) stored.

Solving for LMPs


Fixed costs:        24417.83
Variable costs:     19562.74

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:          204.79

Simulating time_step  2020-01-02 02:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:25:59, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2813KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        27 rows           42 cols           96 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2816KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 1.56e-02,  1.60e+01]
  RHS and bounds [min,max] : [ 4.15e+02,  1.00e+08] / [ 3.95e+02,  2.00e+08]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 2.46e-02,  1.20e-01]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       3615.479939      D     15     0        .000000     0
    12      -2406.098006      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -2.406098006199257e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:     20247.18

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:           64.76

Simulating time_step  2020-01-02 03:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:01, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2823KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        27 rows           42 cols           96 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2825KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 1.56e-02,  1.60e+01]
  RHS and bounds [min,max] : [ 7.98e+03,  1.00e+08] / [ 4.40e+03,  2.00e+08]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 2.25e-02,  1.20e-01]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       3714.152553      D     15     0        .000000     0
    15      -2128.943284      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  15 simplex iterations in 0.00 seconds at time 0

Final objective                       : -2.128943283819684e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:     21571.18

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:           56.29

Simulating time_step  2020-01-02 04:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:03, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2832KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        24 rows           39 cols           90 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2835KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 4.45e+03,  1.00e+08] / [ 4.45e+03,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.50e-02,  3.12e-02]
Autoscaling applied standard scaling

Crash basis containing 3 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       2544.561049      D     12     0        .000000     0
    15      -2281.348467      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  15 simplex iterations in 0.00 seconds at time 0

Final objective                       : -2.281348466979623e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:     19652.08

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:           81.68

Simulating time_step  2020-01-02 05:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:05, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2842KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2844KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 3.27e+03,  1.00e+08] / [ 3.27e+03,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.43e-02,  2.93e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0        266.911541      D      9     0        .000000     0
     9      -3429.733707      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : -3.429733706951121e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:     12801.19

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:          307.07

Simulating time_step  2020-01-02 06:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:07, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2851KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        15 rows           30 cols           90 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2853KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 9.95e+02,  1.00e+08] / [ 9.95e+02,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  2.37e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -2470.597218      D      6     0        .000000     0
     6      -4158.097219      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  6 simplex iterations in 0.00 seconds at time 0

Final objective                       : -4.158097218541449e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:     17426.26

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:          210.98

Simulating time_step  2020-01-02 07:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:09, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2860KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2863KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 9.95e+02,  1.00e+08] / [ 9.95e+02,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  2.37e-02]
Autoscaling applied standard scaling

Crash basis containing 3 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -4751.373032      D      9     0        .000000     0
    12      -5876.373033      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -5.876373032592495e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:     19317.67

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:          115.54

Simulating time_step  2020-01-02 08:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:10, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2870KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2872KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 9.21e+02,  1.00e+08] / [ 9.21e+02,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  2.18e-02]
Autoscaling applied standard scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -6841.809721      D      9     0        .000000     0
    12      -7404.309721      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -7.404309721063572e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:      1679.78

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:          856.43

Simulating time_step  2020-01-02 09:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:12, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2879KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           27 cols           72 elements
Presolve finished in 0 seconds
Heap usage: 403KB (peak 514KB, 2881KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 8.87e+02,  1.00e+08] / [ 8.87e+02,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  1.50e-02]
Autoscaling applied standard scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -8694.246575      D      9     0        .000000     0
    12      -8694.246575      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -8.694246575342466e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:      1518.31

Renewables curtailment reported at t=1 - total=      492.71

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:           21.86

Simulating time_step  2020-01-02 10:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:14, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2888KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           27 cols           72 elements
Presolve finished in 0 seconds
Heap usage: 403KB (peak 514KB, 2891KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 7.71e+02,  1.00e+08] / [ 7.71e+02,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  1.50e-02]
Autoscaling applied standard scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -8694.246575      D      9     0        .000000     0
    12      -8694.246575      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -8.694246575342464e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:      1252.34

Renewables curtailment reported at t=1 - total=      870.73

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:           14.00

Simulating time_step  2020-01-02 11:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:16, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2898KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           27 cols           72 elements
Presolve finished in 0 seconds
Heap usage: 403KB (peak 514KB, 2900KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 7.71e+02,  1.00e+08] / [ 7.71e+02,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  1.50e-02]
Autoscaling applied standard scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -8694.246575      D      9     0        .000000     0
    12      -8694.246575      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -8.694246575342462e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:      1271.20

Renewables curtailment reported at t=1 - total=      979.52

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:            1.00

Simulating time_step  2020-01-02 12:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:18, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2907KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           27 cols           72 elements
Presolve finished in 0 seconds
Heap usage: 403KB (peak 514KB, 2910KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 7.71e+02,  1.00e+08] / [ 9.04e+02,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 7.50e-03,  1.50e-02]
Autoscaling applied standard scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -8694.246575      D      9     0        .000000     0
    12      -8694.246575      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -8.694246575342466e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:      1290.06

Renewables curtailment reported at t=1 - total=      958.52

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:            1.00

Simulating time_step  2020-01-02 13:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:20, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2917KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        21 rows           30 cols           81 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2919KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 1.56e-02,  3.20e+01]
  RHS and bounds [min,max] : [ 1.80e+00,  1.00e+08] / [ 2.59e-02,  5.12e+07]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 3.00e-02,  3.91e+01]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 3 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -8580.217940      D     12     0        .000000     0
    18      -8580.222506      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  18 simplex iterations in 0.00 seconds at time 0

Final objective                       : -8.580222506327093e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:      1308.93

Renewables curtailment reported at t=1 - total=      745.92

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:            1.00

Simulating time_step  2020-01-02 14:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:22, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2926KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        21 rows           30 cols           81 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2928KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 1.28e-02,  1.60e+01]
  RHS and bounds [min,max] : [ 1.80e+00,  1.00e+08] / [ 1.04e-01,  5.12e+07]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 5.14e-02,  9.77e+00]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 6 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -6514.279207      D     12     0        .000000     0
    15      -6514.283773      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  15 simplex iterations in 0.00 seconds at time 0

Final objective                       : -6.514283773392906e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        24417.83
Variable costs:      1308.93

Renewables curtailment reported at t=1 - total=      656.49

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:            2.00

Simulating time_step  2020-01-02 15:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:24, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2935KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        21 rows           36 cols           93 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2938KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 2.56e-02,  3.20e+01]
  RHS and bounds [min,max] : [ 1.80e+00,  1.00e+08] / [ 5.18e-02,  5.12e+07]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.66e-02,  1.95e+01]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 3 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0      -3668.230070      D     12     0        .000000     0
    12      -4230.734636      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -4.230734636143005e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


User solution (_) stored.

User solution (_) stored.

Fixed costs:        24417.83
Variable costs:      1271.20

Renewables curtailment reported at t=1 - total=      570.48

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:            2.00

Simulating time_step  2020-01-02 16:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:29, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 3237KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        21 rows           36 cols           93 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 3240KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 2.56e-02,  3.20e+01]
  RHS and bounds [min,max] : [ 1.80e+00,  1.00e+08] / [ 5.18e-02,  5.12e+07]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.82e-02,  1.95e+01]
Autoscaling applied Curtis-Reid scaling

Crash basis containing 3 structural columns created

   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       -633.714838      D     12     0        .000000     0
    12      -2640.477970      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  12 simplex iterations in 0.00 seconds at time 0

Final objective                       : -2.640477969993869e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

User solution (_) stored.

Solving for LMPs


Fixed costs:        89939.88
Variable costs:      1195.76

Renewables curtailment reported at t=1 - total=      337.32

Number on/offs:                  3
Sum on/off ramps:           340.00
Sum nominal ramps:            6.00

Simulating time_step  2020-01-02 17:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:33, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2961KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2963KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 1.01e+03,  1.00e+08] / [ 1.01e+03,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.50e-02,  4.19e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       3391.697158      D      9     0        .000000     0
     9      -1013.689458      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : -1.013689457540215e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

User solution (_) stored.

Solving for LMPs


Fixed costs:        36121.53
Variable costs:     14013.14

Renewables curtailment reported at t=1 - total=      342.13

Number on/offs:                  2
Sum on/off ramps:            16.00
Sum nominal ramps:          646.70

Simulating time_step  2020-01-02 18:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:36, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2973KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2975KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 1.01e+03,  1.00e+08] / [ 1.01e+03,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.50e-02,  4.07e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       7808.182553      D      9     0        .000000     0
     9       3403.042401      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : 3.403042401035108e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

User solution (_) stored.

Solving for LMPs


User solution (_) stored.

Fixed costs:        36018.03
Variable costs:     16763.79

Renewables curtailment reported at t=1 - total=      400.14

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:          127.89

Simulating time_step  2020-01-02 19:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:39, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 3275KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 3277KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 3.53e+03,  1.00e+08] / [ 3.53e+03,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.50e-02,  3.82e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       14042.17710      D      9     0        .000000     0
     9       9931.574706      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : 9.931574705736268e+03
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

User solution (_) stored.

Solving for LMPs


Fixed costs:        33846.52
Variable costs:     13323.78

Renewables curtailment reported at t=1 - total=      306.57

Number on/offs:                  2
Sum on/off ramps:             0.00
Sum nominal ramps:          157.51

Simulating time_step  2020-01-02 20:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:42, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2999KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 3001KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 1.52e+04,  1.00e+08] / [ 1.52e+04,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.14e-02,  3.44e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       16369.04420      D      9     0        .000000     0
     9       13432.76460      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : 1.343276459623203e+04
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        33846.52
Variable costs:     10781.31

Renewables curtailment reported at t=1 - total=      169.59

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:          118.76

Simulating time_step  2020-01-02 21:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:45, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2779KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2781KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 2.50e+04,  1.00e+08] / [ 2.50e+04,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.50e-02,  3.32e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       16209.46791      D      9     0        .000000     0
     9       13549.84798      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : 1.354984797926082e+04
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        33846.52
Variable costs:      5931.41

Renewables curtailment reported at t=1 - total=      209.79

Number on/offs:                  0
Sum on/off ramps:             0.00
Sum nominal ramps:          240.42

Simulating time_step  2020-01-02 22:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:47, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2788KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2791KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 2.50e+04,  1.00e+08] / [ 2.50e+04,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.50e-02,  3.07e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       17159.37776      D      9     0        .000000     0
     9       14500.54127      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : 1.450054126796456e+04
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        27260.91
Variable costs:      5757.22

Renewables curtailment reported at t=1 - total=       95.62

Number on/offs:                  4
Sum on/off ramps:             0.00
Sum nominal ramps:          213.67

Simulating time_step  2020-01-02 23:00

Solving SCED instance

FICO Xpress v8.12.4, Hyper, solve started 10:26:49, Nov 11, 2022
Heap usage: 406KB (peak 406KB, 2798KB system)
Maximizing LP unknown with these control settings:
OUTPUTLOG = 1
Original problem has:
       210 rows          180 cols          348 elements
Presolved problem has:
        18 rows           33 cols           84 elements
Presolve finished in 0 seconds
Heap usage: 404KB (peak 514KB, 2800KB system)

Coefficient range                    original                 solved
  Coefficients   [min,max] : [ 1.00e-04,  1.05e+00] / [ 5.00e-05,  1.05e+00]
  RHS and bounds [min,max] : [ 2.50e+04,  1.00e+08] / [ 2.50e+04,  1.00e+05]
  Objective      [min,max] : [ 1.50e-02,  1.00e+04] / [ 1.50e-02,  3.21e-02]
Autoscaling applied standard scaling


   Its         Obj Value      S   Ninf  Nneg   Sum Dual Inf  Time
     0       13323.96196      D      9     0        .000000     0
     9       10295.49515      D      0     0        .000000     0
Uncrunching matrix
Optimal solution found
Dual solved problem
  9 simplex iterations in 0.00 seconds at time 0

Final objective                       : 1.029549515441892e+04
  Max primal violation      (abs/rel) :       0.0 /       0.0
  Max dual violation        (abs/rel) :       0.0 /       0.0
  Max complementarity viol. (abs/rel) :       0.0 /       0.0

Solving for LMPs


Fixed costs:        23937.59
Variable costs:      3748.24

Renewables curtailment reported at t=1 - total=       48.08

Number on/offs:                  1
Sum on/off ramps:             0.00
Sum nominal ramps:          112.93


Saving bidding results to disk...

Saving tracking results to disk...
Simulation Complete
Total simulation time: 121.52 seconds

[11]:
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
plt.style.use('seaborn')

df = double_loop_outputs_for_gen(output_dir, rts_gmlc.source_data_path)
prescient_df = df[df['Model'] == "Prescient"].copy()
da_bidder_df = df[df['Model'] == "DA Bidder"].copy()
rt_bidder_df = df[df['Model'] == "RT Bidder"].copy()
tracker_df = df[df['Model'] == "Tracker"].copy()
tracker_df.loc[:, 'Wind Curtailment [MW]'] = tracker_df['Wind Curtailment [MW]'] * -1
time_index = prescient_df.index
time_slice = slice(0, len(time_index))

da_bid_powers = [i for i in da_bidder_df.columns if 'DA Power' in i]
rt_bid_powers = [i for i in da_bidder_df.columns if 'RT Power' in i]

Analyzing the Wind + Battery IES Performance: Bidder

In contrast to the wind plant above which bids its DA resource forecast and its RT resource forecast at $0/MWh marginal cost, the Wind + Battery IES is shifting the times and prices to sell energy. The bidding process for both the DA and RT market take place across multiple horizons within the staggered, forward-rolling UC and ED problems. As the Bidder receives more information about its state within each time horizon, it updates its bids. This is shown in the first plot in the top row, where the final DA and RT Bid are 24-Hr Ahead DA Bid and 0-Hr Ahead RT Bid. The second row shows the DA Dispatch and RT Dispatch from Prescient, and the delivered RT Output.

[12]:
fig, ax = plt.subplots(2, 1, figsize=(24, 10), sharex=True)
ax[0].plot(time_index, np.append([0] * 24, da_bidder_df[da_bidder_df['Horizon [hr]'] >= 24][da_bid_powers].sum(axis=1))[time_slice], color='b', alpha=0.4, label="48-Hr Ahead DA Bid")
ax[0].plot(time_index, da_bidder_df[da_bidder_df['Horizon [hr]'] < 24][da_bid_powers].sum(axis=1)[time_slice], color='b', alpha=1, label="24-Hr Ahead DA Bid")
ax[0].plot(time_index, np.append([0] * 3, rt_bidder_df[rt_bidder_df['Horizon [hr]'] == 3][rt_bid_powers].sum(axis=1))[time_slice], color='g', alpha=0.2, label="3-Hr Ahead RT Bid")
ax[0].plot(time_index, np.append([0] * 2, rt_bidder_df[rt_bidder_df['Horizon [hr]'] == 2][rt_bid_powers].sum(axis=1))[time_slice], color='g', alpha=0.3, label="2-Hr Ahead RT Bid")
ax[0].plot(time_index, np.append([0] * 1, rt_bidder_df[rt_bidder_df['Horizon [hr]'] == 1][rt_bid_powers].sum(axis=1))[time_slice], color='g', alpha=0.4, label="1-Hr Ahead RT Bid")
ax[0].plot(time_index, rt_bidder_df[rt_bidder_df['Horizon [hr]'] == 0]['RT Power 0 [MW]'].values[time_slice], color='g', alpha=1, label="0-Hr Ahead RT Bid")

ax[1].plot(time_index, prescient_df['Dispatch DA'].values[time_slice], color='b', label='DA Dispatch')
ax[1].plot(time_index, prescient_df['Dispatch'].values[time_slice], color='g', label='RT Dispatch')
ax[1].plot(time_index, tracker_df[tracker_df['Horizon [hr]'] == 0][['Power Output [MW]']], color='r', label='RT Output')
ax[1].set_ylim(ax[0].get_ylim())
format_plt(fig, ax, mod_ticks=False, titles=["DA and RT Bids at Each Horizon", "Final Dispatch and Output"], suptitle="Double-loop RTS-GMLC Simulation")
../_images/examples_DoubleLoopOptimization_18_0.png

Analyzing the Wind + Battery IES Performance: Tracker and Settlement

The first plot shows the double-loop simulation results. Max power has increased due to battery capacity. In comparison to the original result plotted above, there’s different DA Dispatch due to using RT forecast instead of DA forecast. Also, where there were a few times where the wind plant had negative revenue due to Penalized DA Underdelivered when the RT price was higher than the DA price, here, there is only one instance of being penalized for missing a DA promise. However, there appears to be more curtailed energy, and the battery is full at least once a day, often more.

The second plot shows the impact on the Generator’s Unit Market Revenue.

[13]:
tracker_df.loc[:, 'Penalized DA Underdelivered'] = 0
prescient_df["Penalized DA Underdelivered"] = ((prescient_df['Dispatch DA'] - prescient_df['Dispatch']) * (prescient_df['LMP'] > prescient_df['LMP DA'])).clip(lower=0).values
tracker_df.loc[tracker_df['Horizon [hr]'] == 0, 'Penalized DA Underdelivered [MW]'] = prescient_df["Penalized DA Underdelivered"].values

fig, ax = plt.subplots(2, 1, figsize=(24, 10), sharex=True)
cols = ["Wind Power Output [MW]", "Battery Power Output [MW]", 'Penalized DA Underdelivered [MW]', "Wind Power to Battery [MW]"]
ax[0].plot(prescient_df['Dispatch DA'].values, drawstyle="steps-mid", label='DA Dispatch [MW]', color='grey')
ax[0].plot(tracker_df.loc[tracker_df['Horizon [hr]'] == 0]['Total Power Output [MW]'].values, drawstyle="steps-mid", label='RT Dispatch [MW]', color='k')
tracker_df.loc[tracker_df['Horizon [hr]'] == 0][cols].plot(kind='bar', width=1, stacked=True, ax=ax[0], color=['b', 'g', 'r', 'c'])

tracker_df.loc[tracker_df['Horizon [hr]'] == 0]['Wind Curtailment [MW]'].plot(kind='bar', width=1, stacked=True, ax=ax[1])
tracker_df.loc[tracker_df['Horizon [hr]'] == 0]["Wind Power to Battery [MW]"].plot(kind='bar', width=1, stacked=True, ax=ax[1], color='c')
ax[1].plot([battery_pmax] * len(time_index), linestyle="dashed", label='Max Stored Power [MWh]', alpha=0.8, color='orange')
ax[1].plot(tracker_df.loc[tracker_df['Horizon [hr]'] == 0]['State of Charge [MWh]'].values / 4, drawstyle="steps-mid", label='Stored Power [MW]', color='y')
format_plt(fig, ax, titles=["Wind + Battery Dispatch and Output", "Wind Curtailment and Battery State-of-Charge"], suptitle="Double-loop RTS-GMLC Simulation")
../_images/examples_DoubleLoopOptimization_20_0.png
[14]:
fig, ax = plt.subplots(2, 1, figsize=(24, 10), sharex=True)
prescient_df["Penalized DA Underdelivered"].plot(ax=ax[0], color='r', kind='bar', width=1)
ax0 = ax[0].twinx()
ax0.set_yscale('symlog')
ax0.plot(prescient_df['LMP DA'].values, label="LMP DA [$/MWh]")
ax0.plot(prescient_df['LMP'].values, label='LMP RT [$/MWh]')
ax0.legend(loc='upper right')
ax0.set_ylabel("LMP [$/MWh]")
ax0.grid(None)
ax[1].set_yscale('symlog')
ax[1].plot(prescient_df['Unit Market Revenue'].values, color='k', linestyle=':', label="Market Revenue [$]")
ax[1].plot(prescient_df['Unit Market Revenue'].cumsum().values, color='k', label="Cumulative Market Revenue [$]")
format_plt(fig, ax, y_labels=['Power [MW]', 'Revenue [$]'], titles=["LMPs at Missed DA Promises", "Market Revenue"], suptitle="Double-loop RTS-GMLC Simulation")
ax[0].legend(loc='upper left')
[14]:
<matplotlib.legend.Legend at 0x7f9602347fa0>
../_images/examples_DoubleLoopOptimization_21_1.png

Analyzing the Wind + Battery IES Performance: Comparison to Original RTS-GMLC Simulation

The plots below show the changes in the electricity market which impact the plant’s economic performance and the grid’s production and reliability.

[15]:
fig, ax = plt.subplots(3, 1, figsize=(24, 10), sharex=True)
ax[0].set_yscale('symlog')
ax[0].plot(orig_outputs_df['Unit Market Revenue'].values, color='grey', linestyle=':', label="Orig Market Revenue [$]")
ax[0].plot(orig_outputs_df['Unit Market Revenue'].cumsum().values, color='grey', label="Orig Cumulative Market Revenue [$]")
ax[0].plot(prescient_df['Unit Market Revenue'].values, color='b', linestyle=':', label="Double-loop Market Revenue [$]")
ax[0].plot(prescient_df['Unit Market Revenue'].cumsum().values, color='b', label="Double-loop Cumulative Market Revenue [$]")

ax[1].set_yscale('symlog')
da_rev = orig_outputs_df['Output DA'] * orig_outputs_df['LMP DA']
ax[1].plot(da_rev.values, color='grey', linestyle=':', label="Orig DA Revenue [$]")
ax[1].plot(da_rev.cumsum().values, color='grey', label="Orig Cumulative DA Revenue [$]")
da_rev = prescient_df['Dispatch DA'] * prescient_df['LMP DA']
ax[1].plot(da_rev.values, color='b', linestyle=':', label="Double-loop DA Revenue [$]")
ax[1].plot(da_rev.cumsum().values, color='b', label="Double-loop Cumulative DA Revenue [$]")

ax[2].set_yscale('symlog')
rt_rev = (orig_outputs_df['Output'] - orig_outputs_df['Output DA']) * orig_outputs_df['LMP']
ax[2].plot(rt_rev.values, color='grey', linestyle=':', label="Orig RT Revenue [$]")
ax[2].plot(rt_rev.cumsum().values, color='grey', label="Orig Cumulative RT Revenue [$]")
rt_rev = (tracker_df[tracker_df['Horizon [hr]'] == 0]['Power Output [MW]'] - prescient_df['Dispatch DA']) * prescient_df['LMP']
ax[2].plot(rt_rev.values, color='b', linestyle=':', label="Double-loop RT Revenue [$]")
ax[2].plot(rt_rev.cumsum().values, color='b', label="Double-loop Cumulative RT Revenue [$]")

format_plt(fig, ax, y_labels=['Revenue [$]', "LMP [$/MWh]", "LMP [$/MWh]"], titles=["Total Revenue", 'DA Revenue', 'RT Revenue'], suptitle="Double-Loop vs Original RTS-GMLC Revenue Comparison")

../_images/examples_DoubleLoopOptimization_23_0.png
[16]:
fig, ax = plt.subplots(5, 1, figsize=(24, 15), sharex=True)
ax[0].set_yscale('symlog')
ax[0].plot(orig_outputs_df['TotalCosts'].values, color='grey', linestyle=':', label="Orig Production Cost [$]")
ax[0].plot(orig_outputs_df['TotalCosts'].cumsum().values, color='grey', label="Orig Cumulative Production Cost [$]")
ax[0].plot(prescient_df['TotalCosts'].values, color='b', linestyle=':', label="Double-loop Production Cost [$]")
ax[0].plot(prescient_df['TotalCosts'].cumsum().values, color='b', label="Double-loop Cumulative Production Cost [$]")

ax[1].set_yscale('symlog')
ax[1].plot(orig_outputs_df['LoadShedding'].values * -1, color='grey', linestyle=':', label="Orig LoadShedding [MW]")
ax[1].plot(orig_outputs_df['LoadShedding'].cumsum().values * -1, color='grey', label="Orig Cumulative LoadShedding [MW]")
ax[1].plot(prescient_df['LoadShedding'].values * -1, color='b', linestyle=':', label="Double-loop LoadShedding [MW]")
ax[1].plot(prescient_df['LoadShedding'].cumsum().values * -1, color='b', label="Double-loop Cumulative LoadShedding [MW]")

ax[2].set_yscale('symlog')
ax[2].plot(orig_outputs_df['Curtailment'].values, color='grey', linestyle=':', label="Orig Curtailment [MW]")
ax[2].plot(orig_outputs_df['Curtailment'].cumsum().values, color='grey', label="Cumulative Orig Curtailment [MW]")
ax[2].plot(tracker_df[tracker_df['Horizon [hr]'] == 0]['Wind Curtailment [MW]'].values, color='b', linestyle=':', label="Double-loop Curtailment [MW]")
ax[2].plot(tracker_df[tracker_df['Horizon [hr]'] == 0]['Wind Curtailment [MW]'].cumsum().values, color='b', label="Double-loop Cumulative Curtailment [MW]")

ax[3].set_yscale('symlog')
ax[3].plot(orig_outputs_df['LMP DA'].values, color='grey', label="Orig DA LMPs [$]")
ax[3].plot(prescient_df['LMP DA'].values, color='b', label="Double-loop DA LMPs [$]")

ax[4].set_yscale('symlog')
ax[4].plot(orig_outputs_df['LMP'].values, color='grey', label="Orig RT LMPs [$]")
ax[4].plot(prescient_df['LMP'].values, color='b', label="Double-loop RT LMPs [$]")

format_plt(fig, ax, y_labels=['Cost [$]', "Power [MW]", "Power [MW]", "LMP [$/MWh]", "LMP [$/MWh]"], titles=["Total Production Cost", 'Load Shed', 'Curtailment', 'DA LMPs', 'RT LMPs'], suptitle="Double-Loop vs Original RTS-GMLC Grid Comparison")

../_images/examples_DoubleLoopOptimization_24_0.png