Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mitwindfarm/CurledWake.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def stamp_ic(
# rotate points into yaw-and-tilt frame
_, y_i, z_i = eff_yaw_inv_rotation(np.zeros_like(r_i), np.zeros_like(r_i), r_i, eff_yaw, rotor.yaw, rotor.tilt)
# NOTE: rotor.Ct differs from Shapiro et al. (2018) definition - includes cos^2(eff_yaw)
Gamma_0 = 0.5 * D * rotor.REWS * rotor.Ct * np.sin(eff_yaw)
Gamma_0 = 0.5 * D * rotor.REWS * rotor.extra.Ct * np.sin(eff_yaw)
Gamma_i = (
Gamma_0 * 4 * r_i / (self.N_vortex * D * np.sqrt(1 - (2 * r_i / D) ** 2))
)
Expand Down
52 changes: 52 additions & 0 deletions tests/test_uref_invariance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
Test that the CurledWake solver produces non-dimensionally invariant results
when the freestream velocity U0 is rescaled (and k-l is used).
"""

import numpy as np
from pytest import approx
from mitwindfarm import Uniform, Layout
from mitwindfarm.windfarm import CurledWindfarm
from mitwindfarm.Rotor import UnifiedAD_TI


def _run_curled_farm(U0, k_model="const"):
"""Run a 2-turbine yawed farm at given U0."""
wf = CurledWindfarm(
rotor_model=UnifiedAD_TI(),
base_windfield=Uniform(U0=U0, TIamb=0.05),
solver_kwargs=dict(
dy=0.1, dz=0.1,
integrator="scipy_rk23",
k_model=k_model,
verbose=False,
),
)
layout = Layout([0, 5], [0, 0], [0, 0])
yaw = np.radians(20)
setpoints = [(2, yaw, 0)] * 2
return wf(layout, setpoints)


def test_uref_invariance_kl():
"""REWS/U0 must be identical at U0=1 and U0=2 (k-l turbulence model)."""
sol1 = _run_curled_farm(U0=1.0, k_model="k-l")
sol2 = _run_curled_farm(U0=2.0, k_model="k-l")

for i in range(2):
rews_ratio_1 = sol1.rotors[i].REWS / 1.0
rews_ratio_2 = sol2.rotors[i].REWS / 2.0
assert rews_ratio_2 == approx(rews_ratio_1, rel=1e-2), (
f"Turbine {i}: REWS/U0 differs between U0=1 ({rews_ratio_1:.4f}) "
f"and U0=2 ({rews_ratio_2:.4f})"
)


def test_downstream_rews_below_freestream():
"""Downstream turbine in a wake cannot see REWS > U0 with uniform inflow."""
sol = _run_curled_farm(U0=8.0, k_model="const")
for i in range(1, 2): # skip turbine 0 (upstream)
assert sol.rotors[i].REWS <= 8.0 * 1.01, (
f"Turbine {i}: REWS={sol.rotors[i].REWS:.2f} exceeds U0=8.0 "
f"— physically impossible with uniform inflow"
)