foxes 0.5.0.2__py3-none-any.whl → 0.5.2__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.
- foxes/VERSION +1 -1
- foxes/algorithms/downwind/downwind.py +41 -46
- foxes/algorithms/downwind/models/point_wakes_calc.py +4 -9
- foxes/algorithms/downwind/models/set_amb_point_results.py +5 -22
- foxes/core/algorithm.py +1 -1
- foxes/core/data_calc_model.py +26 -2
- foxes/core/partial_wakes_model.py +1 -1
- foxes/core/rotor_model.py +36 -2
- foxes/core/turbine_model.py +36 -0
- foxes/core/turbine_type.py +35 -1
- foxes/core/wake_frame.py +39 -3
- foxes/core/wake_model.py +36 -0
- foxes/models/model_book.py +129 -89
- foxes/models/turbine_models/rotor_centre_calc.py +1 -2
- foxes/models/turbine_types/CpCt_file.py +13 -3
- foxes/models/turbine_types/CpCt_from_two.py +14 -4
- foxes/models/vertical_profiles/abl_log_neutral_ws.py +32 -5
- foxes/models/vertical_profiles/abl_log_stable_ws.py +32 -4
- foxes/models/vertical_profiles/abl_log_unstable_ws.py +32 -4
- foxes/models/vertical_profiles/abl_log_ws.py +50 -18
- foxes/models/wake_frames/yawed_wakes.py +15 -9
- foxes/models/wake_models/induction/__init__.py +1 -1
- foxes/models/wake_models/induction/rankine_half_body.py +33 -7
- foxes/models/wake_models/ti/crespo_hernandez.py +6 -1
- foxes/models/wake_models/ti/iec_ti.py +5 -3
- foxes/models/wake_models/wind/__init__.py +2 -2
- foxes/models/wake_models/wind/{bastankhah.py → bastankhah14.py} +11 -14
- foxes/models/wake_models/wind/{porte_agel.py → bastankhah16.py} +24 -16
- foxes/models/wake_models/wind/turbopark.py +11 -22
- foxes/models/wake_superpositions/__init__.py +9 -5
- foxes/models/wake_superpositions/ti_linear.py +134 -0
- foxes/models/wake_superpositions/ti_max.py +134 -0
- foxes/models/wake_superpositions/{ti_superp.py → ti_pow.py} +15 -57
- foxes/models/wake_superpositions/ti_quadratic.py +134 -0
- foxes/models/wake_superpositions/ws_linear.py +170 -0
- foxes/models/wake_superpositions/ws_max.py +173 -0
- foxes/models/wake_superpositions/ws_pow.py +175 -0
- foxes/models/wake_superpositions/{product.py → ws_product.py} +43 -22
- foxes/models/wake_superpositions/ws_quadratic.py +170 -0
- foxes/output/__init__.py +4 -0
- foxes/output/calc_points.py +143 -0
- foxes/output/flow_plots_2d/__init__.py +1 -0
- foxes/output/flow_plots_2d/common.py +104 -1
- foxes/output/flow_plots_2d/flow_plots.py +237 -569
- foxes/output/flow_plots_2d/get_fig.py +183 -0
- foxes/output/flow_plots_2d/seq_flow_ani_plugin.py +0 -1
- foxes/output/grids.py +705 -0
- foxes/output/output.py +58 -11
- foxes/output/results_writer.py +101 -17
- foxes/output/round.py +10 -0
- foxes/output/slice_data.py +900 -0
- foxes/utils/__init__.py +5 -3
- foxes/utils/exec_python.py +56 -0
- foxes/utils/geopandas_utils.py +294 -0
- foxes/utils/pandas_utils.py +175 -0
- foxes/utils/plotly_utils.py +19 -0
- foxes/utils/xarray_utils.py +38 -0
- {foxes-0.5.0.2.dist-info → foxes-0.5.2.dist-info}/METADATA +1 -1
- {foxes-0.5.0.2.dist-info → foxes-0.5.2.dist-info}/RECORD +63 -49
- foxes/models/wake_superpositions/linear.py +0 -242
- foxes/models/wake_superpositions/max.py +0 -258
- foxes/models/wake_superpositions/quadratic.py +0 -252
- {foxes-0.5.0.2.dist-info → foxes-0.5.2.dist-info}/LICENSE +0 -0
- {foxes-0.5.0.2.dist-info → foxes-0.5.2.dist-info}/WHEEL +0 -0
- {foxes-0.5.0.2.dist-info → foxes-0.5.2.dist-info}/top_level.txt +0 -0
- {foxes-0.5.0.2.dist-info → foxes-0.5.2.dist-info}/zip-safe +0 -0
foxes/models/model_book.py
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import foxes.models as fm
|
|
2
2
|
import foxes.variables as FV
|
|
3
3
|
from foxes.utils import Dict
|
|
4
|
+
|
|
4
5
|
from foxes.core import (
|
|
5
|
-
TurbineModel,
|
|
6
|
-
RotorModel,
|
|
7
|
-
FarmModel,
|
|
8
6
|
PointDataModel,
|
|
7
|
+
FarmDataModel,
|
|
9
8
|
FarmController,
|
|
9
|
+
RotorModel,
|
|
10
|
+
TurbineType,
|
|
11
|
+
TurbineModel,
|
|
12
|
+
PartialWakesModel,
|
|
13
|
+
WakeFrame,
|
|
14
|
+
WakeSuperposition,
|
|
15
|
+
WakeModel
|
|
10
16
|
)
|
|
11
17
|
|
|
12
|
-
|
|
13
18
|
class ModelBook:
|
|
14
19
|
"""
|
|
15
20
|
Container for all kinds of models.
|
|
@@ -28,9 +33,6 @@ class ModelBook:
|
|
|
28
33
|
turbine_models: foxes.utils.Dict
|
|
29
34
|
The turbine models. Keys: model name str,
|
|
30
35
|
values: foxes.core.TurbineModel
|
|
31
|
-
turbine_orders: foxes.utils.Dict
|
|
32
|
-
The turbine orders. Keys: model name str,
|
|
33
|
-
values: foxes.core.TurbineOrder
|
|
34
36
|
farm_models: foxes.utils.Dict
|
|
35
37
|
The farm models. Keys: model name str,
|
|
36
38
|
values: foxes.core.FarmModel
|
|
@@ -51,6 +53,8 @@ class ModelBook:
|
|
|
51
53
|
values: foxes.core.WakeModel
|
|
52
54
|
sources: foxes.utils.Dict
|
|
53
55
|
All sources dict
|
|
56
|
+
base_classes: foxes.utils.Dict
|
|
57
|
+
The base classes for all model types
|
|
54
58
|
|
|
55
59
|
:group: foxes
|
|
56
60
|
|
|
@@ -193,47 +197,27 @@ class ModelBook:
|
|
|
193
197
|
|
|
194
198
|
self.wake_superpositions = Dict(
|
|
195
199
|
name="wake_superpositions",
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
),
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
),
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
),
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
),
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
),
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
),
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
),
|
|
218
|
-
product=fm.wake_superpositions.ProductSuperposition(),
|
|
219
|
-
product_lim=fm.wake_superpositions.ProductSuperposition(
|
|
220
|
-
lim_low={FV.WS: 1e-4},
|
|
221
|
-
),
|
|
222
|
-
ti_linear=fm.wake_superpositions.TISuperposition(
|
|
223
|
-
ti_superp="linear", superp_to_amb="quadratic"
|
|
224
|
-
),
|
|
225
|
-
ti_quadratic=fm.wake_superpositions.TISuperposition(
|
|
226
|
-
ti_superp="quadratic", superp_to_amb="quadratic"
|
|
227
|
-
),
|
|
228
|
-
ti_cubic=fm.wake_superpositions.TISuperposition(
|
|
229
|
-
ti_superp="power_3", superp_to_amb="quadratic"
|
|
230
|
-
),
|
|
231
|
-
ti_quartic=fm.wake_superpositions.TISuperposition(
|
|
232
|
-
ti_superp="power_4", superp_to_amb="quadratic"
|
|
233
|
-
),
|
|
234
|
-
ti_max=fm.wake_superpositions.TISuperposition(
|
|
235
|
-
ti_superp="max", superp_to_amb="quadratic"
|
|
236
|
-
),
|
|
200
|
+
ws_linear=fm.wake_superpositions.WSLinear(scale_amb=False),
|
|
201
|
+
ws_linear_lim=fm.wake_superpositions.WSLinear(scale_amb=False, lim_low=1e-4),
|
|
202
|
+
ws_linear_amb=fm.wake_superpositions.WSLinear(scale_amb=True),
|
|
203
|
+
ws_linear_amb_lim=fm.wake_superpositions.WSLinear(scale_amb=True, lim_low=1e-4),
|
|
204
|
+
ws_quadratic=fm.wake_superpositions.WSQuadratic(scale_amb=False),
|
|
205
|
+
ws_quadratic_lim=fm.wake_superpositions.WSQuadratic(scale_amb=False, lim_low=1e-4),
|
|
206
|
+
ws_quadratic_amb=fm.wake_superpositions.WSQuadratic(scale_amb=True),
|
|
207
|
+
ws_quadratic_amb_lim=fm.wake_superpositions.WSQuadratic(scale_amb=True, lim_low=1e-4),
|
|
208
|
+
ws_cubic=fm.wake_superpositions.WSPow(pow=3, scale_amb=False),
|
|
209
|
+
ws_cubic_amb=fm.wake_superpositions.WSPow(pow=3, scale_amb=True),
|
|
210
|
+
ws_quartic=fm.wake_superpositions.WSPow(pow=4, scale_amb=False),
|
|
211
|
+
ws_quartic_amb=fm.wake_superpositions.WSPow(pow=4, scale_amb=True),
|
|
212
|
+
ws_max=fm.wake_superpositions.WSMax(scale_amb=False),
|
|
213
|
+
ws_max_amb=fm.wake_superpositions.WSMax(scale_amb=True),
|
|
214
|
+
ws_product=fm.wake_superpositions.WSProduct(),
|
|
215
|
+
ws_product_lim=fm.wake_superpositions.WSProduct(lim_low=1e-4),
|
|
216
|
+
ti_linear=fm.wake_superpositions.TILinear(superp_to_amb="quadratic"),
|
|
217
|
+
ti_quadratic=fm.wake_superpositions.TIQuadratic(superp_to_amb="quadratic"),
|
|
218
|
+
ti_cubic=fm.wake_superpositions.TIPow(pow=3, superp_to_amb="quadratic"),
|
|
219
|
+
ti_quartic=fm.wake_superpositions.TIPow(pow=4, superp_to_amb="quadratic"),
|
|
220
|
+
ti_max=fm.wake_superpositions.TIMax(superp_to_amb="quadratic"),
|
|
237
221
|
)
|
|
238
222
|
|
|
239
223
|
self.wake_models = Dict(name="wake_models")
|
|
@@ -241,69 +225,80 @@ class ModelBook:
|
|
|
241
225
|
"linear",
|
|
242
226
|
"linear_lim",
|
|
243
227
|
"linear_amb",
|
|
228
|
+
"linear_amb_lim",
|
|
244
229
|
"quadratic",
|
|
230
|
+
"wquadratic_lim",
|
|
245
231
|
"quadratic_amb",
|
|
246
|
-
"
|
|
232
|
+
"quadratic_amb_lim",
|
|
233
|
+
"cubic",
|
|
234
|
+
"cubic_amb",
|
|
235
|
+
"quartic",
|
|
236
|
+
"quartic_amb",
|
|
237
|
+
"wmax",
|
|
247
238
|
"max_amb",
|
|
248
239
|
"product",
|
|
249
240
|
"product_lim",
|
|
250
241
|
]
|
|
251
242
|
for s in slist:
|
|
252
243
|
self.wake_models[f"Jensen_{s}"] = fm.wake_models.wind.JensenWake(
|
|
253
|
-
superposition=s
|
|
244
|
+
superposition=f"ws_{s}"
|
|
254
245
|
)
|
|
255
246
|
self.wake_models[f"Jensen_{s}_k002"] = fm.wake_models.wind.JensenWake(
|
|
256
|
-
k=0.02, superposition=s
|
|
247
|
+
k=0.02, superposition=f"ws_{s}"
|
|
257
248
|
)
|
|
258
249
|
self.wake_models[f"Jensen_{s}_k004"] = fm.wake_models.wind.JensenWake(
|
|
259
|
-
k=0.04, superposition=s
|
|
250
|
+
k=0.04, superposition=f"ws_{s}"
|
|
260
251
|
)
|
|
261
252
|
self.wake_models[f"Jensen_{s}_k007"] = fm.wake_models.wind.JensenWake(
|
|
262
|
-
k=0.07, superposition=s
|
|
253
|
+
k=0.07, superposition=f"ws_{s}"
|
|
263
254
|
)
|
|
264
255
|
self.wake_models[f"Jensen_{s}_k0075"] = fm.wake_models.wind.JensenWake(
|
|
265
|
-
k=0.075, superposition=s
|
|
256
|
+
k=0.075, superposition=f"ws_{s}"
|
|
266
257
|
)
|
|
267
258
|
|
|
268
|
-
self.wake_models[f"
|
|
269
|
-
superposition=s
|
|
259
|
+
self.wake_models[f"Bastankhah2014_{s}"] = fm.wake_models.wind.Bastankhah2014(
|
|
260
|
+
superposition=f"ws_{s}", sbeta_factor=0.2
|
|
270
261
|
)
|
|
271
262
|
self.wake_models[
|
|
272
|
-
f"
|
|
273
|
-
] = fm.wake_models.wind.
|
|
263
|
+
f"Bastankhah2014_{s}_k002"
|
|
264
|
+
] = fm.wake_models.wind.Bastankhah2014(
|
|
265
|
+
k=0.02, sbeta_factor=0.2, superposition=f"ws_{s}"
|
|
266
|
+
)
|
|
274
267
|
self.wake_models[
|
|
275
|
-
f"
|
|
276
|
-
] = fm.wake_models.wind.
|
|
268
|
+
f"Bastankhah2014_{s}_k004"
|
|
269
|
+
] = fm.wake_models.wind.Bastankhah2014(
|
|
270
|
+
k=0.04, sbeta_factor=0.2, superposition=f"ws_{s}"
|
|
271
|
+
)
|
|
277
272
|
|
|
278
|
-
self.wake_models[f"
|
|
279
|
-
superposition=s, sbeta_factor=0.
|
|
273
|
+
self.wake_models[f"Bastankhah025_{s}"] = fm.wake_models.wind.Bastankhah2014(
|
|
274
|
+
superposition=f"ws_{s}", sbeta_factor=0.25
|
|
280
275
|
)
|
|
281
276
|
self.wake_models[
|
|
282
|
-
f"
|
|
283
|
-
] = fm.wake_models.wind.
|
|
284
|
-
k=0.02, superposition=s, sbeta_factor=0.
|
|
277
|
+
f"Bastankhah025_{s}_k002"
|
|
278
|
+
] = fm.wake_models.wind.Bastankhah2014(
|
|
279
|
+
k=0.02, superposition=f"ws_{s}", sbeta_factor=0.25
|
|
285
280
|
)
|
|
286
281
|
self.wake_models[
|
|
287
|
-
f"
|
|
288
|
-
] = fm.wake_models.wind.
|
|
289
|
-
k=0.04, superposition=s, sbeta_factor=0.
|
|
282
|
+
f"Bastankhah025_{s}_k004"
|
|
283
|
+
] = fm.wake_models.wind.Bastankhah2014(
|
|
284
|
+
k=0.04, superposition=f"ws_{s}", sbeta_factor=0.25
|
|
290
285
|
)
|
|
291
286
|
|
|
292
|
-
self.wake_models[f"
|
|
293
|
-
superposition=s
|
|
287
|
+
self.wake_models[f"Bastankhah2016_{s}"] = fm.wake_models.wind.Bastankhah2016(
|
|
288
|
+
superposition=f"ws_{s}"
|
|
294
289
|
)
|
|
295
|
-
self.wake_models[f"
|
|
296
|
-
superposition=s, k=0.02
|
|
290
|
+
self.wake_models[f"Bastankhah2016_{s}_k002"] = fm.wake_models.wind.Bastankhah2016(
|
|
291
|
+
superposition=f"ws_{s}", k=0.02
|
|
297
292
|
)
|
|
298
|
-
self.wake_models[f"
|
|
299
|
-
superposition=s, k=0.04
|
|
293
|
+
self.wake_models[f"Bastankhah2016_{s}_k004"] = fm.wake_models.wind.Bastankhah2016(
|
|
294
|
+
superposition=f"ws_{s}", k=0.04
|
|
300
295
|
)
|
|
301
296
|
|
|
302
297
|
self.wake_models[f"TurbOPark_{s}_A002"] = fm.wake_models.wind.TurbOParkWake(
|
|
303
|
-
A=0.02, superposition=s
|
|
298
|
+
A=0.02, superposition=f"ws_{s}"
|
|
304
299
|
)
|
|
305
300
|
self.wake_models[f"TurbOPark_{s}_A004"] = fm.wake_models.wind.TurbOParkWake(
|
|
306
|
-
A=0.04, superposition=s
|
|
301
|
+
A=0.04, superposition=f"ws_{s}"
|
|
307
302
|
)
|
|
308
303
|
|
|
309
304
|
As = [0.02, 0.04]
|
|
@@ -314,29 +309,29 @@ class ModelBook:
|
|
|
314
309
|
d = str(dx).replace(".", "") if dx < 1 else int(dx)
|
|
315
310
|
self.wake_models[
|
|
316
311
|
f"TurbOParkIX_{s}_A{a}_dx{d}"
|
|
317
|
-
] = fm.wake_models.wind.TurbOParkWakeIX(A=A, superposition=s, dx=dx)
|
|
312
|
+
] = fm.wake_models.wind.TurbOParkWakeIX(A=A, superposition=f"ws_{s}", dx=dx)
|
|
318
313
|
|
|
319
|
-
slist = ["
|
|
314
|
+
slist = ["linear", "quadratic", "cubic", "quartic", "max"]
|
|
320
315
|
for s in slist:
|
|
321
316
|
self.wake_models[
|
|
322
|
-
f"CrespoHernandez_{s
|
|
323
|
-
] = fm.wake_models.ti.CrespoHernandezTIWake(superposition=s)
|
|
317
|
+
f"CrespoHernandez_{s}"
|
|
318
|
+
] = fm.wake_models.ti.CrespoHernandezTIWake(superposition=f"ti_{s}")
|
|
324
319
|
self.wake_models[
|
|
325
|
-
f"CrespoHernandez_ambti_{s
|
|
326
|
-
] = fm.wake_models.ti.CrespoHernandezTIWake(superposition=s, use_ambti=True)
|
|
320
|
+
f"CrespoHernandez_ambti_{s}"
|
|
321
|
+
] = fm.wake_models.ti.CrespoHernandezTIWake(superposition=f"ti_{s}", use_ambti=True)
|
|
327
322
|
self.wake_models[
|
|
328
|
-
f"CrespoHernandez_{s
|
|
329
|
-
] = fm.wake_models.ti.CrespoHernandezTIWake(k=0.02, superposition=s)
|
|
323
|
+
f"CrespoHernandez_{s}_k002"
|
|
324
|
+
] = fm.wake_models.ti.CrespoHernandezTIWake(k=0.02, superposition=f"ti_{s}")
|
|
330
325
|
|
|
331
|
-
self.wake_models[f"IECTI2005_{s
|
|
332
|
-
superposition=s, iec_type="2005"
|
|
326
|
+
self.wake_models[f"IECTI2005_{s}"] = fm.wake_models.ti.IECTIWake(
|
|
327
|
+
superposition=f"ti_{s}", iec_type="2005"
|
|
333
328
|
)
|
|
334
329
|
|
|
335
|
-
self.wake_models[f"IECTI2019_{s
|
|
336
|
-
superposition=s, iec_type="2019"
|
|
330
|
+
self.wake_models[f"IECTI2019_{s}"] = fm.wake_models.ti.IECTIWake(
|
|
331
|
+
superposition=f"ti_{s}", iec_type="2019"
|
|
337
332
|
)
|
|
338
333
|
|
|
339
|
-
self.wake_models[f"RHB"] = fm.wake_models.induction.
|
|
334
|
+
self.wake_models[f"RHB"] = fm.wake_models.induction.RankineHalfBody()
|
|
340
335
|
|
|
341
336
|
self.sources = Dict(
|
|
342
337
|
name="sources",
|
|
@@ -351,6 +346,19 @@ class ModelBook:
|
|
|
351
346
|
wake_superpositions=self.wake_superpositions,
|
|
352
347
|
wake_models=self.wake_models,
|
|
353
348
|
)
|
|
349
|
+
self.base_classes = Dict(
|
|
350
|
+
name="base_classes",
|
|
351
|
+
point_models=PointDataModel,
|
|
352
|
+
rotor_models=RotorModel,
|
|
353
|
+
turbine_types=TurbineType,
|
|
354
|
+
turbine_models=TurbineModel,
|
|
355
|
+
farm_models=FarmDataModel,
|
|
356
|
+
farm_controllers=FarmController,
|
|
357
|
+
partial_wakes=PartialWakesModel,
|
|
358
|
+
wake_frames=WakeFrame,
|
|
359
|
+
wake_superpositions=WakeSuperposition,
|
|
360
|
+
wake_models=WakeModel,
|
|
361
|
+
)
|
|
354
362
|
|
|
355
363
|
for s in self.sources.values():
|
|
356
364
|
for k, m in s.items():
|
|
@@ -383,6 +391,38 @@ class ModelBook:
|
|
|
383
391
|
else:
|
|
384
392
|
print("(none)")
|
|
385
393
|
print()
|
|
394
|
+
|
|
395
|
+
def get(self, model_type, name, class_name=None, *args, **kwargs):
|
|
396
|
+
"""
|
|
397
|
+
Gets a model object.
|
|
398
|
+
|
|
399
|
+
If not found, dynamically creates it (given the class name)
|
|
400
|
+
|
|
401
|
+
Parameters
|
|
402
|
+
----------
|
|
403
|
+
model_type: str
|
|
404
|
+
The model type
|
|
405
|
+
name: str
|
|
406
|
+
The model name
|
|
407
|
+
class_name: str, optinal
|
|
408
|
+
Name of the model class
|
|
409
|
+
args: tuple, optional
|
|
410
|
+
Arguments for the model class
|
|
411
|
+
kwargs: dict, optional
|
|
412
|
+
Arguments for the model class
|
|
413
|
+
|
|
414
|
+
Returns
|
|
415
|
+
-------
|
|
416
|
+
model: mclass
|
|
417
|
+
The model object
|
|
418
|
+
|
|
419
|
+
"""
|
|
420
|
+
if name not in self.sources[model_type]:
|
|
421
|
+
if class_name is None:
|
|
422
|
+
raise KeyError(f"Model '{name}' of type '{model_type}' not found in model book. Available: {sorted(list(self.sources[model_type].keys()))}")
|
|
423
|
+
bclass = self.base_classes[model_type]
|
|
424
|
+
self.sources[model_type][name] = bclass.new(class_name, *args, **kwargs)
|
|
425
|
+
return self.sources[model_type][name]
|
|
386
426
|
|
|
387
427
|
def finalize(self, algo, verbosity=0):
|
|
388
428
|
"""
|
|
@@ -49,8 +49,7 @@ class RotorCentreCalc(TurbineModel):
|
|
|
49
49
|
The verbosity level, 0 = silent
|
|
50
50
|
|
|
51
51
|
"""
|
|
52
|
-
|
|
53
|
-
self._wcalc = algo.PointWakesCalculation(point_vars=pvars)
|
|
52
|
+
self._wcalc = algo.get_model("PointWakesCalculation")()
|
|
54
53
|
super().initialize(algo, verbosity)
|
|
55
54
|
|
|
56
55
|
def sub_models(self):
|
|
@@ -4,7 +4,7 @@ import pandas as pd
|
|
|
4
4
|
from .PCt_file import PCtFile
|
|
5
5
|
from foxes.data import parse_Pct_file_name
|
|
6
6
|
from foxes.utils import PandasFileHelper
|
|
7
|
-
|
|
7
|
+
import foxes.constants as FC
|
|
8
8
|
|
|
9
9
|
class CpCtFile(PCtFile):
|
|
10
10
|
"""
|
|
@@ -55,6 +55,16 @@ class CpCtFile(PCtFile):
|
|
|
55
55
|
A = np.pi * (D / 2) ** 2
|
|
56
56
|
ws = data[col_ws].to_numpy()
|
|
57
57
|
cp = data[col_cp].to_numpy()
|
|
58
|
-
|
|
58
|
+
P_unit = pars.pop("P_unit", FC.kW)
|
|
59
|
+
|
|
60
|
+
ws_delta = 0.0001
|
|
61
|
+
ws_min = np.min(ws)
|
|
62
|
+
ws_max = np.max(ws)
|
|
63
|
+
N = int((ws_max - ws_min)/ws_delta)
|
|
64
|
+
|
|
65
|
+
data_P = pd.DataFrame(index=range(N), dtype=FC.DTYPE)
|
|
66
|
+
data_P["ws"] = np.linspace(ws_min, ws_max, N, endpoint=True)
|
|
67
|
+
data_P["cp"] = np.interp(data_P["ws"], ws, cp, left=0, right=0)
|
|
68
|
+
data_P["P"] = 0.5 * rho * A * data_P["cp"] * data_P["ws"]**3 / FC.P_UNITS[P_unit]
|
|
59
69
|
|
|
60
|
-
super().__init__(
|
|
70
|
+
super().__init__(data_P, col_ws="ws", col_P="P", rho=rho, P_unit=P_unit, **pars)
|
|
@@ -66,14 +66,24 @@ class CpCtFromTwo(PCtFromTwo):
|
|
|
66
66
|
A = np.pi * (D / 2) ** 2
|
|
67
67
|
ws = data_cp[col_ws_cp_file].to_numpy()
|
|
68
68
|
cp = data_cp[col_cp].to_numpy()
|
|
69
|
-
|
|
69
|
+
P_unit = pars.pop("P_unit", FC.kW)
|
|
70
|
+
|
|
71
|
+
ws_delta = 0.0001
|
|
72
|
+
ws_min = np.min(ws)
|
|
73
|
+
ws_max = np.max(ws)
|
|
74
|
+
N = int((ws_max - ws_min)/ws_delta)
|
|
75
|
+
|
|
76
|
+
data_P = pd.DataFrame(index=range(N), dtype=FC.DTYPE)
|
|
77
|
+
data_P["ws"] = np.linspace(ws_min, ws_max, N, endpoint=True)
|
|
78
|
+
data_P["cp"] = np.interp(data_P["ws"], ws, cp, left=0, right=0)
|
|
79
|
+
data_P["P"] = 0.5 * rho * A * data_P["cp"] * data_P["ws"]**3 / FC.P_UNITS[P_unit]
|
|
70
80
|
|
|
71
81
|
super().__init__(
|
|
72
|
-
|
|
82
|
+
data_P,
|
|
73
83
|
data_ct,
|
|
74
|
-
col_ws_P_file=
|
|
84
|
+
col_ws_P_file="ws",
|
|
75
85
|
col_P="P",
|
|
76
86
|
rho=rho,
|
|
77
|
-
P_unit=
|
|
87
|
+
P_unit=P_unit,
|
|
78
88
|
**pars,
|
|
79
89
|
)
|
|
@@ -8,10 +8,32 @@ class ABLLogNeutralWsProfile(VerticalProfile):
|
|
|
8
8
|
"""
|
|
9
9
|
The neutral ABL wind speed log profile.
|
|
10
10
|
|
|
11
|
+
Attributes
|
|
12
|
+
----------
|
|
13
|
+
ustar_input: bool
|
|
14
|
+
Flag for using ustar as an input
|
|
15
|
+
|
|
11
16
|
:group: models.vertical_profiles
|
|
12
17
|
|
|
13
18
|
"""
|
|
14
19
|
|
|
20
|
+
def __init__(self, *args, ustar_input=False, **kwargs):
|
|
21
|
+
"""
|
|
22
|
+
Constructor.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
args: tuple, optional
|
|
27
|
+
Additional arguments for VerticalProfile
|
|
28
|
+
ustar_input: bool
|
|
29
|
+
Flag for using ustar as an input
|
|
30
|
+
kwargs: dict, optional
|
|
31
|
+
Additional arguments for VerticalProfile
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
super().__init__(*args, **kwargs)
|
|
35
|
+
self.ustar_input = ustar_input
|
|
36
|
+
|
|
15
37
|
def input_vars(self):
|
|
16
38
|
"""
|
|
17
39
|
The input variables needed for the profile
|
|
@@ -23,7 +45,10 @@ class ABLLogNeutralWsProfile(VerticalProfile):
|
|
|
23
45
|
The variable names
|
|
24
46
|
|
|
25
47
|
"""
|
|
26
|
-
|
|
48
|
+
if self.ustar_input:
|
|
49
|
+
return [FV.USTAR, FV.Z0]
|
|
50
|
+
else:
|
|
51
|
+
return [FV.WS, FV.H, FV.Z0]
|
|
27
52
|
|
|
28
53
|
def calculate(self, data, heights):
|
|
29
54
|
"""
|
|
@@ -44,9 +69,11 @@ class ABLLogNeutralWsProfile(VerticalProfile):
|
|
|
44
69
|
|
|
45
70
|
"""
|
|
46
71
|
z0 = data[FV.Z0]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
72
|
+
if self.ustar_input:
|
|
73
|
+
ustar = data[FV.USTAR]
|
|
74
|
+
else:
|
|
75
|
+
h0 = data[FV.H]
|
|
76
|
+
ws = data[FV.WS]
|
|
77
|
+
ustar = neutral.ustar(ws, h0, z0, kappa=FC.KAPPA)
|
|
51
78
|
|
|
52
79
|
return neutral.calc_ws(heights, z0, ustar, kappa=FC.KAPPA)
|
|
@@ -8,10 +8,32 @@ class ABLLogStableWsProfile(VerticalProfile):
|
|
|
8
8
|
"""
|
|
9
9
|
The stable ABL wind speed log profile.
|
|
10
10
|
|
|
11
|
+
Attributes
|
|
12
|
+
----------
|
|
13
|
+
ustar_input: bool
|
|
14
|
+
Flag for using ustar as an input
|
|
15
|
+
|
|
11
16
|
:group: models.vertical_profiles
|
|
12
17
|
|
|
13
18
|
"""
|
|
14
19
|
|
|
20
|
+
def __init__(self, *args, ustar_input=False, **kwargs):
|
|
21
|
+
"""
|
|
22
|
+
Constructor.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
args: tuple, optional
|
|
27
|
+
Additional arguments for VerticalProfile
|
|
28
|
+
ustar_input: bool
|
|
29
|
+
Flag for using ustar as an input
|
|
30
|
+
kwargs: dict, optional
|
|
31
|
+
Additional arguments for VerticalProfile
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
super().__init__(*args, **kwargs)
|
|
35
|
+
self.ustar_input = ustar_input
|
|
36
|
+
|
|
15
37
|
def input_vars(self):
|
|
16
38
|
"""
|
|
17
39
|
The input variables needed for the profile
|
|
@@ -23,7 +45,10 @@ class ABLLogStableWsProfile(VerticalProfile):
|
|
|
23
45
|
The variable names
|
|
24
46
|
|
|
25
47
|
"""
|
|
26
|
-
|
|
48
|
+
if self.ustar_input:
|
|
49
|
+
return [FV.USTAR, FV.Z0, FV.MOL]
|
|
50
|
+
else:
|
|
51
|
+
return [FV.WS, FV.H, FV.Z0, FV.MOL]
|
|
27
52
|
|
|
28
53
|
def calculate(self, data, heights):
|
|
29
54
|
"""
|
|
@@ -43,12 +68,15 @@ class ABLLogStableWsProfile(VerticalProfile):
|
|
|
43
68
|
shape as heights
|
|
44
69
|
|
|
45
70
|
"""
|
|
46
|
-
ws = data[FV.WS]
|
|
47
|
-
h0 = data[FV.H]
|
|
48
71
|
z0 = data[FV.Z0]
|
|
49
72
|
mol = data[FV.MOL]
|
|
50
73
|
|
|
51
|
-
|
|
74
|
+
if self.ustar_input:
|
|
75
|
+
ustar = data[FV.USTAR]
|
|
76
|
+
else:
|
|
77
|
+
ws = data[FV.WS]
|
|
78
|
+
h0 = data[FV.H]
|
|
79
|
+
ustar = stable.ustar(ws, h0, z0, mol, kappa=FC.KAPPA)
|
|
52
80
|
psi = stable.psi(heights, mol)
|
|
53
81
|
|
|
54
82
|
return stable.calc_ws(heights, z0, ustar, psi, kappa=FC.KAPPA)
|
|
@@ -8,10 +8,32 @@ class ABLLogUnstableWsProfile(VerticalProfile):
|
|
|
8
8
|
"""
|
|
9
9
|
The unstable ABL wind speed log profile.
|
|
10
10
|
|
|
11
|
+
Attributes
|
|
12
|
+
----------
|
|
13
|
+
ustar_input: bool
|
|
14
|
+
Flag for using ustar as an input
|
|
15
|
+
|
|
11
16
|
:group: models.vertical_profiles
|
|
12
17
|
|
|
13
18
|
"""
|
|
14
19
|
|
|
20
|
+
def __init__(self, *args, ustar_input=False, **kwargs):
|
|
21
|
+
"""
|
|
22
|
+
Constructor.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
args: tuple, optional
|
|
27
|
+
Additional arguments for VerticalProfile
|
|
28
|
+
ustar_input: bool
|
|
29
|
+
Flag for using ustar as an input
|
|
30
|
+
kwargs: dict, optional
|
|
31
|
+
Additional arguments for VerticalProfile
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
super().__init__(*args, **kwargs)
|
|
35
|
+
self.ustar_input = ustar_input
|
|
36
|
+
|
|
15
37
|
def input_vars(self):
|
|
16
38
|
"""
|
|
17
39
|
The input variables needed for the profile
|
|
@@ -23,7 +45,10 @@ class ABLLogUnstableWsProfile(VerticalProfile):
|
|
|
23
45
|
The variable names
|
|
24
46
|
|
|
25
47
|
"""
|
|
26
|
-
|
|
48
|
+
if self.ustar_input:
|
|
49
|
+
return [FV.USTAR, FV.Z0, FV.MOL]
|
|
50
|
+
else:
|
|
51
|
+
return [FV.WS, FV.H, FV.Z0, FV.MOL]
|
|
27
52
|
|
|
28
53
|
def calculate(self, data, heights):
|
|
29
54
|
"""
|
|
@@ -43,12 +68,15 @@ class ABLLogUnstableWsProfile(VerticalProfile):
|
|
|
43
68
|
shape as heights
|
|
44
69
|
|
|
45
70
|
"""
|
|
46
|
-
ws = data[FV.WS]
|
|
47
|
-
h0 = data[FV.H]
|
|
48
71
|
z0 = data[FV.Z0]
|
|
49
72
|
mol = data[FV.MOL]
|
|
50
73
|
|
|
51
|
-
|
|
74
|
+
if self.ustar_input:
|
|
75
|
+
ustar = data[FV.USTAR]
|
|
76
|
+
else:
|
|
77
|
+
ws = data[FV.WS]
|
|
78
|
+
h0 = data[FV.H]
|
|
79
|
+
ustar = unstable.ustar(ws, h0, z0, mol, kappa=FC.KAPPA)
|
|
52
80
|
psi = unstable.psi(heights, mol)
|
|
53
81
|
|
|
54
82
|
return unstable.calc_ws(heights, z0, ustar, psi, kappa=FC.KAPPA)
|