foxes 1.3__py3-none-any.whl → 1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of foxes might be problematic. Click here for more details.
- docs/source/conf.py +3 -3
- examples/abl_states/run.py +2 -2
- examples/compare_rotors_pwakes/run.py +1 -1
- examples/compare_wakes/run.py +1 -2
- examples/dyn_wakes/run.py +29 -6
- examples/field_data_nc/run.py +1 -1
- examples/induction/run.py +3 -3
- examples/multi_height/run.py +1 -1
- examples/power_mask/run.py +2 -2
- examples/quickstart/run.py +0 -1
- examples/random_timeseries/run.py +3 -4
- examples/scan_row/run.py +3 -3
- examples/sequential/run.py +33 -10
- examples/single_state/run.py +3 -4
- examples/states_lookup_table/run.py +3 -3
- examples/streamline_wakes/run.py +29 -6
- examples/tab_file/run.py +3 -3
- examples/timelines/run.py +29 -5
- examples/timeseries/run.py +3 -3
- examples/timeseries_slurm/run.py +3 -3
- examples/wind_rose/run.py +3 -3
- examples/yawed_wake/run.py +19 -9
- foxes/__init__.py +21 -17
- foxes/algorithms/__init__.py +6 -6
- foxes/algorithms/downwind/__init__.py +2 -2
- foxes/algorithms/downwind/downwind.py +49 -17
- foxes/algorithms/downwind/models/__init__.py +6 -6
- foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -9
- foxes/algorithms/downwind/models/init_farm_data.py +58 -29
- foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
- foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +6 -6
- foxes/algorithms/iterative/__init__.py +7 -3
- foxes/algorithms/iterative/iterative.py +1 -2
- foxes/algorithms/iterative/models/__init__.py +7 -3
- foxes/algorithms/iterative/models/farm_wakes_calc.py +9 -5
- foxes/algorithms/sequential/__init__.py +3 -3
- foxes/algorithms/sequential/models/__init__.py +2 -2
- foxes/algorithms/sequential/sequential.py +3 -4
- foxes/config/__init__.py +5 -1
- foxes/constants.py +16 -0
- foxes/core/__init__.py +45 -22
- foxes/core/algorithm.py +5 -6
- foxes/core/data.py +94 -22
- foxes/core/data_calc_model.py +4 -2
- foxes/core/engine.py +42 -53
- foxes/core/farm_controller.py +2 -2
- foxes/core/farm_data_model.py +16 -13
- foxes/core/ground_model.py +4 -13
- foxes/core/model.py +24 -6
- foxes/core/partial_wakes_model.py +147 -10
- foxes/core/point_data_model.py +21 -17
- foxes/core/rotor_model.py +4 -3
- foxes/core/states.py +2 -3
- foxes/core/turbine.py +2 -1
- foxes/core/wake_deflection.py +130 -0
- foxes/core/wake_model.py +222 -9
- foxes/core/wake_superposition.py +122 -4
- foxes/core/wind_farm.py +6 -6
- foxes/data/__init__.py +7 -2
- foxes/data/states/point_cloud_100.nc +0 -0
- foxes/data/states/weibull_cloud_4.nc +0 -0
- foxes/data/states/weibull_grid.nc +0 -0
- foxes/data/states/weibull_sectors_12.csv +13 -0
- foxes/data/states/weibull_sectors_12.nc +0 -0
- foxes/engines/__init__.py +14 -15
- foxes/engines/dask.py +42 -20
- foxes/engines/default.py +2 -2
- foxes/engines/numpy.py +11 -13
- foxes/engines/pool.py +20 -11
- foxes/engines/single.py +8 -6
- foxes/input/__init__.py +3 -3
- foxes/input/farm_layout/__init__.py +9 -8
- foxes/input/farm_layout/from_arrays.py +68 -0
- foxes/input/farm_layout/from_csv.py +1 -1
- foxes/input/farm_layout/ring.py +0 -1
- foxes/input/states/__init__.py +28 -12
- foxes/input/states/create/__init__.py +3 -2
- foxes/input/states/dataset_states.py +710 -0
- foxes/input/states/field_data.py +531 -0
- foxes/input/states/multi_height.py +11 -6
- foxes/input/states/one_point_flow.py +1 -4
- foxes/input/states/point_cloud_data.py +618 -0
- foxes/input/states/scan.py +2 -0
- foxes/input/states/single.py +3 -1
- foxes/input/states/states_table.py +23 -30
- foxes/input/states/weibull_sectors.py +330 -0
- foxes/input/states/wrg_states.py +8 -6
- foxes/input/yaml/__init__.py +9 -3
- foxes/input/yaml/dict.py +42 -41
- foxes/input/yaml/windio/__init__.py +10 -5
- foxes/input/yaml/windio/read_attributes.py +42 -29
- foxes/input/yaml/windio/read_farm.py +17 -15
- foxes/input/yaml/windio/read_fields.py +4 -2
- foxes/input/yaml/windio/read_outputs.py +25 -15
- foxes/input/yaml/windio/read_site.py +172 -11
- foxes/input/yaml/windio/windio.py +23 -11
- foxes/input/yaml/yaml.py +1 -0
- foxes/models/__init__.py +15 -14
- foxes/models/axial_induction/__init__.py +2 -2
- foxes/models/farm_controllers/__init__.py +1 -1
- foxes/models/farm_models/__init__.py +1 -1
- foxes/models/ground_models/__init__.py +3 -2
- foxes/models/ground_models/wake_mirror.py +3 -3
- foxes/models/model_book.py +190 -63
- foxes/models/partial_wakes/__init__.py +6 -6
- foxes/models/partial_wakes/axiwake.py +30 -5
- foxes/models/partial_wakes/centre.py +47 -0
- foxes/models/partial_wakes/rotor_points.py +41 -11
- foxes/models/partial_wakes/segregated.py +2 -25
- foxes/models/partial_wakes/top_hat.py +27 -2
- foxes/models/point_models/__init__.py +4 -4
- foxes/models/rotor_models/__init__.py +4 -3
- foxes/models/rotor_models/centre.py +1 -1
- foxes/models/rotor_models/direct_infusion.py +241 -0
- foxes/models/turbine_models/__init__.py +11 -11
- foxes/models/turbine_models/calculator.py +16 -3
- foxes/models/turbine_models/kTI_model.py +1 -0
- foxes/models/turbine_models/lookup_table.py +2 -0
- foxes/models/turbine_models/power_mask.py +1 -0
- foxes/models/turbine_models/rotor_centre_calc.py +2 -0
- foxes/models/turbine_models/sector_management.py +1 -0
- foxes/models/turbine_models/set_farm_vars.py +3 -9
- foxes/models/turbine_models/table_factors.py +2 -0
- foxes/models/turbine_models/thrust2ct.py +1 -0
- foxes/models/turbine_models/yaw2yawm.py +2 -0
- foxes/models/turbine_models/yawm2yaw.py +2 -0
- foxes/models/turbine_types/PCt_file.py +2 -6
- foxes/models/turbine_types/PCt_from_two.py +1 -2
- foxes/models/turbine_types/__init__.py +10 -9
- foxes/models/turbine_types/calculator_type.py +123 -0
- foxes/models/turbine_types/null_type.py +1 -0
- foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -0
- foxes/models/turbine_types/wsti2PCt_from_two.py +3 -1
- foxes/models/vertical_profiles/__init__.py +7 -7
- foxes/models/wake_deflections/__init__.py +3 -0
- foxes/models/{wake_frames/yawed_wakes.py → wake_deflections/bastankhah2016.py} +32 -111
- foxes/models/wake_deflections/jimenez.py +277 -0
- foxes/models/wake_deflections/no_deflection.py +94 -0
- foxes/models/wake_frames/__init__.py +6 -7
- foxes/models/wake_frames/dynamic_wakes.py +12 -3
- foxes/models/wake_frames/rotor_wd.py +3 -1
- foxes/models/wake_frames/seq_dynamic_wakes.py +41 -7
- foxes/models/wake_frames/streamlines.py +8 -6
- foxes/models/wake_frames/timelines.py +9 -3
- foxes/models/wake_models/__init__.py +7 -7
- foxes/models/wake_models/dist_sliced.py +50 -84
- foxes/models/wake_models/gaussian.py +20 -0
- foxes/models/wake_models/induction/__init__.py +5 -5
- foxes/models/wake_models/induction/rankine_half_body.py +30 -71
- foxes/models/wake_models/induction/rathmann.py +65 -64
- foxes/models/wake_models/induction/self_similar.py +65 -68
- foxes/models/wake_models/induction/self_similar2020.py +0 -3
- foxes/models/wake_models/induction/vortex_sheet.py +71 -75
- foxes/models/wake_models/ti/__init__.py +2 -2
- foxes/models/wake_models/ti/crespo_hernandez.py +5 -3
- foxes/models/wake_models/ti/iec_ti.py +6 -4
- foxes/models/wake_models/top_hat.py +58 -7
- foxes/models/wake_models/wind/__init__.py +6 -4
- foxes/models/wake_models/wind/bastankhah14.py +25 -7
- foxes/models/wake_models/wind/bastankhah16.py +35 -3
- foxes/models/wake_models/wind/jensen.py +15 -2
- foxes/models/wake_models/wind/turbopark.py +28 -2
- foxes/models/wake_superpositions/__init__.py +18 -9
- foxes/models/wake_superpositions/ti_linear.py +4 -4
- foxes/models/wake_superpositions/ti_max.py +4 -4
- foxes/models/wake_superpositions/ti_pow.py +4 -4
- foxes/models/wake_superpositions/ti_quadratic.py +4 -4
- foxes/models/wake_superpositions/wind_vector.py +257 -0
- foxes/models/wake_superpositions/ws_linear.py +9 -10
- foxes/models/wake_superpositions/ws_max.py +8 -8
- foxes/models/wake_superpositions/ws_pow.py +8 -8
- foxes/models/wake_superpositions/ws_product.py +4 -4
- foxes/models/wake_superpositions/ws_quadratic.py +8 -8
- foxes/output/__init__.py +21 -19
- foxes/output/farm_layout.py +4 -2
- foxes/output/farm_results_eval.py +19 -16
- foxes/output/flow_plots_2d/__init__.py +2 -2
- foxes/output/flow_plots_2d/flow_plots.py +18 -0
- foxes/output/flow_plots_2d/get_fig.py +5 -2
- foxes/output/output.py +6 -1
- foxes/output/results_writer.py +1 -1
- foxes/output/rose_plot.py +13 -3
- foxes/output/rotor_point_plots.py +3 -0
- foxes/output/seq_plugins/__init__.py +2 -2
- foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -3
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -1
- foxes/output/state_turbine_map.py +3 -0
- foxes/output/turbine_type_curves.py +10 -8
- foxes/utils/__init__.py +37 -19
- foxes/utils/abl/__init__.py +4 -4
- foxes/utils/cubic_roots.py +1 -1
- foxes/utils/data_book.py +4 -3
- foxes/utils/dict.py +49 -37
- foxes/utils/exec_python.py +5 -5
- foxes/utils/factory.py +3 -5
- foxes/utils/geom2d/__init__.py +7 -5
- foxes/utils/geopandas_utils.py +2 -2
- foxes/utils/pandas_utils.py +4 -3
- foxes/utils/tab_files.py +0 -1
- foxes/utils/weibull.py +28 -0
- foxes/utils/wrg_utils.py +3 -1
- foxes/utils/xarray_utils.py +9 -2
- foxes/variables.py +67 -9
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/METADATA +34 -63
- foxes-1.5.dist-info/RECORD +328 -0
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/WHEEL +1 -1
- tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +2 -3
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +1 -1
- tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -2
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -1
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -1
- tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -1
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -1
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -1
- foxes/input/states/field_data_nc.py +0 -847
- foxes/output/round.py +0 -10
- foxes/utils/pandas_helpers.py +0 -178
- foxes-1.3.dist-info/RECORD +0 -313
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/entry_points.txt +0 -0
- {foxes-1.3.dist-info → foxes-1.5.dist-info/licenses}/LICENSE +0 -0
- {foxes-1.3.dist-info → foxes-1.5.dist-info}/top_level.txt +0 -0
foxes/utils/dict.py
CHANGED
|
@@ -6,16 +6,11 @@ class Dict(dict):
|
|
|
6
6
|
"""
|
|
7
7
|
A slightly enhanced dictionary.
|
|
8
8
|
|
|
9
|
-
Attributes
|
|
10
|
-
----------
|
|
11
|
-
name: str
|
|
12
|
-
The dictionary name
|
|
13
|
-
|
|
14
9
|
:group: utils
|
|
15
10
|
|
|
16
11
|
"""
|
|
17
12
|
|
|
18
|
-
def __init__(self, *args,
|
|
13
|
+
def __init__(self, *args, _name=None, **kwargs):
|
|
19
14
|
"""
|
|
20
15
|
Constructor.
|
|
21
16
|
|
|
@@ -23,38 +18,28 @@ class Dict(dict):
|
|
|
23
18
|
----------
|
|
24
19
|
*args: tuple, optional
|
|
25
20
|
Arguments passed to `dict`
|
|
26
|
-
|
|
21
|
+
_name: str, optional
|
|
27
22
|
The dictionary name
|
|
28
23
|
**kwargs: dict, optional
|
|
29
24
|
Arguments passed to `dict`
|
|
30
25
|
|
|
31
26
|
"""
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
super().__init__(
|
|
46
|
-
**tmp,
|
|
47
|
-
**{
|
|
48
|
-
k: (
|
|
49
|
-
Dict(d, name=k)
|
|
50
|
-
if isinstance(d, dict) and not isinstance(d, Dict)
|
|
51
|
-
else d
|
|
52
|
-
)
|
|
53
|
-
for k, d in kwargs.items()
|
|
54
|
-
},
|
|
55
|
-
)
|
|
27
|
+
super().__init__()
|
|
28
|
+
self._name = _name if _name is not None else type(self).__name__
|
|
29
|
+
self.update(*args, **kwargs)
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def name(self):
|
|
33
|
+
"""
|
|
34
|
+
The dictionary name
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
name: str
|
|
39
|
+
The dictionary name
|
|
56
40
|
|
|
57
|
-
|
|
41
|
+
"""
|
|
42
|
+
return self._name
|
|
58
43
|
|
|
59
44
|
def get_item(self, key, *deflt, prnt=True):
|
|
60
45
|
"""
|
|
@@ -77,9 +62,9 @@ class Dict(dict):
|
|
|
77
62
|
"""
|
|
78
63
|
try:
|
|
79
64
|
if len(deflt):
|
|
80
|
-
assert (
|
|
81
|
-
len(deflt)
|
|
82
|
-
)
|
|
65
|
+
assert len(deflt) == 1, (
|
|
66
|
+
f"Expecting a single default entry, got {len(deflt)}"
|
|
67
|
+
)
|
|
83
68
|
data = self.get(key, deflt[0])
|
|
84
69
|
else:
|
|
85
70
|
data = self[key]
|
|
@@ -93,7 +78,7 @@ class Dict(dict):
|
|
|
93
78
|
raise e
|
|
94
79
|
|
|
95
80
|
if isinstance(data, dict) and not isinstance(data, Dict):
|
|
96
|
-
data = Dict(data,
|
|
81
|
+
data = Dict(data, _name=f"{self.name}.{key}")
|
|
97
82
|
|
|
98
83
|
return data
|
|
99
84
|
|
|
@@ -121,6 +106,25 @@ class Dict(dict):
|
|
|
121
106
|
del self[key]
|
|
122
107
|
return data
|
|
123
108
|
|
|
109
|
+
def __setitem__(self, key, value):
|
|
110
|
+
if isinstance(value, list):
|
|
111
|
+
out = []
|
|
112
|
+
for i, x in enumerate(value):
|
|
113
|
+
if isinstance(x, dict) and not isinstance(x, Dict):
|
|
114
|
+
nme = f"{self.name}.{key}"
|
|
115
|
+
if len(value) > 1:
|
|
116
|
+
nme += f".{i}"
|
|
117
|
+
out.append(Dict(x, _name=nme))
|
|
118
|
+
else:
|
|
119
|
+
out.append(x)
|
|
120
|
+
value = out
|
|
121
|
+
elif isinstance(value, dict) and not isinstance(value, Dict):
|
|
122
|
+
out = Dict(_name=f"{self.name}.{key}")
|
|
123
|
+
out.update(value)
|
|
124
|
+
value = out
|
|
125
|
+
|
|
126
|
+
super().__setitem__(key, value)
|
|
127
|
+
|
|
124
128
|
def __getitem__(self, key):
|
|
125
129
|
try:
|
|
126
130
|
return super().__getitem__(key)
|
|
@@ -129,6 +133,14 @@ class Dict(dict):
|
|
|
129
133
|
e = f"{self.name}: Cannot find key '{key}'. Known keys: {k}"
|
|
130
134
|
raise KeyError(e)
|
|
131
135
|
|
|
136
|
+
def update(self, *args, **kwargs):
|
|
137
|
+
"""
|
|
138
|
+
Update the dictionary with the key/value pairs from other, overwriting existing keys.
|
|
139
|
+
"""
|
|
140
|
+
other = dict(*args, **kwargs)
|
|
141
|
+
for k, v in other.items():
|
|
142
|
+
self[k] = v
|
|
143
|
+
|
|
132
144
|
@classmethod
|
|
133
145
|
def from_yaml(self, yml_file, verbosity=1):
|
|
134
146
|
"""
|
|
@@ -158,7 +170,7 @@ class Dict(dict):
|
|
|
158
170
|
data = safe_load(stream)
|
|
159
171
|
if data is None:
|
|
160
172
|
data = {}
|
|
161
|
-
dct = Dict(data,
|
|
173
|
+
dct = Dict(data, _name=fpath.stem)
|
|
162
174
|
_print(dct, level=2)
|
|
163
175
|
|
|
164
176
|
return dct
|
foxes/utils/exec_python.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import pandas as pd
|
|
3
|
-
import xarray as xr
|
|
4
|
-
import matplotlib.pyplot as plt
|
|
1
|
+
import numpy as np # noqa: F401
|
|
2
|
+
import pandas as pd # noqa: F401
|
|
3
|
+
import xarray as xr # noqa: F401
|
|
4
|
+
import matplotlib.pyplot as plt # noqa: F401
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def exec_python(s, indicator="%", newline=";", globals=globals(), locals={}):
|
|
@@ -38,7 +38,7 @@ def exec_python(s, indicator="%", newline=";", globals=globals(), locals={}):
|
|
|
38
38
|
L = len(indicator)
|
|
39
39
|
if len(s) > L and s[:L] == indicator:
|
|
40
40
|
a = s[L:]
|
|
41
|
-
if not
|
|
41
|
+
if indicator not in a:
|
|
42
42
|
exec(a, globals, locals)
|
|
43
43
|
else:
|
|
44
44
|
ilist = a.split(indicator)
|
foxes/utils/factory.py
CHANGED
|
@@ -107,7 +107,7 @@ class Factory:
|
|
|
107
107
|
f"Factory '{name_template}': Require indicator before variable '{v}' in template, e.g. '{v}<{v}>'"
|
|
108
108
|
)
|
|
109
109
|
|
|
110
|
-
self.options = Dict(
|
|
110
|
+
self.options = Dict(_name=f"{self._pre[0]}_options")
|
|
111
111
|
for v, o in options.items():
|
|
112
112
|
if v not in self.variables:
|
|
113
113
|
raise KeyError(
|
|
@@ -121,7 +121,7 @@ class Factory:
|
|
|
121
121
|
raise TypeError(
|
|
122
122
|
f"Factory '{name_template}': Found option for variable '{v}' that is not a str, {k}"
|
|
123
123
|
)
|
|
124
|
-
self.options[v] = Dict(
|
|
124
|
+
self.options[v] = Dict(_name=f"{self._pre[0]}_options_{v}", **o)
|
|
125
125
|
elif hasattr(o, "__call__"):
|
|
126
126
|
self.options[v] = o
|
|
127
127
|
else:
|
|
@@ -526,9 +526,7 @@ class WakeKFactory:
|
|
|
526
526
|
s += f"\n {v} from {list(f0.options[v])}"
|
|
527
527
|
else:
|
|
528
528
|
s += f"\n {v}={f0.hints.get(v, '(value)')}"
|
|
529
|
-
s += (
|
|
530
|
-
f"\n [wake_k]=(None or k<k> or ka<ka> or ka<ka>_kb<kb>, e.g. 004 for 0.04)"
|
|
531
|
-
)
|
|
529
|
+
s += "\n [wake_k]=(None or k<k> or ka<ka> or ka<ka>_kb<kb>, e.g. 004 for 0.04)"
|
|
532
530
|
return s
|
|
533
531
|
|
|
534
532
|
|
foxes/utils/geom2d/__init__.py
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
Geometries in two dimensions.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from .area_geometry import AreaGeometry
|
|
6
|
-
from .area_geometry import
|
|
7
|
-
from .
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
5
|
+
from .area_geometry import AreaGeometry as AreaGeometry
|
|
6
|
+
from .area_geometry import InvertedAreaGeometry as InvertedAreaGeometry
|
|
7
|
+
from .area_geometry import AreaUnion as AreaUnion
|
|
8
|
+
from .area_geometry import AreaIntersection as AreaIntersection
|
|
9
|
+
from .polygon import ClosedPolygon as ClosedPolygon
|
|
10
|
+
from .circle import Circle as Circle
|
|
11
|
+
from .half_plane import HalfPlane as HalfPlane
|
foxes/utils/geopandas_utils.py
CHANGED
|
@@ -179,7 +179,7 @@ def read_shp_polygons(
|
|
|
179
179
|
utmz = None
|
|
180
180
|
utml = None
|
|
181
181
|
apply_utm = False
|
|
182
|
-
if isinstance(to_utm, str) or to_utm
|
|
182
|
+
if isinstance(to_utm, str) or to_utm:
|
|
183
183
|
apply_utm = True
|
|
184
184
|
check_import_utm()
|
|
185
185
|
utmz = int(to_utm[:-1]) if isinstance(to_utm, str) else None
|
|
@@ -190,7 +190,7 @@ def read_shp_polygons(
|
|
|
190
190
|
names = pnames if names is None else names
|
|
191
191
|
for name in names:
|
|
192
192
|
if name == name: # exclude nan values
|
|
193
|
-
if not
|
|
193
|
+
if name not in pnames:
|
|
194
194
|
raise KeyError(
|
|
195
195
|
f"Name '{name}' not found in file '{fname}'. Names: {pnames}"
|
|
196
196
|
)
|
foxes/utils/pandas_utils.py
CHANGED
|
@@ -106,9 +106,10 @@ class PandasFileHelper:
|
|
|
106
106
|
elif sfx == "h5":
|
|
107
107
|
f = pd.read_hdf
|
|
108
108
|
elif sfx == "nc":
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
|
|
110
|
+
def f(fname, **pars):
|
|
111
|
+
"""little helper to read netcdf files"""
|
|
112
|
+
return xarray.open_dataset(fname, **pars).to_dataframe()
|
|
112
113
|
|
|
113
114
|
if f is not None:
|
|
114
115
|
pars = deepcopy(cls.DEFAULT_READING_PARAMETERS[fmt])
|
foxes/utils/tab_files.py
CHANGED
foxes/utils/weibull.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def weibull_weights(ws, ws_deltas, A, k):
|
|
5
|
+
"""
|
|
6
|
+
Computes the weibull weights for given wind speeds
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
----------
|
|
10
|
+
ws: numpy.ndarray
|
|
11
|
+
The wind speed bin centre values
|
|
12
|
+
ws_deltas: numpy.ndarray
|
|
13
|
+
The wind speed bin widths, same shape as ws
|
|
14
|
+
A: numpy.ndarray
|
|
15
|
+
The Weibull scale parameters, same shape as ws
|
|
16
|
+
k: numpy.ndarray
|
|
17
|
+
The Weibull shape parameters, same shape as ws
|
|
18
|
+
|
|
19
|
+
Returns
|
|
20
|
+
-------
|
|
21
|
+
weights: numpy.ndarray
|
|
22
|
+
The weights, same shape as ws
|
|
23
|
+
|
|
24
|
+
:group: utils
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
wsA = ws / A
|
|
28
|
+
return ws_deltas * (k / A * wsA ** (k - 1) * np.exp(-(wsA**k)))
|
foxes/utils/wrg_utils.py
CHANGED
|
@@ -42,7 +42,9 @@ class ReaderWRG:
|
|
|
42
42
|
int(self._res),
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
-
cols_sel
|
|
45
|
+
def cols_sel(name, secs):
|
|
46
|
+
"""little helper to create column names"""
|
|
47
|
+
return [f"{name}_{i}" for i in range(secs)]
|
|
46
48
|
|
|
47
49
|
cols = [0] * (8 + 3 * self._n_sectors)
|
|
48
50
|
cols[0] = "utmx"
|
foxes/utils/xarray_utils.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from xarray import Dataset
|
|
1
3
|
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
from foxes.variables import get_default_digits
|
|
@@ -31,18 +33,23 @@ def write_nc(
|
|
|
31
33
|
"""
|
|
32
34
|
fpath = Path(fpath)
|
|
33
35
|
if round is not None:
|
|
36
|
+
crds = {}
|
|
34
37
|
for v in ds.coords.keys():
|
|
35
38
|
d = round.get(v, get_default_digits(v))
|
|
36
39
|
if d is not None:
|
|
37
40
|
if verbosity > 1:
|
|
38
41
|
print(f"File {fpath.name}: Rounding {v} to {d} decimals")
|
|
39
|
-
|
|
42
|
+
crds[v] = np.round(ds[v].to_numpy(), d)
|
|
43
|
+
else:
|
|
44
|
+
crds[v] = ds[v].to_numpy()
|
|
45
|
+
dvrs = {}
|
|
40
46
|
for v in ds.data_vars.keys():
|
|
41
47
|
d = round.get(v, get_default_digits(v))
|
|
42
48
|
if d is not None:
|
|
43
49
|
if verbosity > 1:
|
|
44
50
|
print(f"File {fpath.name}: Rounding {v} to {d} decimals")
|
|
45
|
-
|
|
51
|
+
dvrs[v] = (ds[v].dims, np.round(ds[v].to_numpy(), d))
|
|
52
|
+
ds = Dataset(coords=crds, data_vars=dvrs)
|
|
46
53
|
|
|
47
54
|
enc = None
|
|
48
55
|
if complevel is not None and complevel > 0:
|
foxes/variables.py
CHANGED
|
@@ -54,6 +54,21 @@ WD = "WD"
|
|
|
54
54
|
:group: foxes.variables
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
|
+
UV = "UV"
|
|
58
|
+
""" The 2D wind vector in m/s
|
|
59
|
+
:group: foxes.variables
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
U = "U"
|
|
63
|
+
""" The first horizontal wind vector component in m/s
|
|
64
|
+
:group: foxes.variables
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
V = "V"
|
|
68
|
+
""" The second horizontal wind vector component in m/s
|
|
69
|
+
:group: foxes.variables
|
|
70
|
+
"""
|
|
71
|
+
|
|
57
72
|
TI = "TI"
|
|
58
73
|
""" The turbulence intensity
|
|
59
74
|
:group: foxes.variables
|
|
@@ -128,6 +143,17 @@ calculated from third moment
|
|
|
128
143
|
"""
|
|
129
144
|
|
|
130
145
|
|
|
146
|
+
WEIBULL_A = "Weibull_A"
|
|
147
|
+
""" The Weibull scale parameter,
|
|
148
|
+
:group: foxes.variables
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
WEIBULL_k = "Weibull_k"
|
|
152
|
+
""" The Weibull shape parameter,
|
|
153
|
+
:group: foxes.variables
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
|
|
131
157
|
AMB_WS = "AMB_WS"
|
|
132
158
|
""" The ambient wind speed in m/s
|
|
133
159
|
:group: foxes.variables
|
|
@@ -138,6 +164,21 @@ AMB_WD = "AMB_WD"
|
|
|
138
164
|
:group: foxes.variables
|
|
139
165
|
"""
|
|
140
166
|
|
|
167
|
+
AMB_UV = "AMB_UV"
|
|
168
|
+
""" The ambient 2D wind vector in m/s
|
|
169
|
+
:group: foxes.variables
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
AMB_U = "AMB_U"
|
|
173
|
+
""" The first horizontal ambient wind vector component in m/s
|
|
174
|
+
:group: foxes.variables
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
AMB_V = "AMB_V"
|
|
178
|
+
""" The second horizontal ambient wind vector component in m/s
|
|
179
|
+
:group: foxes.variables
|
|
180
|
+
"""
|
|
181
|
+
|
|
141
182
|
AMB_TI = "AMB_TI"
|
|
142
183
|
""" The ambient turbulence intensity
|
|
143
184
|
:group: foxes.variables
|
|
@@ -203,6 +244,16 @@ calculated from third moment
|
|
|
203
244
|
:group: foxes.variables
|
|
204
245
|
"""
|
|
205
246
|
|
|
247
|
+
AMB_WEIBULL_A = "AMB_Weibull_A"
|
|
248
|
+
""" Ambient Weibull scale parameter,
|
|
249
|
+
:group: foxes.variables
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
AMB_WEIBULL_k = "AMB_Weibull_k"
|
|
253
|
+
""" Ambient Weibull shape parameter,
|
|
254
|
+
:group: foxes.variables
|
|
255
|
+
"""
|
|
256
|
+
|
|
206
257
|
|
|
207
258
|
var2amb = {
|
|
208
259
|
v: f"AMB_{v}"
|
|
@@ -219,8 +270,13 @@ var2amb = {
|
|
|
219
270
|
REWS,
|
|
220
271
|
REWS2,
|
|
221
272
|
REWS3,
|
|
273
|
+
WEIBULL_A,
|
|
274
|
+
WEIBULL_k,
|
|
222
275
|
YLD,
|
|
223
276
|
CAP,
|
|
277
|
+
UV,
|
|
278
|
+
U,
|
|
279
|
+
V,
|
|
224
280
|
]
|
|
225
281
|
}
|
|
226
282
|
""" Mapping from variable to the corresponding
|
|
@@ -282,9 +338,10 @@ PA_BETA = "PA_beta"
|
|
|
282
338
|
:group: foxes.variables
|
|
283
339
|
"""
|
|
284
340
|
|
|
285
|
-
DEFAULT_DIGITS =
|
|
341
|
+
DEFAULT_DIGITS = 4
|
|
342
|
+
|
|
343
|
+
ROUND_DIGITS = {
|
|
286
344
|
WD: 3,
|
|
287
|
-
WS: 4,
|
|
288
345
|
TI: 6,
|
|
289
346
|
RHO: 5,
|
|
290
347
|
P: 3,
|
|
@@ -293,10 +350,14 @@ DEFAULT_DIGITS = {
|
|
|
293
350
|
YLD: 3,
|
|
294
351
|
CAP: 5,
|
|
295
352
|
EFF: 5,
|
|
353
|
+
WEIBULL_A: 3,
|
|
354
|
+
WEIBULL_k: 3,
|
|
355
|
+
YAW: 3,
|
|
356
|
+
YAWM: 3,
|
|
296
357
|
}
|
|
297
|
-
|
|
298
|
-
:
|
|
299
|
-
|
|
358
|
+
ROUND_DIGITS.update(
|
|
359
|
+
{var2amb[v]: ROUND_DIGITS[v] for v in var2amb.keys() if v in ROUND_DIGITS}
|
|
360
|
+
)
|
|
300
361
|
|
|
301
362
|
|
|
302
363
|
def get_default_digits(variable):
|
|
@@ -314,7 +375,4 @@ def get_default_digits(variable):
|
|
|
314
375
|
The default number of output digits
|
|
315
376
|
|
|
316
377
|
"""
|
|
317
|
-
|
|
318
|
-
if v in [REWS, REWS2, REWS3]:
|
|
319
|
-
v = WS
|
|
320
|
-
return DEFAULT_DIGITS.get(v, None)
|
|
378
|
+
return ROUND_DIGITS.get(variable, DEFAULT_DIGITS)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: foxes
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5
|
|
4
4
|
Summary: Farm Optimization and eXtended yield Evaluation Software
|
|
5
5
|
Author: Jonas Schulte
|
|
6
6
|
Maintainer: Jonas Schulte
|
|
@@ -36,7 +36,6 @@ Classifier: Topic :: Scientific/Engineering
|
|
|
36
36
|
Classifier: Intended Audience :: Developers
|
|
37
37
|
Classifier: Intended Audience :: Science/Research
|
|
38
38
|
Classifier: Programming Language :: Python :: 3
|
|
39
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
40
39
|
Classifier: Programming Language :: Python :: 3.9
|
|
41
40
|
Classifier: Programming Language :: Python :: 3.10
|
|
42
41
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -45,63 +44,42 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
45
44
|
Classifier: License :: OSI Approved :: MIT License
|
|
46
45
|
Classifier: Operating System :: OS Independent
|
|
47
46
|
Classifier: Development Status :: 4 - Beta
|
|
48
|
-
Requires-Python: >=3.
|
|
47
|
+
Requires-Python: >=3.9
|
|
49
48
|
Description-Content-Type: text/markdown
|
|
50
49
|
License-File: LICENSE
|
|
51
|
-
Requires-Dist:
|
|
52
|
-
Requires-Dist:
|
|
53
|
-
Requires-Dist:
|
|
54
|
-
Requires-Dist:
|
|
55
|
-
Requires-Dist:
|
|
56
|
-
Requires-Dist:
|
|
57
|
-
Requires-Dist:
|
|
58
|
-
Requires-Dist:
|
|
50
|
+
Requires-Dist: cycler>=0.10
|
|
51
|
+
Requires-Dist: h5netcdf>=1.0
|
|
52
|
+
Requires-Dist: matplotlib>=3.8
|
|
53
|
+
Requires-Dist: numpy>=1.26
|
|
54
|
+
Requires-Dist: pandas>=2.0
|
|
55
|
+
Requires-Dist: pyyaml>=4.0
|
|
56
|
+
Requires-Dist: scipy>=1.12
|
|
57
|
+
Requires-Dist: tqdm>=2.0
|
|
58
|
+
Requires-Dist: xarray>=2023
|
|
59
59
|
Provides-Extra: opt
|
|
60
|
-
Requires-Dist: foxes-opt; extra == "opt"
|
|
60
|
+
Requires-Dist: foxes-opt>=0.5; extra == "opt"
|
|
61
61
|
Provides-Extra: dask
|
|
62
|
-
Requires-Dist:
|
|
63
|
-
Requires-Dist:
|
|
64
|
-
Requires-Dist:
|
|
65
|
-
Requires-Dist:
|
|
66
|
-
Requires-Dist: setuptools; extra == "dask"
|
|
67
|
-
Provides-Extra: eng
|
|
68
|
-
Requires-Dist: h5netcdf; extra == "eng"
|
|
69
|
-
Requires-Dist: multiprocess; extra == "eng"
|
|
70
|
-
Requires-Dist: dask; extra == "eng"
|
|
71
|
-
Requires-Dist: distributed; extra == "eng"
|
|
72
|
-
Requires-Dist: dask-jobqueue; extra == "eng"
|
|
73
|
-
Requires-Dist: setuptools; extra == "eng"
|
|
74
|
-
Requires-Dist: mpi4py; extra == "eng"
|
|
75
|
-
Requires-Dist: ray; extra == "eng"
|
|
76
|
-
Provides-Extra: eng0
|
|
77
|
-
Requires-Dist: h5netcdf; extra == "eng0"
|
|
78
|
-
Requires-Dist: multiprocess; extra == "eng0"
|
|
79
|
-
Requires-Dist: dask; extra == "eng0"
|
|
80
|
-
Requires-Dist: distributed; extra == "eng0"
|
|
81
|
-
Requires-Dist: dask-jobqueue; extra == "eng0"
|
|
82
|
-
Requires-Dist: setuptools; extra == "eng0"
|
|
83
|
-
Requires-Dist: ray; extra == "eng0"
|
|
84
|
-
Provides-Extra: test
|
|
85
|
-
Requires-Dist: flake8; extra == "test"
|
|
86
|
-
Requires-Dist: pytest; extra == "test"
|
|
87
|
-
Requires-Dist: h5netcdf; extra == "test"
|
|
62
|
+
Requires-Dist: dask>=2022.0; extra == "dask"
|
|
63
|
+
Requires-Dist: distributed>=2022.0; extra == "dask"
|
|
64
|
+
Requires-Dist: dask-jobqueue>=0.8; extra == "dask"
|
|
65
|
+
Requires-Dist: setuptools>=61.0; extra == "dask"
|
|
88
66
|
Provides-Extra: doc
|
|
89
|
-
Requires-Dist: setuptools; extra == "doc"
|
|
90
|
-
Requires-Dist: sphinx; extra == "doc"
|
|
91
|
-
Requires-Dist: sphinx-immaterial; extra == "doc"
|
|
92
|
-
Requires-Dist: nbsphinx; extra == "doc"
|
|
93
|
-
Requires-Dist: ipykernel; extra == "doc"
|
|
94
|
-
Requires-Dist: ipywidgets; extra == "doc"
|
|
95
|
-
Requires-Dist: m2r2; extra == "doc"
|
|
96
|
-
Requires-Dist: lxml_html_clean; extra == "doc"
|
|
97
|
-
Requires-Dist: dask; extra == "doc"
|
|
98
|
-
Requires-Dist: distributed; extra == "doc"
|
|
99
|
-
Provides-Extra:
|
|
100
|
-
Requires-Dist: flake8; extra == "
|
|
101
|
-
Requires-Dist: pytest; extra == "
|
|
102
|
-
|
|
103
|
-
Requires-Dist: objsize; extra == "
|
|
104
|
-
|
|
67
|
+
Requires-Dist: setuptools>=61.0; extra == "doc"
|
|
68
|
+
Requires-Dist: sphinx>=5.0; extra == "doc"
|
|
69
|
+
Requires-Dist: sphinx-immaterial>=0.10; extra == "doc"
|
|
70
|
+
Requires-Dist: nbsphinx>=0.5; extra == "doc"
|
|
71
|
+
Requires-Dist: ipykernel>=5.0; extra == "doc"
|
|
72
|
+
Requires-Dist: ipywidgets>=5.0; extra == "doc"
|
|
73
|
+
Requires-Dist: m2r2>=0.2; extra == "doc"
|
|
74
|
+
Requires-Dist: lxml_html_clean>=0.4; extra == "doc"
|
|
75
|
+
Requires-Dist: dask>=2022.0; extra == "doc"
|
|
76
|
+
Requires-Dist: distributed>=2022.0; extra == "doc"
|
|
77
|
+
Provides-Extra: test
|
|
78
|
+
Requires-Dist: flake8>=0.1; extra == "test"
|
|
79
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
80
|
+
Provides-Extra: utils
|
|
81
|
+
Requires-Dist: objsize>=0.5; extra == "utils"
|
|
82
|
+
Dynamic: license-file
|
|
105
83
|
|
|
106
84
|
# Welcome to foxes
|
|
107
85
|
|
|
@@ -161,14 +139,7 @@ Evaluation Software"`
|
|
|
161
139
|
|
|
162
140
|
## Requirements
|
|
163
141
|
|
|
164
|
-
The supported Python versions are
|
|
165
|
-
|
|
166
|
-
- `Python 3.8`
|
|
167
|
-
- `Python 3.9`
|
|
168
|
-
- `Python 3.10`
|
|
169
|
-
- `Python 3.11`
|
|
170
|
-
- `Python 3.12`
|
|
171
|
-
- `Python 3.13`
|
|
142
|
+
The supported Python versions are `Python 3.9`...`3.13`.
|
|
172
143
|
|
|
173
144
|
## Installation
|
|
174
145
|
|