Skip to content

Commit

Permalink
Validate and test wind direction and wind speed (NREL#793)
Browse files Browse the repository at this point in the history
* Adding to the wind_direction validator a test that it is 1D
* Add a wind_speed validator to test that it is 1D and the same length as wind_direction
* Adds test to confirm that making these errors in reinitialize raises value errors.
* Fixing regression test that didn't conform to this standard
  • Loading branch information
paulf81 authored Feb 7, 2024
1 parent cd55d8b commit f149309
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 7 deletions.
28 changes: 28 additions & 0 deletions floris/simulation/flow_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ def turbulence_intensities_validator(
self, instance: attrs.Attribute, value: NDArrayFloat
) -> None:

# Check that the array is 1-dimensional
if value.ndim != 1:
raise ValueError(
"wind_directions must have 1-dimension"
)

# Check the turbulence intensity is either length 1 or n_findex
if len(value) != 1 and len(value) != self.n_findex:
raise ValueError("turbulence_intensities should either be length 1 or n_findex")
Expand All @@ -79,9 +85,31 @@ def turbulence_intensities_validator(

@wind_directions.validator
def wind_directions_validator(self, instance: attrs.Attribute, value: NDArrayFloat) -> None:
# Check that the array is 1-dimensional
if self.wind_directions.ndim != 1:
raise ValueError(
"wind_directions must have 1-dimension"
)

"""Using the validator method to keep the `n_findex` attribute up to date."""
self.n_findex = value.size

@wind_speeds.validator
def wind_speeds_validator(self, instance: attrs.Attribute, value: NDArrayFloat) -> None:

# Check that the array is 1-dimensional
if self.wind_speeds.ndim != 1:
raise ValueError(
"wind_speeds must have 1-dimension"
)

"""Confirm wind speeds and wind directions have the same lenght"""
if len(self.wind_directions) != len(self.wind_speeds):
raise ValueError(
f"wind_directions (length = {len(self.wind_directions)}) and "
f"wind_speeds (length = {len(self.wind_speeds)}) must have the same length"
)

@heterogenous_inflow_config.validator
def heterogenous_config_validator(self, instance: attrs.Attribute, value: dict | None) -> None:
"""Using the validator method to check that the heterogenous_inflow_config dictionary has
Expand Down
1 change: 1 addition & 0 deletions tests/floris_interface_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def test_read_yaml():
assert isinstance(fi, FlorisInterface)



def test_calculate_wake():
"""
In FLORIS v3.2, running calculate_wake twice incorrectly set the yaw angles when the first time
Expand Down
58 changes: 57 additions & 1 deletion tests/flow_field_unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

# See https://floris.readthedocs.io for documentation


import numpy as np
import pytest

from floris.simulation import FlowField, TurbineGrid
from tests.conftest import N_FINDEX, N_TURBINES
Expand Down Expand Up @@ -59,6 +59,62 @@ def test_asdict(flow_field_fixture: FlowField, turbine_grid_fixture: TurbineGrid

assert dict1 == dict2

def test_len_ws_equals_len_wd(flow_field_fixture: FlowField, turbine_grid_fixture: TurbineGrid):

flow_field_fixture.initialize_velocity_field(turbine_grid_fixture)
dict1 = flow_field_fixture.as_dict()

# Test that having the 3 equal in lenght raises no error
dict1['wind_directions'] = np.array([180, 180])
dict1['wind_speeds'] = np.array([5., 6.])
dict1['turbulence_intensities'] = np.array([175., 175.])

FlowField.from_dict(dict1)

# Set the wind speeds as a different length of wind directions and turbulence_intensities
# And confirm error raised
dict1['wind_directions'] = np.array([180, 180])
dict1['wind_speeds'] = np.array([5., 6., 7.])
dict1['turbulence_intensities'] = np.array([175., 175.])

with pytest.raises(ValueError):
FlowField.from_dict(dict1)

# Set the wind directions as a different length of wind speeds and turbulence_intensities
dict1['wind_directions'] = np.array([180, 180, 180.])
# And confirm error raised
dict1['wind_speeds'] = np.array([5., 6.])
dict1['turbulence_intensities'] = np.array([175., 175.])

with pytest.raises(ValueError):
FlowField.from_dict(dict1)

def test_dim_ws_wd_ti(flow_field_fixture: FlowField, turbine_grid_fixture: TurbineGrid):

flow_field_fixture.initialize_velocity_field(turbine_grid_fixture)
dict1 = flow_field_fixture.as_dict()

# Test that having an extra dimension in wind_directions raises an error
with pytest.raises(ValueError):
dict1['wind_directions'] = np.array([[180, 180]])
dict1['wind_speeds'] = np.array([5., 6.])
dict1['turbulence_intensities'] = np.array([175., 175.])
FlowField.from_dict(dict1)

# Test that having an extra dimension in wind_speeds raises an error
with pytest.raises(ValueError):
dict1['wind_directions'] = np.array([180, 180])
dict1['wind_speeds'] = np.array([[5., 6.]])
dict1['turbulence_intensities'] = np.array([175., 175.])
FlowField.from_dict(dict1)

# Test that having an extra dimension in turbulence_intensities raises an error
with pytest.raises(ValueError):
dict1['wind_directions'] = np.array([180, 180])
dict1['wind_speeds'] = np.array([5., 6.])
dict1['turbulence_intensities'] = np.array([[175., 175.]])
FlowField.from_dict(dict1)


def test_turbulence_intensities_to_n_findex(flow_field_fixture, turbine_grid_fixture):
# Assert tubulence intensity has same length as n_findex
Expand Down
2 changes: 1 addition & 1 deletion tests/reg_tests/cumulative_curl_regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def test_regression_rotation(sample_inputs_fixture):
5 * TURBINE_DIAMETER
]
sample_inputs_fixture.floris["flow_field"]["wind_directions"] = [270.0, 360.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0, 8.0]

floris = Floris.from_dict(sample_inputs_fixture.floris)
floris.initialize_domain()
Expand Down
2 changes: 1 addition & 1 deletion tests/reg_tests/empirical_gauss_regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ def test_regression_rotation(sample_inputs_fixture):
5 * TURBINE_DIAMETER
]
sample_inputs_fixture.floris["flow_field"]["wind_directions"] = [270.0, 360.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0, 8.0]

floris = Floris.from_dict(sample_inputs_fixture.floris)
floris.initialize_domain()
Expand Down
2 changes: 1 addition & 1 deletion tests/reg_tests/gauss_regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def test_regression_rotation(sample_inputs_fixture):
5 * TURBINE_DIAMETER
]
sample_inputs_fixture.floris["flow_field"]["wind_directions"] = [270.0, 360.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0, 8.0]

