Skip to content

Commit

Permalink
Scripts needed to reproduce results in the NE/RE report (#210)
Browse files Browse the repository at this point in the history
* Added all scripts used for the report

* Updated readme file

* Updated the market surrogates code

---------

Co-authored-by: Ludovico Bianchi <[email protected]>
Co-authored-by: Keith Beattie <[email protected]>
  • Loading branch information
3 people authored Jul 24, 2023
1 parent 654d287 commit e0b8192
Show file tree
Hide file tree
Showing 18 changed files with 9,782 additions and 0 deletions.
21 changes: 21 additions & 0 deletions dispatches/case_studies/nuclear_case/report/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Source Code for Generating Nuclear Case Study Results in Report

This folder contains the source code used to generate the results shown in the combined report for nuclear and renewable case studies.

### `base_case_pcm_simulation.py`
This script performs a Prescient simulation of the base case i.e., nuclear generator without an electrolyzer. The script creates a new folder called `ne_without_pem_results` and saves the simulation results in that folder. Then, the LMP data at the bus `Attlee` is extracted from the file `bus_detail.csv`. For convenience, the extracted LMP data is included in the file `rts_gmlc_15_500.csv` file. This LMP data is used for the price-taker analysis.

### `traditional_tea.py`

This script performs the traditional techno-economic analysis. The function `run_exhaustive_enumeration` fixes the capacity of the electrolyzer and the selling price of hydrogen and computes the revenue from both electricity, and hydrogen markets and the annualized net present value. The script saves the results in a `json` file.

### `price_taker.py`

This script performs price-taker analysis. The function `run_exhaustive_enumeration` fixes the capacity of the electrolyzer and the selling price of hydrogen and computes the revenue from both electricity and hydrogen markets, and the annualized net present value. `market` argument to the function indicates which of the four price-taker variants to use for the analysis. To use the first variant (refer to the report for more details), specify `market="DA"`. For second, third, and fourth variants, specify `market="RT"`, `market="Max-DA-RT"`, and `market="DA-RT"`, respectively. The script saves the results in a `json` file.

### `market_surrogates.py`

Solves the conceptual design problem by embedding the surrogate models for market interactions. To run this script, `tensorflow` must be installed in the current environment. If it is not installed, the user can do so by running `pip install tensorflow` in a command window. The trained neural network surrogate models are included in the folder `nn_steady_state`. The function `run_exhaustive_enumeration` fixes the capacity of the electrolyzer and the selling price of hydrogen and computes the revenue from both electricity, and hydrogen markets and the annualized net present value, and saves the results in a `json` file.

### `generate_contour_plots.py`
This script generates the contour plots shown in the report.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#################################################################################
# DISPATCHES was produced under the DOE Design Integration and Synthesis Platform
# to Advance Tightly Coupled Hybrid Energy Systems program (DISPATCHES), and is
# copyright (c) 2020-2023 by the software owners: The Regents of the University
# of California, through Lawrence Berkeley National Laboratory, National
# Technology & Engineering Solutions of Sandia, LLC, Alliance for Sustainable
# Energy, LLC, Battelle Energy Alliance, LLC, University of Notre Dame du Lac, et
# al. All rights reserved.
#
# Please see the files COPYRIGHT.md and LICENSE.md for full copyright and license
# information, respectively. Both files are also available online at the URL:
# "https://github.com/gmlc-dispatches/dispatches".
#################################################################################

import os
from prescient.simulator import Prescient


def download_rts_gmlc(dir_name="DISPATCHES_RTS-GMLC"):
cur_path = os.getcwd()
this_file_path = os.path.dirname(os.path.realpath(__file__))

if os.path.isdir(os.path.join(this_file_path, dir_name)):
return

os.chdir(this_file_path)
os.system(f"git clone --depth=1 https://github.com/bknueven/RTS-GMLC -b no_reserves {dir_name}")

os.chdir(cur_path)


download_rts_gmlc()
this_file_path = os.path.dirname(os.path.realpath(__file__))

start_date = "01-01-2020"
n_days = 366
shortfall = 500 # 500 $/MWh
reserve_factor = 0.15 # 15% reserves
day_ahead_horizon = 36
real_time_horizon = 1
tracking_horizon = 4
n_tracking_hour = 1
output_dir = "ne_without_pem_results"

# default some options
prescient_options = {
"data_path": os.path.join(this_file_path, "DISPATCHES_RTS-GMLC/RTS_Data/SourceData"),
"reserve_factor": reserve_factor,
"simulate_out_of_sample": True,
"output_directory": output_dir,
"monitor_all_contingencies": False,
"input_format": "rts-gmlc",
"start_date": start_date,
"num_days": n_days,
"sced_horizon": real_time_horizon,
"ruc_mipgap": 0.01,
"deterministic_ruc_solver": "gurobi_persistent",
"deterministic_ruc_solver_options" : {
"threads": 4,
"heurstrategy": 2,
"cutstrategy": 3,
"symmetry": 2,
"maxnode": 1000,
},
"sced_solver": "gurobi_persistent",
"sced_frequency_minutes": 60,
"sced_solver_options" : {"threads": 1},
"ruc_horizon": day_ahead_horizon,
"compute_market_settlements": True,
"output_solver_logs": False,
"price_threshold": shortfall,
"transmission_price_threshold": shortfall / 2,
"contingency_price_threshold": None,
"reserve_price_threshold": shortfall / 10,
"day_ahead_pricing": "aCHP",
"enforce_sced_shutdown_ramprate": False,
"ruc_slack_type": "ref-bus-and-branches",
"sced_slack_type": "ref-bus-and-branches",
"disable_stackgraphs": True,
}


Prescient().simulate(**prescient_options)
Loading

0 comments on commit e0b8192

Please sign in to comment.