Skip to content

Commit be642aa

Browse files
authored
Merge pull request #30 from NREL/develop
Release v0.7
2 parents 2e0b4c4 + 869d354 commit be642aa

99 files changed

Lines changed: 2021 additions & 545250 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/pre-commit.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: pre-commit
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [main, develop]
7+
8+
jobs:
9+
pre-commit:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v5
13+
- name: Set up Python
14+
uses: actions/setup-python@v6
15+
with:
16+
python-version: "3.13"
17+
- name: Run pre-commit
18+
uses: pre-commit/action@v3.0.1

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# CHANGELOG
22

3+
## v0.7 - 12 January 2026
4+
5+
- Supports WOMBAT v0.13.1+ to ensure the latest bug fixes and data updates are available to all users.
6+
- Supports ORBIT v.1.2.6+ to ensure the latest bug fixes, features, data updates are available to all users.
7+
- Updates the COWER example for the 2025 reporting cycle.
8+
- Removes `library/base_2022` in favor of a `libray/base` for base assumptions and scenarios that
9+
can be updated annually as needed.
10+
- A pre-commit workflow is added to be run against PRs into the main and develop branches to ensure
11+
code quality checks are passed.
12+
313
## v0.6.2 - 1 December 2025
414

515
- Pins `jupyter-book` to "<2" to avoid v2 migration issues prior to testing.

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,20 @@ reference guide, and examples.
2424

2525
## Requirements
2626

27-
Python 3.10+, preferably 3.12
27+
Python 3.10+
2828

2929
## Environment Setup
3030

