Skip to content

Commit 6a13b01

Browse files
committed
FEA: Add rotor_rpm as an array
1 parent 82ea500 commit 6a13b01

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed

power-curve-schema/examples/generic-274-20.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,64 @@
353353
0.029, 0.027, 0.025, 0.024, 0.023, 0.021, 0.02, 0.019, 0.018
354354
]
355355
],
356+
"rotor_rpm": [
357+
[
358+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
359+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
360+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
361+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
362+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
363+
],
364+
[
365+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
366+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
367+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
368+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
369+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
370+
],
371+
[
372+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
373+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
374+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
375+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
376+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
377+
],
378+
[
379+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
380+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
381+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
382+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
383+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
384+
],
385+
[
386+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
387+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
388+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
389+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
390+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
391+
],
392+
[
393+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
394+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
395+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
396+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
397+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
398+
],
399+
[
400+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
401+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
402+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
403+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
404+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
405+
],
406+
[
407+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13,
408+
4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
409+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
410+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
411+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0
412+
]
413+
],
356414
"overrides": {}
357415
},
358416
{

power-curve-schema/schema.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,32 @@
14461446
}
14471447
]
14481448
},
1449+
"rotor_rpm": {
1450+
"title": "Rotor RPM Curve",
1451+
"description": "Rotor RPM, defined as an N-D array (where N is the number of independent parameters) at the sample points described in the `parameters` property. These arrays shall be the same size and shape as the `power` value. This variation is useful for detailed loading simulations, wake simulation, and ice-throw analyses. If not given, a common practice is to assume a linear variation of rotational speed between cut_in_rpm and rated_rpm values if supplied in the `turbine` property.",
1452+
"oneOf": [
1453+
{
1454+
"title": "1 Parameter (1D Array, e.g. wind-speed for ISO standard air density of 1.225)",
1455+
"type": "array",
1456+
"$ref": "#/$defs/1darray"
1457+
},
1458+
{
1459+
"title": "2 Parameters (2D Array, e.g. air-density and wind-speed)",
1460+
"type": "array",
1461+
"$ref": "#/$defs/2darray"
1462+
},
1463+
{
1464+
"title": "3 Parameters (3D Array, e.g. turbulent-intensity, air-density and wind-speed)",
1465+
"type": "array",
1466+
"$ref": "#/$defs/3darray"
1467+
},
1468+
{
1469+
"title": "4 Parameters (4D Array, e.g. monin-obukhov-stability, turbulent-intensity, air-density and wind-speed)",
1470+
"type": "array",
1471+
"$ref": "#/$defs/4darray"
1472+
}
1473+
]
1474+
},
14491475
"acoustic_emissions": {
14501476
"title": "Acoustic emissions",
14511477
"description": "Specify the noise (Sound Power Level) emitted by the turbine in this mode of operation",

test/test_power_curves.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,69 @@ def test_wind_speed_reference(subschema, one_dimensional_mode):
331331
},
332332
schema=subschema,
333333
)
334+
335+
336+
def test_rotor_rpm(subschema, one_dimensional_mode, two_dimensional_mode):
337+
"""Ensure rotor_rpm is optional and validates correctly for 1D and 2D arrays"""
338+
# fmt: off
339+
# 1D rotor_rpm array matching the wind-speed axis (45 values)
340+
one_d_rotor_rpm = [
341+
1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0,
342+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
343+
6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0
344+
]
345+
346+
# 2D rotor_rpm array (8 air densities x 55 wind speeds)
347+
two_d_rotor_rpm = [
348+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0],
349+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0],
350+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0],
351+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0],
352+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0],
353+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0],
354+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0],
355+
[1.0, 1.31, 1.63, 1.94, 2.25, 2.56, 2.88, 3.19, 3.5, 3.81, 4.13, 4.44, 4.75, 5.06, 5.38, 5.69, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0]
356+
]
357+
# fmt: on
358+
359+
# Test 1D mode with rotor_rpm
360+
one_dimensional_mode["rotor_rpm"] = [one_d_rotor_rpm]
361+
validate(
362+
instance={
363+
"power_curves": {
364+
"default_operating_mode_label": "one_dimensional",
365+
"operating_modes": [one_dimensional_mode],
366+
}
367+
},
368+
schema=subschema,
369+
)
370+
371+
# Test 2D mode with rotor_rpm
372+
two_dimensional_mode["rotor_rpm"] = two_d_rotor_rpm
373+
validate(
374+
instance={
375+
"power_curves": {
376+
"default_operating_mode_label": "two_dimensional",
377+
"operating_modes": [two_dimensional_mode],
378+
}
379+
},
380+
schema=subschema,
381+
)
382+
383+
384+
def test_rotor_rpm_invalid(subschema, one_dimensional_mode):
385+
"""Validation should fail if rotor_rpm contains invalid values"""
386+
one_dimensional_mode["rotor_rpm"] = "not an array"
387+
388+
with pytest.raises(ValidationError) as e:
389+
validate(
390+
instance={
391+
"power_curves": {
392+
"default_operating_mode_label": "one_dimensional",
393+
"operating_modes": [one_dimensional_mode],
394+
}
395+
},
396+
schema=subschema,
397+
)
398+
399+
assert "is not valid under any of the given schemas" in str(e)

0 commit comments

Comments
 (0)