From 7736931ddfcb1f8a5384b1e6c4df33f097650a91 Mon Sep 17 00:00:00 2001 From: paulf81 Date: Mon, 2 Feb 2026 09:39:06 -0700 Subject: [PATCH 1/6] fix git ignore file --- .gitignore | 142 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 65d20905..4c17b317 100644 --- a/.gitignore +++ b/.gitignore @@ -1,78 +1,114 @@ -# Gitignore file +# ============================================================================= +# Python +# ============================================================================= *.pyc -*.log -*.egg-info -data.db +__pycache__/ +*.egg-info/ *.python-version -*.DS_Store -*.conda -*.sqlite -slices -# macOS files +# ============================================================================= +# macOS +# ============================================================================= .DS_Store +__MACOSX/ -# ide settings and files -.idea -.vscode +# ============================================================================= +# IDE/Editor Settings +# ============================================================================= +.idea/ +.vscode/ +.cursor/rules/ -# Some c++ stuff -a.out -*.plist -test_client.dSYM +# ============================================================================= +# Jupyter Notebooks +# ============================================================================= *checkpoint.ipynb -hercules/sampling00000.nc -hercules/front_end.db -hercules/control_center.db -hercules/test_client_cpp/test_client -hercules/df_flow.p -hercules/flow_data.p - -t_*.txt -hercules/sample_copy.nc -hercules/t_0* -hercules/local_amr_wind_demo/sample_copy.nc +*.nbconvert.ipynb +.ipynb_checkpoints/ -#Ignore csv files +# ============================================================================= +# Data Files (large/generated) +# ============================================================================= +# CSV files (except test inputs) *.csv !tests/test_inputs/*.csv -!example_case_folders/00_wind_farm_only/inputs/floris_standin_data.csv -!example_case_folders/00_wind_farm_only/inputs/wind_power_reference_data.csv -# h5 files +# Binary data formats *.h5 *.hdf5 +*.feather +*.ftr +*.parquet -# Larger wind input file -wind_resource_rex +# Pickle files (generated input data) +*.p +*.pkl -# Wind input pickle files -wind_input.p +# Large wind resource data +wind_resource_rex/ -# Solar input pickle files -solar_input.p +# ============================================================================= +# Hercules Simulation Outputs +# ============================================================================= +# Output directories contain generated results +outputs/ -# Intermediate notebook files -*.nbconvert.ipynb -*.ipynb_checkpoints +# Log files (generated during simulation) +*.log -# Some output files to ignore +# H_dict echo files (simulation state dumps) +*.echo + +# ============================================================================= +# Documentation Build Artifacts +# ============================================================================= +docs/_build/ + +# ============================================================================= +# Testing/CI Artifacts +# ============================================================================= +.pytest_cache/ +.ruff_cache/ + +# ============================================================================= +# LEGACY HERCULES - May remove in future cleanup +# ============================================================================= +# Old example folder path (renamed to examples/) +!example_case_folders/00_wind_farm_only/inputs/floris_standin_data.csv +!example_case_folders/00_wind_farm_only/inputs/wind_power_reference_data.csv + +# C++ build artifacts (from old AMR-Wind integration) +a.out +*.plist +test_client.dSYM +hercules/test_client_cpp/test_client + +# NetCDF files (from old AMR-Wind demos) +hercules/sampling00000.nc +hercules/sample_copy.nc +hercules/local_amr_wind_demo/sample_copy.nc + +# Database files (from old front-end/control center) +data.db +*.sqlite +*.conda +hercules/front_end.db +hercules/control_center.db + +# Old data/flow pickle files +hercules/df_flow.p +hercules/flow_data.p + +# AMR-Wind time step outputs +t_*.txt +hercules/t_0* t_00* +slices + +# Old log file patterns (now covered by *.log) logdummy loghelics loghercules* logstandin* logfloris* -*echo *out-example.json - -.vscode/* - -# Doc builds -docs/_build -docs/examples - -.cursor/rules/ -*.feather -*.ftr -*.parquet From 93376c970d4d65881d80c29190f346428652101a Mon Sep 17 00:00:00 2001 From: paulf81 Date: Mon, 2 Feb 2026 09:39:20 -0700 Subject: [PATCH 2/6] Add examples docs pages --- docs/examples/00_wind_farm_only.md | 25 ++++++++++ docs/examples/01_wind_farm_dof1_model.md | 24 +++++++++ .../examples/02_wind_farm_realistic_inflow.md | 25 ++++++++++ ...ind_farm_realistic_inflow_precom_floris.md | 42 ++++++++++++++++ docs/examples/03_wind_and_solar.md | 24 +++++++++ docs/examples/04_wind_and_storage.md | 25 ++++++++++ docs/examples/05_wind_and_storage_with_lmp.md | 5 ++ docs/examples/06_wind_and_hydrogen.md | 49 +++++++++++++++++++ 8 files changed, 219 insertions(+) create mode 100644 docs/examples/00_wind_farm_only.md create mode 100644 docs/examples/01_wind_farm_dof1_model.md create mode 100644 docs/examples/02_wind_farm_realistic_inflow.md create mode 100644 docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md create mode 100644 docs/examples/03_wind_and_solar.md create mode 100644 docs/examples/04_wind_and_storage.md create mode 100644 docs/examples/05_wind_and_storage_with_lmp.md create mode 100644 docs/examples/06_wind_and_hydrogen.md diff --git a/docs/examples/00_wind_farm_only.md b/docs/examples/00_wind_farm_only.md new file mode 100644 index 00000000..c78df4a0 --- /dev/null +++ b/docs/examples/00_wind_farm_only.md @@ -0,0 +1,25 @@ +# Example 00: Wind only + +## Description + +This example demonstrates a simple wind farm simulation using generated wind data. The simulation uses a small wind farm configuration with basic turbine control. + +## Setup + +No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. + +## Running + +To run the example, execute the following command in the terminal: + +```bash +python hercules_runscript.py +``` + +## Outputs + +To plot the outputs run the following command in the terminal: + +```bash +python plot_outputs.py +``` \ No newline at end of file diff --git a/docs/examples/01_wind_farm_dof1_model.md b/docs/examples/01_wind_farm_dof1_model.md new file mode 100644 index 00000000..97264833 --- /dev/null +++ b/docs/examples/01_wind_farm_dof1_model.md @@ -0,0 +1,24 @@ +# Example 01: Wind Only: 1-DOF model + +## Description + +This example runs the 1-DOF long-duration wind simulation. + +## Pre setup + +Make sure to first generate the wind input file using generate_wind_history.ipynb + +## Running + +To run the example, execute the following command in the terminal: + +```bash +python hercules_runscript.py +``` +## Outputs + +To plot the outputs run the following command in the terminal: + +```bash +python plot_outputs.py +``` diff --git a/docs/examples/02_wind_farm_realistic_inflow.md b/docs/examples/02_wind_farm_realistic_inflow.md new file mode 100644 index 00000000..ad8bff56 --- /dev/null +++ b/docs/examples/02_wind_farm_realistic_inflow.md @@ -0,0 +1,25 @@ +# Example 02: Wind Farm Realistic Inflow + +## Description + +In this case uses a large set of synthetic wind data. + +## Setup + +No manual setup is required. The example automatically generates the necessary input files (large-scale wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. + + +## Running + +To run the example, execute the following command in the terminal: + +```bash +python hercules_runscript.py +``` +## Outputs + +To plot the outputs run the following command in the terminal: + +```bash +python plot_outputs.py +``` \ No newline at end of file diff --git a/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md new file mode 100644 index 00000000..13b17567 --- /dev/null +++ b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md @@ -0,0 +1,42 @@ +# Example 02b: Wind Farm Realistic Inflow (Precomputed FLORIS) + +## Description + +This example is identical to `02_wind_farm_realistic_inflow` with the exception that the `Wind_MesoToPowerPrecomFloris` +class is used to speed up the simulation. This example automatically generates the necessary input files in the centralized `examples/inputs/` folder when first run. + +Note the caveats to using this class from the docs: + + +> In contrast to the Wind_MesoToPower class, this class pre-computes the FLORIS wake + deficits for all possible wind speeds and power setpoints. This is done by running for + all wind speeds and wind directions (but not over all power setpoints). This is valid + for cases where the wind farm is operating: + - all turbines operating normally + - all turbines off + - following a wind-farm wide derating level + + It is in practice conservative with respect to the wake deficits, but it is more efficient + than running FLORIS for each condition. In cases where turbines are: + - partially derated below the curtailment level + - not uniformly curtailed or some turbines are off + + This is not an appropriate model and the more general Wind_MesoToPower class should be used. + + + + +## Running + +To run the example, execute the following command in the terminal: + +```bash +python hercules_runscript.py +``` +## Outputs + +To plot the outputs run the following command in the terminal: + +```bash +python plot_outputs.py +``` \ No newline at end of file diff --git a/docs/examples/03_wind_and_solar.md b/docs/examples/03_wind_and_solar.md new file mode 100644 index 00000000..8fdddb3c --- /dev/null +++ b/docs/examples/03_wind_and_solar.md @@ -0,0 +1,24 @@ +# Example 03: Wind and solar hybrid plant + +## Description + +In this setup, wind and solar are combined in a hybrid plant. For demonstration, the plant has a fixed interconnect limit of 3000 kW, which is much below the combined capacity of the wind and solar farms. A simple controller limits the solar power to keep the total power below the interconnect limit. + +## Setup + +No manual setup is required. The example automatically generates the necessary input files (wind data, solar data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. + +## Running + +To run the example, execute the following command in the terminal: + +```bash +python hercules_runscript.py +``` +## Outputs + +To plot the outputs run the following command in the terminal: + +```bash +python plot_outputs.py +``` \ No newline at end of file diff --git a/docs/examples/04_wind_and_storage.md b/docs/examples/04_wind_and_storage.md new file mode 100644 index 00000000..5922a45f --- /dev/null +++ b/docs/examples/04_wind_and_storage.md @@ -0,0 +1,25 @@ +# Example 04: Wind and storage hybrid plant + +## Description + +Example of a wind and storage hybrid plant where the storage is constrained to charge only using power produced by the wind farm. + +## Setup + +No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. + + +## Running + +To run the example, execute the following command in the terminal: + +```bash +python hercules_runscript.py +``` +## Outputs + +To plot the outputs run the following command in the terminal: + +```bash +python plot_outputs.py +``` \ No newline at end of file diff --git a/docs/examples/05_wind_and_storage_with_lmp.md b/docs/examples/05_wind_and_storage_with_lmp.md new file mode 100644 index 00000000..bf82ccbf --- /dev/null +++ b/docs/examples/05_wind_and_storage_with_lmp.md @@ -0,0 +1,5 @@ +# Example 05: Wind and Storage with LMP-Based Control + +## Overview + +This example demonstrates a wind farm with battery storage using a controller that responds to Locational Marginal Pricing (LMP) signals. It also showcases the **selective external data logging** feature, where external data can be accessed by the controller but selectively logged to the output file. diff --git a/docs/examples/06_wind_and_hydrogen.md b/docs/examples/06_wind_and_hydrogen.md new file mode 100644 index 00000000..174b324b --- /dev/null +++ b/docs/examples/06_wind_and_hydrogen.md @@ -0,0 +1,49 @@ +# Example 06: Wind and Hydrogen + +## Description + +This example demonstrates a wind and hydrogen hybrid plant where power that the wind farm produces goes directly to hydrogen electrolysis. This configuration is useful for understanding how renewable energy can be directly converted to hydrogen for energy storage or industrial applications. + +## Key Features + +- Wind farm power generation +- Electrolyzer plant for hydrogen production +- Direct power flow from wind to electrolyzer +- Hydrogen production tracking + +## Setup + +No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. + +## Running the Example + +To run the example, execute the following command in the terminal: + +```bash +cd examples/06_wind_and_hydrogen/ +python hercules_runscript.py +``` + +## Visualizing Outputs + +To plot the outputs, run the following command: + +```bash +python plot_outputs.py +``` + +## Expected Results + +The simulation will produce outputs showing: +- Wind farm power generation over time +- Hydrogen production rates +- Electrolyzer stack status +- Power consumption by the electrolyzer + +## Configuration + +The example uses: +- Wind farm with FLORIS wake modeling +- Electrolyzer plant with multiple stacks +- Hydrogen reference signal for electrolyzer control (from `inputs/hydrogen_ref_signal.csv`) + From c4e83dfbcbbea868a81b76f21a5964dce839fd0f Mon Sep 17 00:00:00 2001 From: paulf81 Date: Mon, 2 Feb 2026 11:30:48 -0700 Subject: [PATCH 3/6] Consolidate readmes into docs --- docs/_toc.yml | 3 +- docs/examples/00_wind_farm_only.md | 2 +- docs/examples/01_wind_farm_dof1_model.md | 9 ++-- ...w.md => 02a_wind_farm_realistic_inflow.md} | 8 ++-- ...ind_farm_realistic_inflow_precom_floris.md | 20 ++++----- .../02c_wind_farm_realistic_inflow_direct.md | 6 +-- docs/examples/03_wind_and_solar.md | 5 ++- docs/examples/04_wind_and_storage.md | 6 +-- docs/examples/05_wind_and_storage_with_lmp.md | 44 +++++++++++++++++-- docs/examples/06_wind_and_hydrogen.md | 34 +++----------- examples/00_wind_farm_only/README.md | 25 ----------- examples/01_wind_farm_dof1_model/README.md | 24 ---------- .../02a_wind_farm_realistic_inflow/README.md | 25 ----------- .../README.md | 40 ----------------- examples/03_wind_and_solar/README.md | 24 ---------- examples/04_wind_and_storage/README.md | 25 ----------- .../05_wind_and_storage_with_lmp/README.md | 43 ------------------ examples/06_wind_and_hydrogen/README.md | 25 ----------- 18 files changed, 74 insertions(+), 294 deletions(-) rename docs/examples/{02_wind_farm_realistic_inflow.md => 02a_wind_farm_realistic_inflow.md} (72%) rename examples/02c_wind_farm_realistic_inflow_direct/README.md => docs/examples/02c_wind_farm_realistic_inflow_direct.md (84%) delete mode 100644 examples/00_wind_farm_only/README.md delete mode 100644 examples/01_wind_farm_dof1_model/README.md delete mode 100644 examples/02a_wind_farm_realistic_inflow/README.md delete mode 100644 examples/02b_wind_farm_realistic_inflow_precom_floris/README.md delete mode 100644 examples/03_wind_and_solar/README.md delete mode 100644 examples/04_wind_and_storage/README.md delete mode 100644 examples/05_wind_and_storage_with_lmp/README.md delete mode 100644 examples/06_wind_and_hydrogen/README.md diff --git a/docs/_toc.yml b/docs/_toc.yml index 993017ea..f0477e30 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -36,8 +36,9 @@ parts: - file: examples_overview - file: examples/00_wind_farm_only - file: examples/01_wind_farm_dof1_model - - file: examples/02_wind_farm_realistic_inflow + - file: examples/02a_wind_farm_realistic_inflow - file: examples/02b_wind_farm_realistic_inflow_precom_floris + - file: examples/02c_wind_farm_realistic_inflow_direct - file: examples/03_wind_and_solar - file: examples/04_wind_and_storage - file: examples/05_wind_and_storage_with_lmp diff --git a/docs/examples/00_wind_farm_only.md b/docs/examples/00_wind_farm_only.md index c78df4a0..abfc3bc6 100644 --- a/docs/examples/00_wind_farm_only.md +++ b/docs/examples/00_wind_farm_only.md @@ -18,7 +18,7 @@ python hercules_runscript.py ## Outputs -To plot the outputs run the following command in the terminal: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py diff --git a/docs/examples/01_wind_farm_dof1_model.md b/docs/examples/01_wind_farm_dof1_model.md index 97264833..36fd5370 100644 --- a/docs/examples/01_wind_farm_dof1_model.md +++ b/docs/examples/01_wind_farm_dof1_model.md @@ -2,11 +2,11 @@ ## Description -This example runs the 1-DOF long-duration wind simulation. +This example demonstrates a simple wind farm simulation using generated wind data, using a higher fidelity turbine model. The simulation uses a small wind farm configuration with basic turbine control. -## Pre setup +## Setup -Make sure to first generate the wind input file using generate_wind_history.ipynb +No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. ## Running @@ -15,9 +15,10 @@ To run the example, execute the following command in the terminal: ```bash python hercules_runscript.py ``` + ## Outputs -To plot the outputs run the following command in the terminal: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py diff --git a/docs/examples/02_wind_farm_realistic_inflow.md b/docs/examples/02a_wind_farm_realistic_inflow.md similarity index 72% rename from docs/examples/02_wind_farm_realistic_inflow.md rename to docs/examples/02a_wind_farm_realistic_inflow.md index ad8bff56..5ef24dc7 100644 --- a/docs/examples/02_wind_farm_realistic_inflow.md +++ b/docs/examples/02a_wind_farm_realistic_inflow.md @@ -1,14 +1,13 @@ -# Example 02: Wind Farm Realistic Inflow +# Example 02a: Wind Farm Realistic Inflow ## Description -In this case uses a large set of synthetic wind data. +This example uses a large set of synthetic wind data. ## Setup No manual setup is required. The example automatically generates the necessary input files (large-scale wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - ## Running To run the example, execute the following command in the terminal: @@ -16,9 +15,10 @@ To run the example, execute the following command in the terminal: ```bash python hercules_runscript.py ``` + ## Outputs -To plot the outputs run the following command in the terminal: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py diff --git a/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md index 13b17567..086affb7 100644 --- a/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md +++ b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md @@ -2,13 +2,12 @@ ## Description -This example is identical to `02_wind_farm_realistic_inflow` with the exception that the `Wind_MesoToPowerPrecomFloris` -class is used to speed up the simulation. This example automatically generates the necessary input files in the centralized `examples/inputs/` folder when first run. +This example is identical to `02a_wind_farm_realistic_inflow` with the exception that the `precomputed` wake method is used to speed up the simulation. The configuration sets `wake_method: precomputed` in the `wind_farm` component. This example automatically generates the necessary input files in the centralized `examples/inputs/` folder when first run. -Note the caveats to using this class from the docs: +Note the caveats to using this method from the docs: -> In contrast to the Wind_MesoToPower class, this class pre-computes the FLORIS wake +> In contrast to `wake_method: dynamic`, this method pre-computes the FLORIS wake deficits for all possible wind speeds and power setpoints. This is done by running for all wind speeds and wind directions (but not over all power setpoints). This is valid for cases where the wind farm is operating: @@ -19,12 +18,8 @@ Note the caveats to using this class from the docs: It is in practice conservative with respect to the wake deficits, but it is more efficient than running FLORIS for each condition. In cases where turbines are: - partially derated below the curtailment level - - not uniformly curtailed or some turbines are off - - This is not an appropriate model and the more general Wind_MesoToPower class should be used. - - - + - not uniformly curtailed or some turbines are off + this is not an appropriate model and the more general `wake_method: dynamic` should be used. ## Running @@ -33,10 +28,11 @@ To run the example, execute the following command in the terminal: ```bash python hercules_runscript.py ``` + ## Outputs -To plot the outputs run the following command in the terminal: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py -``` \ No newline at end of file +``` diff --git a/examples/02c_wind_farm_realistic_inflow_direct/README.md b/docs/examples/02c_wind_farm_realistic_inflow_direct.md similarity index 84% rename from examples/02c_wind_farm_realistic_inflow_direct/README.md rename to docs/examples/02c_wind_farm_realistic_inflow_direct.md index fda307b8..13229660 100644 --- a/examples/02c_wind_farm_realistic_inflow_direct/README.md +++ b/docs/examples/02c_wind_farm_realistic_inflow_direct.md @@ -4,7 +4,7 @@ This example demonstrates the `"no_added_wakes"` wake method, which assumes that wake effects are already included in the input wind data and performs no additional wake modeling. -In this example, the `WindFarm` component type uses `wake_method="no_added_wakes"`, which means: +In this example, the `WindFarm` component uses `wake_method: no_added_wakes`, which means: - No FLORIS calculations are performed during the simulation (only at initialization to read turbine properties) - `wind_speeds_withwakes` equals `wind_speeds_background` at all times - Wake deficits are always zero @@ -22,10 +22,8 @@ python hercules_runscript.py ## Outputs -To plot the outputs run the following command in the terminal: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py ``` - - diff --git a/docs/examples/03_wind_and_solar.md b/docs/examples/03_wind_and_solar.md index 8fdddb3c..2132b24c 100644 --- a/docs/examples/03_wind_and_solar.md +++ b/docs/examples/03_wind_and_solar.md @@ -2,7 +2,7 @@ ## Description -In this setup, wind and solar are combined in a hybrid plant. For demonstration, the plant has a fixed interconnect limit of 3000 kW, which is much below the combined capacity of the wind and solar farms. A simple controller limits the solar power to keep the total power below the interconnect limit. +In this setup, wind and solar are combined in a hybrid plant. A simple controller can be used to limit the solar power to keep the total power below the interconnect limit. ## Setup @@ -15,9 +15,10 @@ To run the example, execute the following command in the terminal: ```bash python hercules_runscript.py ``` + ## Outputs -To plot the outputs run the following command in the terminal: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py diff --git a/docs/examples/04_wind_and_storage.md b/docs/examples/04_wind_and_storage.md index 5922a45f..0e99cbab 100644 --- a/docs/examples/04_wind_and_storage.md +++ b/docs/examples/04_wind_and_storage.md @@ -2,13 +2,12 @@ ## Description -Example of a wind and storage hybrid plant where the storage is constrained to charge only using power produced by the wind farm. +Example of a wind and storage hybrid plant where the storage is constrained to charge only using power produced by the wind farm. ## Setup No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - ## Running To run the example, execute the following command in the terminal: @@ -16,9 +15,10 @@ To run the example, execute the following command in the terminal: ```bash python hercules_runscript.py ``` + ## Outputs -To plot the outputs run the following command in the terminal: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py diff --git a/docs/examples/05_wind_and_storage_with_lmp.md b/docs/examples/05_wind_and_storage_with_lmp.md index bf82ccbf..fd91cef7 100644 --- a/docs/examples/05_wind_and_storage_with_lmp.md +++ b/docs/examples/05_wind_and_storage_with_lmp.md @@ -1,5 +1,43 @@ -# Example 05: Wind and Storage with LMP-Based Control +# Example 05: Wind and storage with LMP-based control -## Overview +## Description -This example demonstrates a wind farm with battery storage using a controller that responds to Locational Marginal Pricing (LMP) signals. It also showcases the **selective external data logging** feature, where external data can be accessed by the controller but selectively logged to the output file. +Example of a wind and storage hybrid plant with a controller that responds to Locational Marginal Pricing (LMP) signals. The controller: +- Charges the battery when real-time LMP is below $15/MWh (low prices) +- Discharges the battery when real-time LMP is above $35/MWh (high prices) +- Keeps the battery idle for intermediate prices + +This example also demonstrates the new **selective external data logging** feature. Both `lmp_rt` and `lmp_da` are available to the controller via `h_dict["external_signals"]`, but only `lmp_rt` is logged to the HDF5 output file as specified in `log_channels`. + +## Setup + +No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, turbine model, and LMP data) when first run. + +## Running + +To run the example, execute the following command in the terminal: + +```bash +python hercules_runscript.py +``` + +The simulation runs for 4 hours with the following characteristics: +- Real-time LMP ramps from $0 to $50/MWh over 4 hours +- Day-ahead LMP remains constant at $10/MWh +- Only real-time LMP is logged to output (selective logging) + +## Outputs + +To plot the outputs, run the following command in the terminal: + +```bash +python plot_outputs.py +``` + +The plot shows: +1. Wind and battery power with interconnect limits +2. Battery state of charge (SOC) +3. Battery power vs setpoint +4. LMP prices and control thresholds + +Note that `lmp_rt` appears in the HDF5 output file, but `lmp_da` does not (as specified in `log_channels`), even though both were available to the controller. diff --git a/docs/examples/06_wind_and_hydrogen.md b/docs/examples/06_wind_and_hydrogen.md index 174b324b..60f95e11 100644 --- a/docs/examples/06_wind_and_hydrogen.md +++ b/docs/examples/06_wind_and_hydrogen.md @@ -1,49 +1,25 @@ -# Example 06: Wind and Hydrogen +# Example 06: Wind and hydrogen hybrid plant ## Description -This example demonstrates a wind and hydrogen hybrid plant where power that the wind farm produces goes directly to hydrogen electrolysis. This configuration is useful for understanding how renewable energy can be directly converted to hydrogen for energy storage or industrial applications. - -## Key Features - -- Wind farm power generation -- Electrolyzer plant for hydrogen production -- Direct power flow from wind to electrolyzer -- Hydrogen production tracking +Example of a wind and hydrogen hybrid plant where power that the wind farm produces goes directly to hydrogen electrolysis. ## Setup No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. -## Running the Example +## Running To run the example, execute the following command in the terminal: ```bash -cd examples/06_wind_and_hydrogen/ python hercules_runscript.py ``` -## Visualizing Outputs +## Outputs -To plot the outputs, run the following command: +To plot the outputs, run the following command in the terminal: ```bash python plot_outputs.py ``` - -## Expected Results - -The simulation will produce outputs showing: -- Wind farm power generation over time -- Hydrogen production rates -- Electrolyzer stack status -- Power consumption by the electrolyzer - -## Configuration - -The example uses: -- Wind farm with FLORIS wake modeling -- Electrolyzer plant with multiple stacks -- Hydrogen reference signal for electrolyzer control (from `inputs/hydrogen_ref_signal.csv`) - diff --git a/examples/00_wind_farm_only/README.md b/examples/00_wind_farm_only/README.md deleted file mode 100644 index c78df4a0..00000000 --- a/examples/00_wind_farm_only/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Example 00: Wind only - -## Description - -This example demonstrates a simple wind farm simulation using generated wind data. The simulation uses a small wind farm configuration with basic turbine control. - -## Setup - -No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` - -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` \ No newline at end of file diff --git a/examples/01_wind_farm_dof1_model/README.md b/examples/01_wind_farm_dof1_model/README.md deleted file mode 100644 index f2a3e55f..00000000 --- a/examples/01_wind_farm_dof1_model/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Example 01: Wind Only: 1-DOF model - -## Description - -This example demonstrates a simple wind farm simulation using generated wind data, using a higher fidelity turbine model. The simulation uses a small wind farm configuration with basic turbine control. - -## Setup - -No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` diff --git a/examples/02a_wind_farm_realistic_inflow/README.md b/examples/02a_wind_farm_realistic_inflow/README.md deleted file mode 100644 index ad8bff56..00000000 --- a/examples/02a_wind_farm_realistic_inflow/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Example 02: Wind Farm Realistic Inflow - -## Description - -In this case uses a large set of synthetic wind data. - -## Setup - -No manual setup is required. The example automatically generates the necessary input files (large-scale wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` \ No newline at end of file diff --git a/examples/02b_wind_farm_realistic_inflow_precom_floris/README.md b/examples/02b_wind_farm_realistic_inflow_precom_floris/README.md deleted file mode 100644 index 20531969..00000000 --- a/examples/02b_wind_farm_realistic_inflow_precom_floris/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Example 02b: Wind Farm Realistic Inflow (Precomputed FLORIS) - -## Description - -This example is identical to `02_wind_farm_realistic_inflow` with the exception that the `precomputed` wake method of the `WindFarm` class is used to speed up the simulation. This example automatically generates the necessary input files in the centralized `examples/inputs/` folder when first run. - -Note the caveats to using this class from the docs: - - -> In contrast to `wake_method="dynamic"`, this class pre-computes the FLORIS wake - deficits for all possible wind speeds and power setpoints. This is done by running for - all wind speeds and wind directions (but not over all power setpoints). This is valid - for cases where the wind farm is operating: - - all turbines operating normally - - all turbines off - - following a wind-farm wide derating level - - It is in practice conservative with respect to the wake deficits, but it is more efficient - than running FLORIS for each condition. In cases where turbines are: - - partially derated below the curtailment level - - not uniformly curtailed or some turbines are off - this is not an appropriate model and the more general `wake_method="dynamic"` version should be used. - - - - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` \ No newline at end of file diff --git a/examples/03_wind_and_solar/README.md b/examples/03_wind_and_solar/README.md deleted file mode 100644 index 8fdddb3c..00000000 --- a/examples/03_wind_and_solar/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Example 03: Wind and solar hybrid plant - -## Description - -In this setup, wind and solar are combined in a hybrid plant. For demonstration, the plant has a fixed interconnect limit of 3000 kW, which is much below the combined capacity of the wind and solar farms. A simple controller limits the solar power to keep the total power below the interconnect limit. - -## Setup - -No manual setup is required. The example automatically generates the necessary input files (wind data, solar data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` \ No newline at end of file diff --git a/examples/04_wind_and_storage/README.md b/examples/04_wind_and_storage/README.md deleted file mode 100644 index 5922a45f..00000000 --- a/examples/04_wind_and_storage/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Example 04: Wind and storage hybrid plant - -## Description - -Example of a wind and storage hybrid plant where the storage is constrained to charge only using power produced by the wind farm. - -## Setup - -No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` \ No newline at end of file diff --git a/examples/05_wind_and_storage_with_lmp/README.md b/examples/05_wind_and_storage_with_lmp/README.md deleted file mode 100644 index 2bf9fe85..00000000 --- a/examples/05_wind_and_storage_with_lmp/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Example 05: Wind and storage with LMP-based control - -## Description - -Example of a wind and storage hybrid plant with a controller that responds to Locational Marginal Pricing (LMP) signals. The controller: -- Charges the battery when real-time LMP is below $15/MWh (low prices) -- Discharges the battery when real-time LMP is above $35/MWh (high prices) -- Keeps the battery idle for intermediate prices - -This example also demonstrates the new **selective external data logging** feature. Both `lmp_rt` and `lmp_da` are available to the controller via `h_dict["external_signals"]`, but only `lmp_rt` is logged to the HDF5 output file as specified in `log_channels`. - -## Setup - -No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, turbine model, and LMP data) when first run. - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` - -The simulation runs for 4 hours with the following characteristics: -- Real-time LMP ramps from $0 to $50/MWh over 4 hours -- Day-ahead LMP remains constant at $10/MWh -- Only real-time LMP is logged to output (selective logging) - -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` - -The plot shows: -1. Wind and battery power with interconnect limits -2. Battery state of charge (SOC) -3. Battery power vs setpoint -4. LMP prices and control thresholds - -Note that `lmp_rt` appears in the HDF5 output file, but `lmp_da` does not (as specified in `log_channels`), even though both were available to the controller. diff --git a/examples/06_wind_and_hydrogen/README.md b/examples/06_wind_and_hydrogen/README.md deleted file mode 100644 index 7aca39b7..00000000 --- a/examples/06_wind_and_hydrogen/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Example 06: Wind and hydrogen hybrid plant - -## Description - -Example of a wind and hydrogen hybrid plant where power that the wind farm produces goes directly to hydrogen electrolysis - -## Setup - -No manual setup is required. The example automatically generates the necessary input files (wind data, FLORIS configuration, and turbine model) in the centralized `examples/inputs/` folder when first run. - - -## Running - -To run the example, execute the following command in the terminal: - -```bash -python hercules_runscript.py -``` -## Outputs - -To plot the outputs run the following command in the terminal: - -```bash -python plot_outputs.py -``` \ No newline at end of file From 3c1518cc10e25b6df3003b32f763240aac945bdd Mon Sep 17 00:00:00 2001 From: paulf81 Date: Mon, 2 Feb 2026 11:45:29 -0700 Subject: [PATCH 4/6] add pointer to online documentation --- examples/readme.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 examples/readme.txt diff --git a/examples/readme.txt b/examples/readme.txt new file mode 100644 index 00000000..3bc2aca8 --- /dev/null +++ b/examples/readme.txt @@ -0,0 +1,3 @@ +See https://natlabrockies.github.io/hercules/examples_overview.html for documentation describing +the Hercules examples. + From 287e3b817e091dd45429e5769b2deae059d02b76 Mon Sep 17 00:00:00 2001 From: Genevieve Starke Date: Tue, 3 Feb 2026 19:36:39 -0500 Subject: [PATCH 5/6] Small updates to example readmes --- .../02b_wind_farm_realistic_inflow_precom_floris.md | 6 +++--- docs/examples/03_wind_and_solar.md | 2 +- docs/examples/06_wind_and_hydrogen.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md index 086affb7..bd5c2286 100644 --- a/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md +++ b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md @@ -10,13 +10,13 @@ Note the caveats to using this method from the docs: > In contrast to `wake_method: dynamic`, this method pre-computes the FLORIS wake deficits for all possible wind speeds and power setpoints. This is done by running for all wind speeds and wind directions (but not over all power setpoints). This is valid - for cases where the wind farm is operating: - - all turbines operating normally + for cases where the wind farm is operating in the following ways: + - all turbines operating normally (maximum power) - all turbines off - following a wind-farm wide derating level It is in practice conservative with respect to the wake deficits, but it is more efficient - than running FLORIS for each condition. In cases where turbines are: + than running FLORIS for each condition at each time step. In cases where turbines are: - partially derated below the curtailment level - not uniformly curtailed or some turbines are off this is not an appropriate model and the more general `wake_method: dynamic` should be used. diff --git a/docs/examples/03_wind_and_solar.md b/docs/examples/03_wind_and_solar.md index 2132b24c..3742d91d 100644 --- a/docs/examples/03_wind_and_solar.md +++ b/docs/examples/03_wind_and_solar.md @@ -2,7 +2,7 @@ ## Description -In this setup, wind and solar are combined in a hybrid plant. A simple controller can be used to limit the solar power to keep the total power below the interconnect limit. +In this setup, wind and solar are simulated together in a hybrid plant. A simple controller can be used to curtail the solar power to keep the total power below the interconnect limit. ## Setup diff --git a/docs/examples/06_wind_and_hydrogen.md b/docs/examples/06_wind_and_hydrogen.md index 60f95e11..ed962fe4 100644 --- a/docs/examples/06_wind_and_hydrogen.md +++ b/docs/examples/06_wind_and_hydrogen.md @@ -2,7 +2,7 @@ ## Description -Example of a wind and hydrogen hybrid plant where power that the wind farm produces goes directly to hydrogen electrolysis. +Example of a wind and hydrogen hybrid plant where power that the wind farm produces goes directly to hydrogen electrolysis. The hydrogen output is then controlled by controlling the wind farm power to follow a hydrogen production reference signal. ## Setup From abfa1e01795aae4bdfd9f0d50c6cc4239be8769e Mon Sep 17 00:00:00 2001 From: paulf81 Date: Wed, 4 Feb 2026 10:06:00 -0700 Subject: [PATCH 6/6] clarify doc --- docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md index bd5c2286..3c42c271 100644 --- a/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md +++ b/docs/examples/02b_wind_farm_realistic_inflow_precom_floris.md @@ -18,7 +18,7 @@ Note the caveats to using this method from the docs: It is in practice conservative with respect to the wake deficits, but it is more efficient than running FLORIS for each condition at each time step. In cases where turbines are: - partially derated below the curtailment level - - not uniformly curtailed or some turbines are off + - some, but not all, turbines are off this is not an appropriate model and the more general `wake_method: dynamic` should be used. ## Running