From 2b957df8576e33b4b5049a53e83c49a5913e73d6 Mon Sep 17 00:00:00 2001 From: misi9170 Date: Thu, 4 Apr 2024 15:45:16 -0600 Subject: [PATCH 1/3] Handling for order of set_operation model and setting layout. --- floris/core/farm.py | 3 ++- floris/floris_model.py | 18 +++++++++++++---- tests/floris_model_integration_test.py | 27 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/floris/core/farm.py b/floris/core/farm.py index 5c009c253..c92078be6 100644 --- a/floris/core/farm.py +++ b/floris/core/farm.py @@ -209,7 +209,8 @@ def check_turbine_type(self, attribute: attrs.Attribute, value: Any) -> None: if len(value) != 1 and len(value) != self.n_turbines: raise ValueError( "turbine_type must have the same number of entries as layout_x/layout_y or have " - "a single turbine_type value." + "a single turbine_type value. This error can arise if you set the turbine_type or " + "alter the operation model before setting the layout." ) @turbine_library_path.validator diff --git a/floris/floris_model.py b/floris/floris_model.py index 157c99ac2..a74b1bb6a 100644 --- a/floris/floris_model.py +++ b/floris/floris_model.py @@ -1309,13 +1309,23 @@ def set_operation_model(self, operation_model: str | List[str]): operation_model (str): The operation model to set. """ if isinstance(operation_model, str): - operation_model = [operation_model]*self.core.farm.n_turbines - elif len(operation_model) != self.core.farm.n_turbines: + if len(self.core.farm.turbine_type) == 1: + # Set a single one here, then, and return + turbine_type = self.core.farm.turbine_definitions[0] + turbine_type["operation_model"] = operation_model + self.set(turbine_type=[turbine_type]) + return + else: + operation_model = [operation_model]*self.core.farm.n_turbines + + if len(operation_model) != self.core.farm.n_turbines: raise ValueError( - "The length of the operation_model list must be equal to the number of turbines." - ) + "The length of the operation_model list must be " + "equal to the number of turbines." + ) turbine_type_list = self.core.farm.turbine_definitions + for tindex in range(self.core.farm.n_turbines): turbine_type_list[tindex]["turbine_type"] = ( turbine_type_list[tindex]["turbine_type"]+"_"+operation_model[tindex] diff --git a/tests/floris_model_integration_test.py b/tests/floris_model_integration_test.py index 7d4fcbc12..f5d0a77b8 100644 --- a/tests/floris_model_integration_test.py +++ b/tests/floris_model_integration_test.py @@ -591,3 +591,30 @@ def test_set_operation_model(): fmodel.set(layout_x=[0, 0], layout_y=[0, 1000]) fmodel.set_operation_model(["simple-derating", "cosine-loss"]) assert fmodel.get_operation_model() == ["simple-derating", "cosine-loss"] + + # Check that setting a single turbine type, and then altering the operation model works + fmodel.set(layout_x=[0, 0], layout_y=[0, 1000]) + fmodel.set(turbine_type=["nrel_5MW"]) + fmodel.set_operation_model("simple-derating") + assert fmodel.get_operation_model() == "simple-derating" + + # Check that setting over mutliple turbine types works + fmodel.set(turbine_type=["nrel_5MW", "iea_15MW"]) + fmodel.set_operation_model("simple-derating") + assert fmodel.get_operation_model() == "simple-derating" + fmodel.set_operation_model(["simple-derating", "cosine-loss"]) + assert fmodel.get_operation_model() == ["simple-derating", "cosine-loss"] + + # Check setting over single turbine type; then updating layout works + fmodel.set(turbine_type=["nrel_5MW"]) + fmodel.set_operation_model("simple-derating") + fmodel.set(layout_x=[0, 0, 0], layout_y=[0, 1000, 2000]) + assert fmodel.get_operation_model() == "simple-derating" + + # Check that setting for multiple turbine types and then updating layout breaks + fmodel.set(layout_x=[0, 0], layout_y=[0, 1000]) + fmodel.set(turbine_type=["nrel_5MW"]) + fmodel.set_operation_model(["simple-derating", "cosine-loss"]) + assert fmodel.get_operation_model() == ["simple-derating", "cosine-loss"] + with pytest.raises(ValueError): + fmodel.set(layout_x=[0, 0, 0], layout_y=[0, 1000, 2000]) From d73c280d8ae1f9a3addc1218442c6aebd45ae59a Mon Sep 17 00:00:00 2001 From: misi9170 Date: Thu, 4 Apr 2024 15:46:37 -0600 Subject: [PATCH 2/3] ruff. --- floris/floris_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/floris/floris_model.py b/floris/floris_model.py index a74b1bb6a..9ad56b41e 100644 --- a/floris/floris_model.py +++ b/floris/floris_model.py @@ -1317,7 +1317,7 @@ def set_operation_model(self, operation_model: str | List[str]): return else: operation_model = [operation_model]*self.core.farm.n_turbines - + if len(operation_model) != self.core.farm.n_turbines: raise ValueError( "The length of the operation_model list must be " From 2132d9948a8687211ab659d58e981b0f29aba49f Mon Sep 17 00:00:00 2001 From: misi9170 Date: Thu, 4 Apr 2024 15:54:32 -0600 Subject: [PATCH 3/3] One more test added. --- tests/floris_model_integration_test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/floris_model_integration_test.py b/tests/floris_model_integration_test.py index f5d0a77b8..9947d6ef8 100644 --- a/tests/floris_model_integration_test.py +++ b/tests/floris_model_integration_test.py @@ -618,3 +618,11 @@ def test_set_operation_model(): assert fmodel.get_operation_model() == ["simple-derating", "cosine-loss"] with pytest.raises(ValueError): fmodel.set(layout_x=[0, 0, 0], layout_y=[0, 1000, 2000]) + + # Check one more variation + fmodel.set(layout_x=[0, 0], layout_y=[0, 1000]) + fmodel.set(turbine_type=["nrel_5MW", "iea_15MW"]) + fmodel.set_operation_model("simple-derating") + fmodel.set(layout_x=[0, 0], layout_y=[0, 1000]) + with pytest.raises(ValueError): + fmodel.set(layout_x=[0, 0, 0], layout_y=[0, 1000, 2000])