internal_turbine_library: Path = field(init=False, default=default_turbine_library_path)
+ # Private attributes
+ _turbine_types: List = field(init=False, validator=iter_validator(list, str), factory=list)
+ _turbine_definition_cache: dict = field(init=False, factory=dict)
+
def __attrs_post_init__(self) -> None:
# Turbine definitions can be supplied in three ways:
# - A string selecting a turbine in the floris turbine library
@@ -703,21 +710,28 @@ Source code for floris.core.farm
# This allows to read the yaml input files once rather than every time they're given.
# In other words, if the turbine type is already in the cache, skip that iteration of
# the for-loop.
- turbine_definition_cache = {}
+
for t in self.turbine_type:
# If a turbine type is a dict, then it was either preprocessed by the yaml
# library to resolve the "!include" or it was set in a script as a dict. In either case,
# add an entry to the cache
if isinstance(t, dict):
- if t["turbine_type"] in turbine_definition_cache:
- continue
- turbine_definition_cache[t["turbine_type"]] = t
+ if t["turbine_type"] in self._turbine_definition_cache:
+ if self._turbine_definition_cache[t["turbine_type"]] == t:
+ continue # Skip t if already loaded
+ else:
+ raise ValueError(
+ "Two different turbine definitions have the same name: "\
+ f"'{t['turbine_type']}'. "\
+ "Please specify a unique 'turbine_type' for each turbine definition."
+ )
+ self._turbine_definition_cache[t["turbine_type"]] = t
# If a turbine type is a string, then it is expected in the internal or external
# turbine library
if isinstance(t, str):
- if t in turbine_definition_cache:
- continue
+ if t in self._turbine_definition_cache:
+ continue # Skip t if already loaded
# Check if the file exists in the internal and/or external library
internal_fn = (self.internal_turbine_library / t).with_suffix(".yaml")
@@ -743,7 +757,7 @@ Source code for floris.core.farm
f"The turbine type: {t} does not exist in either the internal or"
" external turbine library."
)
- turbine_definition_cache[t] = load_yaml(full_path)
+ self._turbine_definition_cache[t] = load_yaml(full_path)
# Convert any dict entries in the turbine_type list to the type string. Since the
# definition is saved above, we can make the whole list consistent now to use it
@@ -753,23 +767,23 @@ Source code for floris.core.farm
# types must be used. If we modify that directly and change its shape, recreating this
# class with a different layout but not a new self.turbine_type could cause the data
# to be out of sync.
- _turbine_types = [
+ self._turbine_types = [
copy.deepcopy(t["turbine_type"]) if isinstance(t, dict) else t
for t in self.turbine_type
]
# If 1 turbine definition is given, expand to N turbines; this covers a 1-turbine
# farm and 1 definition for multiple turbines
- if len(_turbine_types) == 1:
- _turbine_types *= self.n_turbines
+ if len(self._turbine_types) == 1:
+ self._turbine_types *= self.n_turbines
# Check that turbine definitions contain any v3 keys
- for t in _turbine_types:
- check_turbine_definition_for_v3_keys(turbine_definition_cache[t])
+ for _, v in self._turbine_definition_cache.items():
+ check_turbine_definition_for_v3_keys(v)
# Map each turbine definition to its index in this list
self.turbine_definitions = [
- copy.deepcopy(turbine_definition_cache[t]) for t in _turbine_types
+ copy.deepcopy(self._turbine_definition_cache[t]) for t in self._turbine_types
]
@@ -886,7 +900,10 @@
Source code for floris.core.farm
[docs]
def construct_turbine_map(self):
-
self.turbine_map = [Turbine.from_dict(turb) for turb in self.turbine_definitions]
+ turbine_map_unique = {
+ k: Turbine.from_dict(v) for k, v in self._turbine_definition_cache.items()
+ }
+ self.turbine_map = [turbine_map_unique[k] for k in self._turbine_types]
diff --git a/_modules/floris/core/flow_field.html b/_modules/floris/core/flow_field.html
index d415e460d..92fd225d7 100644
--- a/_modules/floris/core/flow_field.html
+++ b/_modules/floris/core/flow_field.html
@@ -240,6 +240,7 @@
floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/grid.html b/_modules/floris/core/grid.html
index e6154d964..c9f05dba5 100644
--- a/_modules/floris/core/grid.html
+++ b/_modules/floris/core/grid.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/rotor_velocity.html b/_modules/floris/core/rotor_velocity.html
index b5f8c38d2..bc6003995 100644
--- a/_modules/floris/core/rotor_velocity.html
+++ b/_modules/floris/core/rotor_velocity.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/solver.html b/_modules/floris/core/solver.html
index 9fdef4af0..83ebfe3cf 100644
--- a/_modules/floris/core/solver.html
+++ b/_modules/floris/core/solver.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/turbine/operation_models.html b/_modules/floris/core/turbine/operation_models.html
index 0cb3fac53..e6c4445ed 100644
--- a/_modules/floris/core/turbine/operation_models.html
+++ b/_modules/floris/core/turbine/operation_models.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/turbine/turbine.html b/_modules/floris/core/turbine/turbine.html
index 579e1d921..c40f2aad4 100644
--- a/_modules/floris/core/turbine/turbine.html
+++ b/_modules/floris/core/turbine/turbine.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake.html b/_modules/floris/core/wake.html
index 64a511203..7c31f3ac2 100644
--- a/_modules/floris/core/wake.html
+++ b/_modules/floris/core/wake.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake_combination/fls.html b/_modules/floris/core/wake_combination/fls.html
index cbfa6e9b9..8fc52c058 100644
--- a/_modules/floris/core/wake_combination/fls.html
+++ b/_modules/floris/core/wake_combination/fls.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake_combination/max.html b/_modules/floris/core/wake_combination/max.html
index 12db363ff..fac767dd5 100644
--- a/_modules/floris/core/wake_combination/max.html
+++ b/_modules/floris/core/wake_combination/max.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake_combination/sosfs.html b/_modules/floris/core/wake_combination/sosfs.html
index 48c657334..cf2399126 100644
--- a/_modules/floris/core/wake_combination/sosfs.html
+++ b/_modules/floris/core/wake_combination/sosfs.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake_deflection/empirical_gauss.html b/_modules/floris/core/wake_deflection/empirical_gauss.html
index a83eda18b..832111a29 100644
--- a/_modules/floris/core/wake_deflection/empirical_gauss.html
+++ b/_modules/floris/core/wake_deflection/empirical_gauss.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake_deflection/gauss.html b/_modules/floris/core/wake_deflection/gauss.html
index b70ce6879..7df8e45b6 100644
--- a/_modules/floris/core/wake_deflection/gauss.html
+++ b/_modules/floris/core/wake_deflection/gauss.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake_deflection/jimenez.html b/_modules/floris/core/wake_deflection/jimenez.html
index ac54404fe..15d6500e0 100644
--- a/_modules/floris/core/wake_deflection/jimenez.html
+++ b/_modules/floris/core/wake_deflection/jimenez.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization
Examples - Multidim
diff --git a/_modules/floris/core/wake_deflection/none.html b/_modules/floris/core/wake_deflection/none.html
index 791c764a8..965daf4e0 100644
--- a/_modules/floris/core/wake_deflection/none.html
+++ b/_modules/floris/core/wake_deflection/none.html
@@ -240,6 +240,7 @@
- floris.optimization.layout_optimization