Skip to content

Commit

Permalink
[BUGFIX] Force yaw_angles to zero in FlorisStandin when `power_se…
Browse files Browse the repository at this point in the history
…tpoints` passed (#109)

* Switch to zero yaw misalignments when valid power setpoints are passed to avoid FLORIS error.

* Raise warning, update test.

* More complex handling to check pairwise combos of power_setpoints and yaw_angles.

* Remove unneeded local floris install.

* Add check to ruff statement

* try forcing matplotlib version

* try 2.0

* set it back

* try 3.7

* Add verbosity to output

* Add alternative os

* take out verbose tests

---------

Co-authored-by: Paul <paul.fleming@nrel.gov>
  • Loading branch information
misi9170 and paulf81 authored Jul 30, 2024
1 parent ad29cf8 commit 446ca31
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/continuous-integration-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
fail-fast: False
matrix:
python-version: ["3.9", "3.10", "3.11"]
os: [ubuntu-latest]
os: [ubuntu-latest, macos-latest]

steps:
- uses: actions/checkout@v3
Expand All @@ -24,11 +24,10 @@ jobs:
pip install -e ".[develop]"
pip install git+https://github.com/NREL/electrolyzer.git
pip install https://github.com/NREL/SEAS/blob/main/SEAS.tar.gz?raw=true
pip install git+https://github.com/NREL/floris.git@v4
# - uses: pre-commit/action@v3.0.0
- name: Run ruff
run: |
ruff .
ruff check .
# ruff format
- name: Run tests and collect coverage
run: |
Expand Down
20 changes: 20 additions & 0 deletions hercules/floris_standin.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,26 @@ def get_step(self, sim_time_s, yaw_angles=None, power_setpoints=None):

turbine_wind_directions = [amr_wind_direction] * self.num_turbines

if power_setpoints is None or yaw_angles is None:
pass # No conflict with yaw angles
elif (
(((np.array(power_setpoints) == 1e9)
| (np.array([ps is None for ps in power_setpoints])))
| ((np.array(yaw_angles) == -1000) | (np.array([ya is None for ya in yaw_angles])) |
(np.array(yaw_angles) == amr_wind_direction))
).all()
):
pass # No conflict with yaw angles
else:
# Cannot currently handle both power setpoints and nonzero yaw angles.
# If power setpoints are provided, overwrite any yaw angles.
logger.warning((
"Received combination of power_setpoints and nonzero yaw_angles for some turbines, "
+"which can not currently be handled by the FlorisStandin. Setting yaw_angles to "
+"None."
))
yaw_angles = None

if yaw_angles is None or (np.array(yaw_angles) == -1000).any():
# Note: -1000 is the "no value" flag for yaw_angles (NaNs not handled well)
yaw_misalignments = None # Floris will remember the previous yaw angles
Expand Down
12 changes: 7 additions & 5 deletions tests/floris_standin_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from pathlib import Path

import numpy as np
import pytest
from floris import FlorisModel
from hercules.amr_wind_standin import AMRWindStandin
from hercules.floris_standin import (
Expand Down Expand Up @@ -121,7 +121,7 @@ def test_FlorisStandin_get_step_yaw_angles():
[260.0, 230.0]
)

def test_FlorisStandin_get_step_power_setpoints():
def test_FlorisStandin_get_step_power_setpoints(caplog):
floris_standin = FlorisStandin(CONFIG, AMR_INPUT, smoothing_coefficient=0.0)

# Get FLORIS equivalent, match layout and turbines
Expand Down Expand Up @@ -155,10 +155,12 @@ def test_FlorisStandin_get_step_power_setpoints():
fmodel_true_tp = fmodel_true.get_turbine_powers() / 1000
assert np.allclose(fs_tp, fmodel_true_tp.flatten().tolist())

# Test with invalid combination of yaw angles and power setpoints
with pytest.raises(ValueError):
# Test warning raise with invalid combination of yaw angles and power setpoints
with caplog.at_level(logging.WARNING):
floris_standin.get_step(5.0, yaw_angles=[230.0, 240.0], power_setpoints=[1e3, 1e3])

assert caplog.text != "" # Checking not empty
caplog.clear()

# Test with valid combination of yaw angles and power setpoints
yaw_angles = [260.0, 240.0]
power_setpoints = [None, 1e3]
Expand Down

0 comments on commit 446ca31

Please sign in to comment.