Skip to content

Commit 30fe99e

Browse files
committed
fix: measure blade span from the root in the rotor lever
reference_axis.z can be offset from zero (defined from a hub datum), but the rotor lever used the absolute z as the distance from the root, placing every section z[0] too far out and inflating the rotor inertia and coned CM offset. The mass integration already used the root-relative arc length, so only the lever was wrong. Subtract the root value: span = z - z[0]. A [20, 70] axis now gives the same rotor inertia and CM as [0, 50].
1 parent bb3ddad commit 30fe99e

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

src/pybmodes/io/windio.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,12 @@ def _blade_span_mass_inertia(
980980
# unaffected. The polar lever is the in-plane distance from the shaft axis
981981
# ``r² + t²`` (so sweep and prebend are not dropped, issue #130); the
982982
# axial offset feeds the coned transverse term.
983-
x_off, y_off, span = coords[0], coords[1], coords[2]
983+
# Span measured from the blade root: reference_axis.z may be offset from
984+
# zero (defined from a hub datum), so subtract the root value rather than
985+
# treat the absolute z as the distance from the root, which would place
986+
# every section too far out.
987+
x_off, y_off = coords[0], coords[1]
988+
span = coords[2] - coords[2][0]
984989
# Distance from the hub centre along the (coned) pitch axis: the blade
985990
# root sits at the hub radius and each section a further `span` outboard,
986991
# so the whole (hub_r + span) length projects through the cone, matching

tests/test_windio_rna.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,30 @@ def _mk(y_off: float):
347347
assert swept.izz > straight.izz
348348

349349

350+
def test_rna_blade_span_offset_from_root(tmp_path: pathlib.Path) -> None:
351+
"""reference_axis.z offset from zero (defined from a hub datum) is measured
352+
relative to the root, so a [20, 70] axis gives the same rotor inertia and
353+
CM as [0, 50] rather than placing every section 20 m too far out (Codex
354+
review on #130)."""
355+
pytest.importorskip("yaml")
356+
from pybmodes.io.windio import read_windio_rna
357+
358+
def _mk(z0: float, z1: float):
359+
o = _base_ontology()
360+
o["components"]["hub"]["cone_angle"] = 0.15
361+
o["components"]["nacelle"]["drivetrain"]["uptilt"] = 0.10
362+
ra = o["components"]["blade"]["elastic_properties_mb"]["six_x_six"][
363+
"reference_axis"
364+
]
365+
ra["z"] = {"grid": [0.0, 1.0], "values": [z0, z1]}
366+
return read_windio_rna(_write(o, tmp_path, f"z_{z0}_{z1}.yaml"))
367+
368+
base = _mk(0.0, 50.0)
369+
offset = _mk(20.0, 70.0)
370+
for attr in ("mass", "cm_axial", "ixx", "iyy", "izz"):
371+
assert getattr(offset, attr) == pytest.approx(getattr(base, attr))
372+
373+
350374
def test_rna_upwind_hub_offdiagonal_inertia_sign(tmp_path: pathlib.Path) -> None:
351375
"""The WindIO hub frame has z up, so at zero tilt the hub tensor rotates by
352376
the identity and its off-diagonal Iyz passes through unchanged, even for an

0 commit comments

Comments
 (0)