Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c13d1e4
allow utc extrapolation (#163)
paulf81 Oct 16, 2025
c8023ca
Allow wind input to specify mean wind speed (#166)
misi9170 Oct 30, 2025
04e859e
Wind and solar resource downloading and upsampling (#164)
ejsimley Oct 31, 2025
8fc55f0
Reorganize logging in Hercules (#167)
paulf81 Oct 31, 2025
3c83c28
Refactor to use UTC based inputs (#168)
paulf81 Oct 31, 2025
76fa86c
Refactor code to use HerculesModel (#169)
paulf81 Nov 5, 2025
fdc35d0
Doc/docstring (#171)
paulf81 Nov 5, 2025
87d2e8d
[BUGFIX] Hercules input yaml loader (#174)
misi9170 Nov 5, 2025
c53dab0
Add grid status tool (#165)
paulf81 Nov 6, 2025
e0f26d4
update deploy pages to debug docs
paulf81 Nov 6, 2025
fd7d142
Fix build command for Jupyter Book
paulf81 Nov 6, 2025
7913aef
Pin jupyter-book version to 1.0.4 in dependencies
paulf81 Nov 6, 2025
d0426a2
fix doc warnings (#175)
paulf81 Nov 6, 2025
a2a1cfa
Merge branch 'main' into develop
misi9170 Nov 7, 2025
3974c6f
Add external data logging selection (#176)
paulf81 Nov 14, 2025
4af35c2
fix warnings (#178)
paulf81 Nov 14, 2025
7790243
Updating the electrolyzer plant model for v2 and new electrolyzer cod…
genevievestarke Nov 14, 2025
a9e9fef
external data to signals name (#179)
paulf81 Nov 14, 2025
21cbc4d
Feature/clean up logging (#177)
paulf81 Nov 14, 2025
28490db
Clean up (#181)
paulf81 Nov 19, 2025
80d44bc
Fix print bug and update interface name (#182)
misi9170 Nov 19, 2025
c2b69d0
Update names (#186)
misi9170 Dec 13, 2025
37ec66a
set update to 100 (#187)
paulf81 Dec 19, 2025
61cfe5b
apply dtype to missed locations (#188)
paulf81 Dec 19, 2025
506b3b7
Dtypes and linting (#191)
paulf81 Dec 19, 2025
3d8de88
Reconfigure wind models (#173)
paulf81 Dec 31, 2025
56064d1
Improve controller for 1dof wind model (#158)
abhineet-gupta Dec 31, 2025
ea7cb0e
Update lisence and v2 docs
genevievestarke Dec 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/continuous-integration-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -e ".[develop]"
pip install git+https://github.com/NREL/electrolyzer.git@638d890
pip install git+https://github.com/NREL/electrolyzer.git
pip install https://github.com/NREL/SEAS/blob/v1/SEAS.tar.gz?raw=true
# - uses: pre-commit/action@v3.0.0
- name: Run ruff
run: |
ruff check .
# ruff format
ruff format --check
- name: Run tests and collect coverage
run: |
# -rA displays the captured output for all tests after they're run
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ data.db
*.python-version
*.DS_Store
*.conda
*.sqlite
slices

# macOS files
Expand Down
6 changes: 3 additions & 3 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
cff-version: 1.3.0
message: "If you use this software, please cite it as below."
authors:
- family-names: NREL
given-names:
- family-names: NLR
given-names:
title: "HERCULES"
version: 2
url: https://github.com/NREL/hercules

date-released: 2025-09-30
date-released: 2025-12-31
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2025, Alliance for Sustainable Energy LLC, All rights reserved.
Copyright (c) 2025, Alliance for Energy Innovation LLC, All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# README

# hercules
Hercules is an open-source tool for wind-based hybrid plant simulation in real time. Hercules is emulated a wind farm co-simulated other generation to form a hybrid plant that can include solar, storage and electrolyzers. The entire hybrid plant can be controlled using the [Wind Hybrid Open Controller (WHOC)](https://github.com/nrel/wind-hybrid-open-controller).
Hercules is an open-source tool for hybrid plant simulation in real time. Hercules co-simulates multiple technologies to form a hybrid plant that can include wind, solar, storage and electrolyzers. The entire hybrid plant can be controlled using [Hycon](https://github.com/nrel/hycon).

## Part of the WETO Stack

Expand Down
7 changes: 5 additions & 2 deletions docs/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
# Learn more at https://jupyterbook.org/customize/config.html

title: HERCULES
author: National Renewable Energy Laboratory
author: National Laboratory of the Rockies
logo: herc.png
copyright: '2025'
only_build_toc_files: false
exclude_patterns:
- not_used/**

# Force re-execution of notebooks on each build.
# See https://jupyterbook.org/content/execute.html
Expand Down Expand Up @@ -33,7 +35,8 @@ html:
use_issues_button: true
use_repository_button: true
use_edit_page_button: true
google_analytics_id: G-3V1BDK8KEJ
analytics:
google_analytics_id: G-3V1BDK8KEJ



35 changes: 18 additions & 17 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,35 @@ parts:
- caption: Running Hercules
chapters:
- file: running_hercules
- file: order_of_op
- caption: Key Concepts
chapters:
- file: key_concepts
- file: units
- file: timing
- file: h_dict
- file: hybrid_plant
- file: emulator
- file: hercules_model
- file: output_files
- caption: Plant Components
chapters:
- file: wind
- file: solar_pv
- file: battery
- file: electrolyzer
- caption: Inputs
chapters:
- file: hercules_input
- file: gridstatus_download
- file: resource_downloading
- caption: Examples
chapters:
- file: examples_overview
- caption: HybridPlant
chapters:
- file: wind
- file: battery
- file: solar_pv
- caption: Usage
chapters:
- file: order_of_op








- file: examples/00_wind_farm_only
- file: examples/01_wind_farm_dof1_model
- file: examples/02_wind_farm_realistic_inflow
- file: examples/02b_wind_farm_realistic_inflow_precom_floris
- file: examples/03_wind_and_solar
- file: examples/04_wind_and_storage
- file: examples/05_wind_and_storage_with_lmp
- file: examples/06_wind_and_hydrogen
35 changes: 33 additions & 2 deletions docs/battery.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ There are two battery models currently implemented in Hercules: `BatterySimple`
It is important to note that within the battery modules, the convention that positive power is charging the
battery is followed for consistency with battery standards. However, at the level of the `HybridPlant`
this is inverted, such that positive power implies power delivery (and thus the battery is discharging)
for consistency with other components. This inversions applies to power_setpoint and also occurs within
for consistency with other components. This inversion applies to power_setpoint and also occurs within
`HybridPlant`.

### Parameters

Battery parameters are defined in the hercules input yaml file used to initialize `emulator`.
Battery parameters are defined in the hercules input yaml file used to initialize `HerculesModel`.

#### Required Parameters
- `component_type`: `"BatterySimple"` or `"BatteryLithiumIon"`
Expand All @@ -32,6 +32,7 @@ Battery parameters are defined in the hercules input yaml file used to initializ
- `usage_calc_interval`: Interval for usage calculations in seconds (BatterySimple only)
- `usage_lifetime`: Battery lifetime in years for time-based degradation (BatterySimple only)
- `usage_cycles`: Number of cycles until replacement for cycle-based degradation (BatterySimple only)
- `log_channels`: List of output channels to log (see [Logging Configuration](battery-logging-configuration) below)


Once initialized, the battery is only interacted with using the `step` method.
Expand All @@ -55,12 +56,42 @@ Outputs are returned as a dict containing the following values:
- `power`: Actual battery power in kW
- `reject`: Rejected power due to constraints in kW (positive when power cannot be absorbed, negative when required power unavailable)
- `soc`: Battery state of charge (0-1)
- `power_setpoint`: Requested power setpoint in kW

#### Additional Outputs (BatterySimple only when track_usage=True)
- `usage_in_time`: Time-based usage percentage
- `usage_in_cycles`: Cycle-based usage percentage
- `total_cycles`: Total equivalent cycles completed

(battery-logging-configuration)=
### Logging Configuration

The `log_channels` parameter controls which outputs are written to the HDF5 output file. This is a list of channel names. The `power` channel is always logged, even if not explicitly specified.

**Available Channels:**
- `power`: Actual battery power output in kW (always logged)
- `soc`: State of charge (0-1)
- `power_setpoint`: Requested power setpoint in kW

**Example:**
```yaml
battery:
component_type: BatterySimple
energy_capacity: 100.0 # kWh
charge_rate: 50.0 # kW
discharge_rate: 50.0 # kW
max_SOC: 0.9
min_SOC: 0.1
log_channels:
- power
- soc
- power_setpoint
initial_conditions:
SOC: 0.5
```

If `log_channels` is not specified, only `power` will be logged.


## `BatterySimple`

Expand Down
117 changes: 117 additions & 0 deletions docs/electrolyzer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Electrolyzer Plant

The hydrogen electrolyzer modules use the [electrolyzer](https://github.com/NREL/electrolyzer) package developed by the National Laboratory of the Rockies to predict hydrogen output of hydrogen electrolyzer plants. This repo contains models for PEM and Alkaline electrolyzer cell types.

To create a hydrogen electrolyzer plant, set `component_type` = `ElectrolyzerPlant` in the input dictionary (.yaml file).


## Inputs

#### Required Parameters
The parameters listed below are required unless otherwise specified as *Optional*.

- `general`: General simulation parameters.
- `initial_conditions`: Initial conditions for the simulation including:
- `power_available_kw`: Initial power available to the electrolyzer [kW]
- `electrolyzer`: Electrolyzer plant specific parameters including:
- `initialize`: boolean. Whether to initialize the electrolyzer.
- `initial_power_kW`: Initial power input to the electrolyzer [kW].
- `supervisor`:
- `system_rating_MW`: Total system rating in MW.
- `n_stacks`: Number of electrolyzer stacks in the plant.
- `stack`: Electrolyzer stack parameters including:
- `cell_type`: Type of electrolyzer cell (e.g., PEM, Alkaline).
- `max_current`: Maximum current of the stack [A].
- `temperature`: Stack operating temperature [degC].
- `n_cells`: Number of cells per stack.
- `min_power`: Minimum power for electrolyzer operation [kW].
- `stack_rating_kW`: Stack rated power [kW].
- `include_degradation_penalty`: *Optional* Whether to include degradation penalty.
- `hydrogen_degradation_penalty`: *Optional* boolean, whether degradation is applied to hydrogen (True) or power (False)
- `cell_params`: Electrolyzer cell parameters including:
- `cell_area`: Area of individual cells in the stack [cm^2].
- `turndown_ratio`: Minimum turndown ratio for stack operation [between 0 and 1].
- `max current_density`: Maximum current density [A/cm^2].
- `p_anode`: Anode operating pressure [bar].
- `p_cathode`: Cathode operating pressure [bar].
- `alpha_a`: anode charge transfer coefficient.
- `alpha_c`: cathode charge transfer coefficient.
- `i_0_a`: anode exchange current density [A/cm^2].
- `i_0_c`: cathode exchange current density [A/cm^2].
- `e_m`: membrane thickness [cm].
- `R_ohmic_elec`: electrolyte resistance [A*cm^2].
- `f_1`: Faradaic coefficient [mA^2/cm^4].
- `f_2`: Faradaic coefficient [mA^2/cm^4].
- `degradation`: Electrolyzer degradation parameters including:
- `eol_eff_percent_loss`: End of life efficiency percent loss [%].
- `PEM_params` or `ALK_params`: Degradation parameters specific to PEM or Alkaline cells:
- `rate_steady`: Rate of voltage degradation under steady operation alone
- `rate_fatigue`: Rate of voltage degradation under variable operation alone
- `rate_onoff`: Rate of voltage degradation per on/off cycle
- `controller`: Electrolyzer control parameters including:
- `control_type`: Controller type for electrolyzer plant operation.
- `costs`: *Optional* Cost parameters for the electrolyzer plant including:
- `plant_params`:
- `plant_life`: integer, Plant life in years
- `pem_location`: Location of the PEM electrolyzer. Options are
[onshore, offshore, in-turbine]
- `grid_connected`: boolean, Whether the plant is connected to the grid or not
- `feedstock`: Parameters related to the feedstock including:
- `water_feedstock_cost`: Cost of water per kg of water
- `water_per_kgH2`: Amount of water required per kg of hydrogen produced
- `opex`: Operational expenditure parameters including:
- `var_OM`: Variable operation and maintenance cost per kW
- `fixed_OM`: Fixed operation and maintenance cost per kW-year
- `stack_replacement`: Parameters related to stack replacement costs including:
- `d_eol`: End of life cell voltage value [V]
- `stack_replacement_percent`: Stack replacement cost as a percentage of CapEx [0,1]
- `capex`: Capital expenditure parameters including:
- `capex_learning_rate`: Capital expenditure learning rate.
- `ref_cost_bop`: Reference cost of balance of plant per kW.
- `ref_size_bop`: Reference size of balance of plant in kW.
- `ref_cost_pem`: Reference cost of PEM electrolyzer stack per kW.
- `ref_size_pem`: Reference size of PEM electrolyzer stack in kW.
- `finances`: Financial parameters including:
- `discount_rate`: Discount rate for financial calculations [%].
- `install_factor`: Installation factor for capital expenditure [0,1].
- `log_channels`: List of output channels to log (see [Logging Configuration](elec-logging-configuration) below)


## Outputs
(elec-logging-configuration)=
**Logging Configuration**

The `log_channels` parameter controls which outputs are written to the HDF5 output file. This is a list of channel names. The `power` channel is always logged, even if not explicitly specified.


### Available Channels

**Scalar Channels:**
- `H2_output`: Total hydrogen produced during the last timestep
- `H2_mfr`: Mass flow rate of the hydrogen production in kg/s
- `power`: Power that the electrolyzer plant used to create hydrogen (kW). This follows the convention that power consumed is negative power.
- `Power_input_kw`: Power allocated to the electrolyzer plant to use (kW)
- `stacks_on`: Total number of stacks producing hydrogen

**Array Channels:**
- `stacks_waiting`: Boolean list of the stacks that are waiting to start producing hydrogen (True for stacks waiting, False for stacks not waiting)


**Example:**
```yaml
ele:
component_type: ElectrolyzerPlant
log_channels:
- power
- H2_output
- H2_mfr
initial_conditions:
- power_available_kw: 3000
electrolyzer:
# ... other parameters
```

If `log_channels` is not specified, only `power` will be logged.

## References
1. Z. Tully, G. Starke, K. Johnson and J. King, "An Investigation of Heuristic Control Strategies for Multi-Electrolyzer Wind-Hydrogen Systems Considering Degradation," 2023 IEEE Conference on Control Technology and Applications (CCTA), Bridgetown, Barbados, 2023, pp. 817-822, doi: 10.1109/CCTA54093.2023.10252187.
41 changes: 0 additions & 41 deletions docs/emulator.md

This file was deleted.

15 changes: 13 additions & 2 deletions docs/examples_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ Hercules includes several example cases that demonstrate different simulation co
## Available Examples

- [00: Wind Farm Only](../examples/00_wind_farm_only/) - Simple wind farm simulation with generated wind data
- [01: Wind Farm DOF1 Model](../examples/01_wind_farm_dof1_model/) - 1-DOF long-duration wind simulation
- [01: Wind Farm DOF1 Model](../examples/01_wind_farm_dof1_model/) - 1-DOF long-duration wind simulation
- [02: Wind Farm Realistic Inflow](../examples/02_wind_farm_realistic_inflow/) - Large-scale wind farm with longer running wind data
- [02b: Wind Farm Realistic Inflow (Precomputed FLORIS)](../examples/02b_wind_farm_realistic_inflow_precom_floris/) - Optimized version using precomputed wake deficits
- [03: Wind and Solar](../examples/03_wind_and_solar/) - Hybrid wind and solar plant with interconnect limits
- [04: Wind and Storage](../examples/04_wind_and_storage/) - Wind farm with battery storage system
- [05: Wind and Storage with LMP](../examples/05_wind_and_storage_with_lmp/) - Battery control based on electricity pricing with selective external data logging
- [06: Wind and Hydrogen](../examples/06_wind_and_hydrogen/) - Wind farm with electrolyzer for hydrogen production

## Input Data Management

All examples use centralized input files located in `examples/inputs/`:
- Wind data files (`.ftr` format)
- Solar data files (`.ftr` format)
- Solar data files (`.ftr` format)
- FLORIS configuration files (`.yaml`)
- Turbine model files (`.yaml`)
- PV system configuration files (`.json`)
Expand All @@ -36,3 +38,12 @@ python hercules_runscript.py
```

No manual setup is required - all necessary input files will be automatically generated on first run.

## Additional Resource Downloading and Upsampling Examples

Examples are provided in the `examples/inputs/` folder demonstrating how to download wind and solar data using the `hercules.resource.wind_solar_resource_downloader` module and upsample wind data using the `hercules.resource.upsample_wind_data` module to create inputs for Hercules simulations.

- [03: Download NSRDB and WIND Toolkit Solar and Wind Data](../examples/inputs/03_download_small_nsrdb_wtk_solar_wind_example.py) - Downloads a subset of solar and wind data for a small grid of locations for a single year from the NSRDB and WIND Toolkit datasets, respectively
- [04: Download and Upsample WIND Toolkit Wind Data](../examples/inputs/04_download_and_upsample_wtk_wind_example.py) - Downloads wind speed and direction for a small grid of locations for a single year from the WIND Toolkit dataset, then spatially interpolates the data at specific wind turbine locations and temporally upsamples the times series with added turbulence
- [05: Download Open-Meteo Solar and Wind Data](../examples/inputs/05_download_small_openmeteo_solar_wind_example.py) - Downloads a subset of solar and wind data for a small grid of locations for a single year using the Open-Meteo API
- [06: Download and Upsample Open-Meteo Wind Data](../examples/inputs/06_download_and_upsample_openmeteo_wind_example.py) - Downloads wind speed and direction for a small grid of locations for a single year using the Open-Meteo API, then spatially interpolates the data at specific wind turbine locations and temporally upsamples the times series with added turbulence
Loading