Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MIT yaw correction model (3rd pass) #924

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
335 changes: 320 additions & 15 deletions docs/operation_models_user.ipynb

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions docs/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,15 @@ @article{SinnerFleming2024grs
title = {Robust wind farm layout optimization},
journal = {Journal of Physics: Conference Series},
}

@article{HeckJohlasHowland2023_yawed_adm,
doi = {10.1017/jfm.2023.129},
url = {https://doi.org/10.1017/jfm.2023.129},
year = {2023},
month = {mar},
publisher={Cambridge University Press},
volume = {959},
author = {K.S. Heck, H.M. Johlas and M.F. Howland},
title = {Modelling the induction, thrust and power of a yaw-misaligned actuator disk},
journal = {Journal of Fluid Mechanics},
}
87 changes: 87 additions & 0 deletions examples/examples_turbine/004_compare_yaw_loss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
Example: Change operation model and compare power loss in yaw.

This example illustrates how to define different operational models and compares
the power loss resulting from yaw misalignment across these various models.
"""

import itertools

import matplotlib.pyplot as plt
import numpy as np

from floris import FlorisModel, TimeSeries


# Parameters
N = 101 # How many steps to cover yaw range in
yaw_max = 30 # Maximum yaw angle to test

# Set up the yaw angle sweep
yaw_angles = np.zeros((N, 1))
yaw_angles[:, 0] = np.linspace(-yaw_max, yaw_max, N)
# print(yaw_angles.shape)


def evaluate_yawed_power(wsp: float, op_model: str) -> float:
print(f"Evaluating model: {op_model} wind speed: {wsp} m/s")

# Grab model of FLORIS
fmodel = FlorisModel("../inputs/gch.yaml")

# Run N cases by setting up a TimeSeries (which is just several independent simulations)
wind_directions = np.ones(N) * 270.0
fmodel.set(
wind_data=TimeSeries(
wind_speeds=wsp,
wind_directions=wind_directions,
turbulence_intensities=0.06,
)
)

yaw_angles = np.array(
[(yaw, 0.0, 0.0) for yaw in np.linspace(-yaw_max, yaw_max, N)]
)
fmodel.set_operation_model(op_model)
fmodel.set(yaw_angles=yaw_angles)
fmodel.run()

# Save the power output results in kW
return fmodel.get_turbine_powers()[:, 0] / 1000


# Loop over the operational models and wind speeds to compare
op_models = ["simple", "cosine-loss", "mit-loss"]
wind_speeds = [11.0, 11.5, 15.0]
results = {}
for op_model, wsp in itertools.product(op_models, wind_speeds):

# Save the power output results in kW
results[(op_model, wsp)] = evaluate_yawed_power(wsp, op_model)
# Plot the results
fig, axes = plt.subplots(1, len(wind_speeds), sharey=True)

colors = ["C0", "k", "r"]
linestyles = ["solid", "dashed", "dotted"]
for wsp, ax in zip(wind_speeds, axes):
ax.set_title(f"wsp: {wsp} m/s")
ax.set_xlabel("Yaw angle [deg]")
ax.grid(True)
for op_model, c, ls in zip(op_models, colors, linestyles):

upstream_yaw_angle = yaw_angles[:, 0]
central_power = results[(op_model, wsp)][upstream_yaw_angle == 0]
ax.plot(
upstream_yaw_angle,
results[(op_model, wsp)] / central_power,
label=op_model,
color=c,
linestyle=ls,
)

ax.grid(True)
ax.legend()
axes[0].set_xlabel("Yaw angle [deg]")
axes[0].set_ylabel("Normalized turbine power [-]")

plt.show()
1 change: 1 addition & 0 deletions floris/core/turbine/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

from floris.core.turbine.mit_turbine import MITTurbine
from floris.core.turbine.operation_models import (
AWCTurbine,
CosineLossTurbine,
Expand Down
Loading
Loading