floris = Floris.from_dict(sample_inputs_fixture.floris)
floris.initialize_domain()
Expand Down
2 changes: 1 addition & 1 deletion tests/reg_tests/jensen_jimenez_regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def test_regression_rotation(sample_inputs_fixture):
5 * TURBINE_DIAMETER
]
sample_inputs_fixture.floris["flow_field"]["wind_directions"] = [270.0, 360.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0, 8.0]

floris = Floris.from_dict(sample_inputs_fixture.floris)
floris.initialize_domain()
Expand Down
2 changes: 1 addition & 1 deletion tests/reg_tests/none_regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def test_regression_rotation(sample_inputs_fixture):
5 * TURBINE_DIAMETER
]
sample_inputs_fixture.floris["flow_field"]["wind_directions"] = [270.0, 360.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0, 8.0]

floris = Floris.from_dict(sample_inputs_fixture.floris)
floris.initialize_domain()
Expand Down
2 changes: 1 addition & 1 deletion tests/reg_tests/turbopark_regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def test_regression_rotation(sample_inputs_fixture):
5 * TURBINE_DIAMETER
]
sample_inputs_fixture.floris["flow_field"]["wind_directions"] = [270.0, 360.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0]
sample_inputs_fixture.floris["flow_field"]["wind_speeds"] = [8.0, 8.0]

floris = Floris.from_dict(sample_inputs_fixture.floris)
floris.initialize_domain()
Expand Down

0 comments on commit f149309

Please sign in to comment.