-
Notifications
You must be signed in to change notification settings - Fork 21
Open cycle gas turbine model and thermal power plant base class #189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
genevievestarke
merged 73 commits into
NatLabRockies:develop
from
paulf81:feature/add_ct
Feb 17, 2026
Merged
Changes from all commits
Commits
Show all changes
73 commits
Select commit
Hold shift + click to select a range
3ccb8e3
Add combustion turbine model
b7b4696
add to hybrid plant
0f65a52
add to utilities
b9e8200
add first test
9eb9535
add new example
36d5493
add test dicts
7cf9dca
Merge branch 'develop' into feature/add_ct
24896c6
address comment
1e386a1
standardize to min_stable_load_fraction
cc58bd0
address comment
dca6e13
clean up state_num error checks
ce8d2c7
clean up step function
494538d
add else case
1bc2961
linting
d75f6e0
fix long line
eccc7a7
fix long line
48594a7
fix comment
8befd4d
adjust timing
feaad7b
Add tests for Ct
6537bb5
add combustion turbine docs
5234a6d
Add 07 example
eb56021
Merge branch 'develop' into feature/add_ct
747a05d
remove combustion turbine model
20e7b77
add thermal component base
0f3870e
add tests
c08227f
update h_dict
bee19b2
linting
6367251
add ocgt
c3e2495
route ocgt
c7d139c
rename example
cf13402
linting
e8b778b
update example 7
bd367c6
update utilities
5d20da4
bugfix
0507d5d
add shell post-process test
313a95f
update docs
05cbc68
Merge branch 'develop' into pr/paulf81/189
69b426a
Add 07 doc
d5b2880
Update hercules/hybrid_plant.py
f5551fe
Merge branch 'develop' into pr/paulf81/189
8ab6150
harmonize comments
5cca1bf
clarify comment
84e1251
Fix comment
055da8d
add warm start state and hard code start state time definitions
07818bf
refactor from heat_rate to efficiency
96ed0ee
add tests
bb2b22b
update test defaults
ffb5f53
linting
4a50d3a
start shutdown behavior within on state
77b0db7
Fix test
6aaef2c
docstring fix
43b5d03
add limit to run up ramp
fa6befe
remove redundant line
9745eaa
Update tests/thermal_component_base_test.py
0aa3188
Merge branch 'feature/add_ct' of github.com:paulf81/hercules into pr/…
1480166
clearer controller name
7ce14ad
Update tests/thermal_component_base_test.py
dc2853a
Update examples/07_ocgt/hercules_input.yaml
5b89a94
Refactor states to an enum
8a27cfb
Remove .value
d9c058b
Change initial condition behavior
4bea937
rename fuel values
edaa598
Refactor to rate
ad8d6f2
specify effiency in HHV and provide defaults
eff4d9a
rename example 7
0af88bd
linting
48d5778
remove get initial conditions
65c45ab
add get initial conditions to base class
315c208
remove state names property
f652bc6
Make component_name and types to be class attributes
603e372
rename calc functions
53343b2
Update with minor notes on specific turbine
genevievestarke 314fec2
Fix ruff formatting
genevievestarke File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider naming this, as well as the actual example directory, open_cycle_gas_turbine for clarity
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Renaming the example now |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Example 07: Open Cycle Gas Turbine (OCGT) | ||
|
|
||
| ## Description | ||
|
|
||
| This example demonstrates a standalone open-cycle gas turbine (OCGT) simulation. The example showcases the turbine's state machine behavior including startup sequences, power ramping, minimum stable load constraints, and shutdown sequences. | ||
|
|
||
| For details on OCGT parameters and configuration, see {doc}`../open_cycle_gas_turbine`. For details on the underlying state machine and ramp behavior, see {doc}`../thermal_component_base`. | ||
|
|
||
| ## Scenario | ||
|
|
||
| The simulation runs for 6 hours with 1-minute time steps. A controller commands the turbine through several operating phases. The table below shows both **control commands** (setpoint changes) and **state transitions** (responses to commands based on constraints). | ||
|
|
||
| ### Timeline | ||
|
|
||
| | Time (min) | Event Type | Setpoint | State | Description | | ||
| |------------|------------|----------|-------|-------------| | ||
| | 0 | Initial | 0 | OFF (0) | Turbine starts off, `time_in_state` begins counting | | ||
| | 40 | Command | → 100 MW | OFF (0) | Setpoint changes to full power, but `min_down_time` (60 min) not yet satisfied—turbine remains off | | ||
| | 60 | State | 100 MW | → HOT STARTING (1) | `min_down_time` satisfied, turbine begins hot starting sequence | | ||
| | ~64 | State | 100 MW | HOT STARTING (1) | `hot_readying_time` (~4.2 min) complete, run-up ramp begins | | ||
| | ~68 | State | 100 MW | → ON (4) | Power reaches P_min (20 MW) after `hot_startup_time` (~8.2 min), turbine now operational | | ||
| | ~76 | Ramp | 100 MW | ON (4) | Power reaches 100 MW (ramped at 10 MW/min from P_min) | | ||
| | 120 | Command | → 50 MW | ON (4) | Setpoint reduced to 50% capacity | | ||
| | ~125 | Ramp | 50 MW | ON (4) | Power reaches 50 MW (ramped down at 10 MW/min) | | ||
| | 180 | Command | → 10 MW | ON (4) | Setpoint reduced to 10% (below P_min), power clamped to P_min | | ||
| | ~183 | Ramp | 10 MW | ON (4) | Power reaches P_min (20 MW), cannot go lower | | ||
| | 210 | Command | → 100 MW | ON (4) | Setpoint increased to full power | | ||
| | ~218 | Ramp | 100 MW | ON (4) | Power reaches 100 MW | | ||
| | 240 | Command + State | → 0 | → STOPPING (5) | Shutdown command; `min_up_time` satisfied (~172 min on), begins stopping sequence | | ||
| | ~250 | State | 0 | → OFF (0) | Power reaches 0 (ramped down at 10 MW/min), turbine off | | ||
| | 360 | End | 0 | OFF (0) | Simulation ends | | ||
|
|
||
| ### Key Behaviors Demonstrated | ||
|
|
||
| - **Minimum down time**: The turbine cannot start until `min_down_time` (60 min) is satisfied, even though the command is issued at 40 min | ||
| - **Hot startup sequence**: After `min_down_time`, the turbine enters HOT STARTING, waits through `hot_readying_time`, then ramps to P_min using `run_up_rate` | ||
| - **Ramp rate constraints**: All power changes in ON state are limited by `ramp_rate` (10 MW/min) | ||
| - **Minimum stable load**: When commanded to 10 MW (below P_min = 20 MW), power is clamped to P_min | ||
| - **Minimum up time**: Shutdown is allowed immediately at 240 min because `min_up_time` (60 min) was satisfied long ago | ||
| - **Stopping sequence**: The turbine ramps down to zero at `ramp_rate` before transitioning to OFF | ||
|
|
||
| ## Setup | ||
|
|
||
| No manual setup is required. The example uses only the OCGT component which requires no external data files. | ||
|
|
||
| ## Running | ||
|
|
||
| To run the example, execute the following command in the terminal: | ||
|
|
||
| ```bash | ||
| python hercules_runscript.py | ||
| ``` | ||
|
|
||
| ## Outputs | ||
|
|
||
| To plot the outputs, run: | ||
|
|
||
| ```bash | ||
| python plot_outputs.py | ||
| ``` | ||
|
|
||
| The plot shows: | ||
| - Power output over time (demonstrating ramp constraints and minimum stable load) | ||
| - Operating state transitions | ||
| - Fuel consumption tracking | ||
| - Heat rate variation with load | ||
paulf81 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| # Open Cycle Gas Turbine | ||
|
|
||
| The `OpenCycleGasTurbine` class models an open-cycle gas turbine (OCGT), also known as a peaker plant or simple-cycle gas turbine. Since this class is focused on peaker plant behavior, this class was developed based on aeroderivative engines. It is a subclass of {doc}`ThermalComponentBase <thermal_component_base>` and inherits all state machine behavior, ramp constraints, and operational logic from the base class. | ||
|
|
||
| For details on the state machine, startup/shutdown behavior, and base parameters, see {doc}`thermal_component_base`. | ||
|
|
||
| ## OCGT-Specific Parameters | ||
|
|
||
| The OCGT class provides default values for natural gas properties from [6]: | ||
|
|
||
| | Parameter | Units | Default | Description | | ||
| |-----------|-------|---------|-------------| | ||
| | `hhv` | J/m³ | 39050000 | Higher heating value of natural gas (39.05 MJ/m³) [6] | | ||
| | `fuel_density` | kg/m³ | 0.768 | Fuel density for mass calculations [6] | | ||
|
|
||
| The `efficiency_table` parameter is **optional**. If not provided, default values based on approximate readings from the SC1A curve in Exhibit ES-4 of [5] are used. All efficiency values are **HHV (Higher Heating Value) net plant efficiencies**. See {doc}`thermal_component_base` for details on the efficiency table format. | ||
|
|
||
| ## Default Parameter Values | ||
|
|
||
| The `OpenCycleGasTurbine` class provides default values for base class parameters based on References [1-5]. Only `rated_capacity` and `initial_conditions` are required in the YAML configuration. | ||
|
|
||
| | Parameter | Default Value | Source | | ||
| |-----------|---------------|--------| | ||
| | `min_stable_load_fraction` | 0.40 (40%) | [4] | | ||
| | `ramp_rate_fraction` | 0.10 (10%/min) | [1] | | ||
| | `run_up_rate_fraction` | Same as `ramp_rate_fraction` | — | | ||
| | `hot_startup_time` | 420 s (7 minutes) | [1], [5] | | ||
| | `warm_startup_time` | 480 s (8 minutes) | [1], [5] | | ||
| | `cold_startup_time` | 480 s (8 minutes) | [1], [5] | | ||
| | `min_up_time` | 1800 s (30 minutes) | [4] | | ||
| | `min_down_time` | 3600 s (1 hour) | [4] | | ||
| | `hhv` | 39050000 J/m³ (39.05 MJ/m³) | [6] | | ||
| | `fuel_density` | 0.768 kg/m³ | [6] | | ||
| | `efficiency_table` | SC1A HHV net efficiency (see below) | Exhibit ES-4 of [5] | | ||
|
|
||
| ### Default Efficiency Table | ||
|
|
||
| The default HHV net plant efficiency table is based on approximate readings from the SC1A (simple cycle) curve in Exhibit ES-4 of [5]: | ||
|
|
||
| | Power Fraction | HHV Net Efficiency | | ||
| |---------------|-------------------| | ||
| | 1.00 | 0.39 (39%) | | ||
| | 0.75 | 0.37 (37%) | | ||
| | 0.50 | 0.325 (32.5%) | | ||
| | 0.25 | 0.245 (24.5%) | | ||
|
|
||
| ## OCGT Outputs | ||
|
|
||
| The OCGT model provides the following outputs (inherited from base class): | ||
|
|
||
| | Output | Units | Description | | ||
| |--------|-------|-------------| | ||
| | `power` | kW | Actual power output | | ||
| | `state` | integer | Operating state number (0-5), corresponding to the `STATES` enum | | ||
| | `efficiency` | fraction (0-1) | Current HHV net plant efficiency | | ||
| | `fuel_volume_rate` | m³/s | Fuel volume flow rate | | ||
| | `fuel_mass_rate` | kg/s | Fuel mass flow rate (computed using `fuel_density` [6]) | | ||
|
|
||
| ### Efficiency and Fuel Rate | ||
|
|
||
| HHV net plant efficiency varies with load based on the `efficiency_table`. The fuel volume rate is calculated as: | ||
|
|
||
| $$ | ||
| \text{fuel\_volume\_rate} = \frac{\text{power}}{\text{efficiency} \times \text{hhv}} | ||
| $$ | ||
|
|
||
| Where: | ||
| - `power` is in W (converted from kW internally) | ||
| - `efficiency` is the HHV net efficiency interpolated from the efficiency table | ||
| - `hhv` is the higher heating value in J/m³ (default 39.05 MJ/m³ for natural gas [6]) | ||
| - Result is fuel volume rate in m³/s | ||
|
|
||
| The fuel mass rate is then computed from the volume rate using the fuel density [6]: | ||
|
|
||
| $$ | ||
| \text{fuel\_mass\_rate} = \text{fuel\_volume\_rate} \times \text{fuel\_density} | ||
| $$ | ||
|
|
||
| Where: | ||
| - `fuel_volume_rate` is in m³/s | ||
| - `fuel_density` is in kg/m³ (default 0.768 kg/m³ for natural gas [6]) | ||
| - Result is fuel mass rate in kg/s | ||
|
|
||
| ## YAML Configuration | ||
|
|
||
| ### Minimal Configuration | ||
|
|
||
| Required parameters only (uses defaults for `hhv`, `efficiency_table`, and other parameters): | ||
|
|
||
| ```yaml | ||
| open_cycle_gas_turbine: | ||
| component_type: OpenCycleGasTurbine | ||
| rated_capacity: 100000 # kW (100 MW) | ||
| initial_conditions: | ||
| power: 0 # 0 kW means OFF; power > 0 means ON | ||
| ``` | ||
|
|
||
| ### Full Configuration | ||
|
|
||
| All parameters explicitly specified: | ||
|
|
||
| ```yaml | ||
| open_cycle_gas_turbine: | ||
| component_type: OpenCycleGasTurbine | ||
| rated_capacity: 100000 # kW (100 MW) | ||
| min_stable_load_fraction: 0.4 # 40% minimum operating point | ||
| ramp_rate_fraction: 0.1 # 10%/min ramp rate | ||
| run_up_rate_fraction: 0.05 # 5%/min run up rate | ||
| hot_startup_time: 420.0 # 7 minutes | ||
| warm_startup_time: 480.0 # 8 minutes | ||
| cold_startup_time: 480.0 # 8 minutes | ||
| min_up_time: 1800 # 30 minutes | ||
| min_down_time: 3600 # 1 hour | ||
| hhv: 39050000 # J/m³ for natural gas (39.05 MJ/m³) [6] | ||
| fuel_density: 0.768 # kg/m³ for natural gas [6] | ||
| efficiency_table: | ||
| power_fraction: | ||
| - 1.0 | ||
| - 0.75 | ||
| - 0.50 | ||
| - 0.25 | ||
| efficiency: # HHV net plant efficiency from SC1A in Exhibit ES-4 of [5] | ||
| - 0.39 | ||
| - 0.37 | ||
| - 0.325 | ||
| - 0.245 | ||
| log_channels: | ||
| - power | ||
| - fuel_volume_rate | ||
| - fuel_mass_rate | ||
| - state | ||
| - efficiency | ||
| - power_setpoint | ||
| initial_conditions: | ||
| power: 0 # 0 kW means OFF; power > 0 means ON | ||
| ``` | ||
|
|
||
| ## Logging Configuration | ||
|
|
||
| The `log_channels` parameter controls which outputs are written to the HDF5 output file. | ||
|
|
||
| **Available Channels:** | ||
| - `power`: Actual power output in kW (always logged) | ||
| - `state`: Operating state number (0-5), corresponding to the `STATES` enum | ||
| - `fuel_volume_rate`: Fuel volume flow rate in m³/s | ||
| - `fuel_mass_rate`: Fuel mass flow rate in kg/s (computed using `fuel_density` [6]) | ||
| - `efficiency`: Current HHV net plant efficiency (0-1) | ||
| - `power_setpoint`: Requested power setpoint in kW | ||
|
|
||
| ## References | ||
|
|
||
| 1. Agora Energiewende (2017): "Flexibility in thermal power plants - With a focus on existing coal-fired power plants." | ||
|
|
||
| 2. "Impact of Detailed Parameter Modeling of Open-Cycle Gas Turbines on Production Cost Simulation", NREL/CP-6A40-87554, National Renewable Energy Laboratory, 2024. | ||
|
|
||
| 3. Deane, J.P., G. Drayton, and B.P. Ó Gallachóir. "The Impact of Sub-Hourly Modelling in Power Systems with Significant Levels of Renewable Generation." Applied Energy 113 (January 2014): 152–58. https://doi.org/10.1016/j.apenergy.2013.07.027. | ||
|
|
||
| 4. IRENA (2019), Innovation landscape brief: Flexibility in conventional power plants, International Renewable Energy Agency, Abu Dhabi. | ||
|
|
||
| 5. M. Oakes, M. Turner, "Cost and Performance Baseline for Fossil Energy Plants, Volume 5: Natural Gas Electricity Generating Units for Flexible Operation," National Energy Technology Laboratory, Pittsburgh, May 5, 2023. | ||
|
|
||
| 6. I. Staffell, "The Energy and Fuel Data Sheet," University of Birmingham, March 2011. https://claverton-energy.com/cms4/wp-content/uploads/2012/08/the_energy_and_fuel_data_sheet.pdf |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the _static/ folder for? Not something I'm familiar with
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand this is the conventional place to put images when building docs with jupyter-book