3131
Download the latest version of [Miniconda](https://docs.conda.io/en/latest/miniconda.html)
3232
for the appropriate OS. Follow the remaining [steps](https://conda.io/projects/conda/en/latest/user-guide/install/index.html#regular-installation)
3333
for the appropriate OS version.
3434

35-
Using conda, create a new virtual environment:
35+
Using conda, create a new virtual environment and replace "waves" with a different environment
36+
name, if preferred:
3637

3738
```console
38-
conda create -n <environment_name> python=3.12
39-
conda activate <environment_name>
39+
conda create -n waves python=3.14
40+
conda activate waves
4041
conda install -c anaconda pip
4142
conda config --set pip_interop_enabled true
4243

docs/user_guide.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
```
77

88
This section will provide a guided overview of all the components of the `Project` class that are
9-
relevant to users, and demonstrate inputs used for the 2022 Cost of Wind Energy Review (COWER)
9+
relevant to users, and demonstrate inputs used for the Cost of Wind Energy Review (COWER)
1010
analysis. For a complete API reference, please refer to the [API documentation](./api.md).
1111

1212
## Configuring
@@ -55,22 +55,22 @@ analysis. For a complete API reference, please refer to the [API documentation](
5555
:noindex:
5656
```
5757

58-
### COWER 2022 Configuration
58+
### COWER Configuration
5959

6060
Aligning with COWER, we have the following inputs. It should be noted that each model's
6161
configuration is a pointer to another file to keep each configuration as tidy as possible. However,
6262
each of `orbit_config`, `wombat_config`, and `floris_config` allow for a direct dictionary
6363
configuration input.
6464

65-
```{literalinclude} ../library/base_2022/project/config/base_fixed_bottom_2022.yaml
65+
```{literalinclude} ../library/base/project/config/base_osw_fixed.yaml
6666
:language: yaml
6767
:lines: 1-36
6868
:linenos:
6969
```
7070

7171
...
7272

73-
```{literalinclude} ../library/base_2022/project/config/base_fixed_bottom_2022.yaml
73+
```{literalinclude} ../library/base/project/config/base_osw_fixed.yaml
7474
:language: yaml
7575
:linenos:
7676
:lineno-start: 43
@@ -79,7 +79,7 @@ configuration input.
7979

8080
...
8181

82-
```{literalinclude} ../library/base_2022/project/config/base_fixed_bottom_2022.yaml
82+
```{literalinclude} ../library/base/project/config/base_osw_fixed.yaml
8383
:language: yaml
8484
:linenos:
8585
:lineno-start: 46
@@ -88,7 +88,7 @@ configuration input.
8888

8989
...
9090

91-
```{literalinclude} ../library/base_2022/project/config/base_fixed_bottom_2022.yaml
91+
```{literalinclude} ../library/base/project/config/base_osw_fixed.yaml
9292
:language: yaml
9393
:linenos:
9494
:lineno-start: 95
@@ -97,7 +97,7 @@ configuration input.
9797

9898
...
9999

100-
```{literalinclude} ../library/base_2022/project/config/base_fixed_bottom_2022.yaml
100+
```{literalinclude} ../library/base/project/config/base_osw_fixed.yaml
101101
:language: yaml
102102
:linenos:
103103
:lineno-start: 141
@@ -140,8 +140,8 @@ from pathlib import Path
140140
from waves import Project
141141
from waves.utilities import load_yaml
142142

143-
library_path = Path("../library/base_2022/")
144-
config = load_yaml(library_path / "project/config", "base_fixed_bottom_2022.yaml")
143+
library_path = Path("../library/base/")
144+
config = load_yaml(library_path / "project/config", "base_osw_fixed.yaml")
145145
config["library_path"] = library_path # add the library path
146146

147147
# Ensure FLORIS is not automatically connected
@@ -234,7 +234,7 @@ Visually, the following is a general flow of operations for combining each model
234234

235235
To quickly produce any of the high-level outputs to a single `DataFrame`, the below method can be
236236
used in place of individually calculating each metric and combining into a report. Additionally,
237-
users can refer to the [COWER 2022 example](example_cower_2022:results) for the reported results,
237+
users can refer to the [COWER example](example_cower:results) for the reported results,
238238
which relies on the `generate_report` method and accessing the ORBIT `ProjectManager` directly for
239239
further CapEx breakdowns.
240240

@@ -400,7 +400,7 @@ defined in the configuration file. The [provided example](./waves_example.md) is
400400
be run through the CLI. Below is an example of the additional configurations
401401

402402
```{eval-rst}
403-
.. literalinclude:: ../library/base_2022/project/config/base_fixed_bottom_2022.yaml
403+
.. literalinclude:: ../library/base/project/config/base_osw_fixed.yaml
404404
:language: yaml
405405
:linenos:
406406
:lineno-start: 146

docs/waves_example.md

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ kernelspec:
99
name: python3
1010
---
1111

12-
(example_cower_2022)=
13-
# Cost of Wind Energy Review 2022
12+
(example_cower)=
13+
# Cost of Wind Energy Review: 2025 Edition
14+
15+
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/NREL/WAVES/main?filepath=examples)
1416

1517
Be sure to install `pip install "waves[examples]"` (or `pip install ".[examples]"`) to work with
1618
this example.
1719

18-
This example will walk through the process of running a subset of the 2022 Cost of Wind Energy
19-
Review (COWER) analysis to demonstrate an analysis workflow. Please note, that this is not the exact
20-
workflow because it has been broken down to highlight some of the key features of WAVES. Similarly,
21-
this will stay up to date with WAVES's dependencies, namely ORBIT, WOMBAT, and FLORIS, so results
22-
may change slightly between this *example* relying on the configurations and the published results.
20+
This example will walk through the process of running a subset of the current year's Cost of Wind
21+
Energy Review (COWER) analysis to demonstrate an analysis workflow. Please note, that this is not
22+
the exact workflow because it has been broken down to highlight some of the key features of WAVES.
23+
Similarly, this will stay up to date with WAVES's dependencies, namely ORBIT, WOMBAT, and FLORIS,
24+
so results may change slightly between this *example* relying on the configurations and the
25+
published results.
2326

2427
````{note}
2528
To run these examples from the command line, the below command can be used, which will dipslay and
@@ -30,10 +33,10 @@ information in the command line wherever WAVES is installed.
3033
# NOTE: This is run from the top level of WAVES/
3134
3235
# Run one example
33-
waves library/base_2022 base_fixed_bottom_2022.yaml
36+
waves library/base base_osw_fixed.yaml
3437
3538
# Run both examples, but don't save the results
36-
waves library/base_2022 base_fixed_bottom_2022.yaml base_floating_2022.yaml --no-save-report
39+
waves library/base base_osw_fixed.yaml base_osw_floating.yaml --no-save-report
3740
```
3841
````
3942

@@ -63,22 +66,22 @@ the configurations. For a complete guide and definition, please see either the
6366

6467
````{warning}
6568
If your FLORIS installation is <3.6, then the FLORIS configuration files in
66-
`library/base_2022/project/config/` will have to be updated so that line 107 (same line number for
69+
`library/base/project/config/` will have to be updated so that line 107 (same line number for
6770
fixed bottom and floating) is using an absolute path like the example below.
6871
6972
```yaml
7073
# original, set to work with FLORIS >= 3.6
7174
turbine_library_path: ../../turbines
7275
7376
# updated absolute path, replace <path_to_waves> in your own files
74-
turbine_library_path: <path_to_waves>/WAVES/library/base_2022/turbines/
77+
turbine_library_path: <path_to_waves>/WAVES/library/base/turbines/
7578
```
7679
````
7780

7881
```{code-cell} ipython3
79-
library_path = Path("../library/base_2022/")
80-
config_fixed = load_yaml(library_path / "project/config", "base_fixed_bottom_2022.yaml")
81-
config_floating = load_yaml(library_path / "project/config", "base_floating_2022.yaml")
82+
library_path = Path("../library/base")
83+
config_fixed = load_yaml(library_path / "project/config", "base_osw_fixed.yaml")
84+
config_floating = load_yaml(library_path / "project/config", "base_osw_floating.yaml")
8285
8386
# This example was designed prior to the FLORIS 3.6 release, so the path to the turbine library in
8487
# FLORIS must be manually updated, but this example must work for all users, so a dynamic method
@@ -100,19 +103,19 @@ WAVES command line interface (CLI).
100103
config_fixed.update({"library_path": library_path,})
101104
config_floating.update({"library_path": library_path,})
102105
103-
start1 = perf_counter()
106+
start = perf_counter()
104107
105108
project_fixed = Project.from_dict(config_fixed)
106109
107-
end1 = perf_counter()
110+
end = perf_counter()
111+
print(f"Fixed bottom loading time: {(end-start):,.2f} seconds")
108112
109-
start2 = perf_counter()
113+
start = perf_counter()
110114
111115
project_floating = Project.from_dict(config_floating)
112116
113-
end2 = perf_counter()
114-
print(f"Fixed bottom loading time: {(end1-start1):,.2f} seconds")
115-
print(f"Floating loading time: {(end2-start2):,.2f} seconds")
117+
end = perf_counter()
118+
print(f"Floating loading time: {(end-start):,.2f} seconds")
116119
```
117120

118121
### Visualize the wind farm
@@ -137,37 +140,34 @@ of the year, for a more accurate energy output. However, we're using just the we
137140
in the O&M phase: `full_wind_rose=False`.
138141

139142
```{code-cell} ipython3
140-
start1 = perf_counter()
143+
start = perf_counter()
141144
project_fixed.run(
142-
which_floris="wind_rose", # month-based wind rose wake analysis
143145
full_wind_rose=False, # use the WOMBAT date range
144-
floris_reinitialize_kwargs={"cut_in_wind_speed": 3.0, "cut_out_wind_speed": 25.0} # standard ws range
146+
floris_kwargs={"cut_in_wind_speed": 3.0, "cut_out_wind_speed": 25.0} # standard ws range
145147
)
146148
project_fixed.wombat.env.cleanup_log_files() # Delete logging data from the WOMBAT simulations
147-
end1 = perf_counter()
149+
end = perf_counter()
150+
print(f"Fixed run time: {end - start:,.2f} seconds")
148151
149-
start2 = perf_counter()
152+
start = perf_counter()
150153
project_floating.run(
151-
which_floris="wind_rose",
152154
full_wind_rose=False,
153-
floris_reinitialize_kwargs=dict(cut_in_wind_speed=3.0, cut_out_wind_speed=25.0)
155+
floris_kwargs=dict(cut_in_wind_speed=3.0, cut_out_wind_speed=25.0)
154156
)
155157
project_floating.wombat.env.cleanup_log_files() # Delete logging data from the WOMBAT simulations
156-
end2 = perf_counter()
158+
end = perf_counter()
157159
158-
print("-" * 29) # separate our timing from the ORBIT and FLORIS run-time warnings
159-
print(f"Fixed run time: {end1 - start1:,.2f} seconds")
160-
print(f"Floating run time: {end2 - start2:,.2f} seconds")
160+
print(f"Floating run time: {end - start:,.2f} seconds")
161161
```
162162

163163
Both of these examples can also be run via the CLI, though the FLORIS `turbine_library_path`
164164
configuration will have to be manually updated in each file to ensure the examples run.
165165

166166
```console
167-
waves path/to/library/base_2022/ base_fixed_bottom_2022.yaml base_floating_bottom_2022.yaml --no-save-report
167+
waves path/to/library/base/ base_osw_fixed.yaml base_osw_floating.yaml --no-save-report
168168
```
169169

170-
(example_cower_2022:results)=
170+
(example_cower:results)=
171171
## Gather the results
172172

173173
Another of the conveniences with using WAVES to run all three models is that some of the core
@@ -213,20 +213,16 @@ metrics_configuration = {
213213
"OpEx per kW ($/kW)": {"metric": "opex", "kwargs": {"per_capacity": "kw"}},
214214
"AEP (MWh)": {
215215
"metric": "energy_production",
216-
"kwargs": {"units": "mw", "aep": True, "with_losses": True}
216+
"kwargs": {"units": "mw", "aep": True}
217217
},
218218
"AEP per kW (MWh/kW)": {
219219
"metric": "energy_production",
220-
"kwargs": {"units": "mw", "per_capacity": "kw", "aep": True, "with_losses": True}
220+
"kwargs": {"units": "mw", "per_capacity": "kw", "aep": True}
221221
},
222-
"Net Capacity Factor With Wake Losses (%)": {
222+
"Net Capacity Factor (%)": {
223223
"metric": "capacity_factor",
224224
"kwargs": {"which": "net"}
225225
},
226-
"Net Capacity Factor With All Losses (%)": {
227-
"metric": "capacity_factor",
228-
"kwargs": {"which": "net", "with_losses": True}
229-
},
230226
"Gross Capacity Factor (%)": {
231227
"metric": "capacity_factor",
232228
"kwargs": {"which": "gross"}
@@ -256,8 +252,7 @@ metrics_order = [
256252
"Annual OpEx per kW ($/kW)",
257253
"Energy Availability (%)",
258254
"Gross Capacity Factor (%)",
259-
"Net Capacity Factor With Wake Losses (%)",
260-
"Net Capacity Factor With All Losses (%)",
255+
"Net Capacity Factor (%)",
261256
"AEP (MWh)",
262257
"AEP per kW (MWh/kW)",
263258
"LCOE ($/MWh)",
@@ -319,8 +314,8 @@ df_capex
319314
Now, let's generate the report, and then add in some additional reporting variables.
320315

321316
```{code-cell} ipython3
322-
project_name_fixed = "COE 2022 - Fixed"
323-
project_name_floating = "COE 2022 - Floating"
317+
project_name_fixed = "Fixed"
318+
project_name_floating = "Floating"
324319
325320
# Generate the reports using WAVES and the above configurations
326321
# NOTE: the results are transposed to view them more easily for the example, otherwise

0 commit comments

Comments
 (0)