In this notebook we evaluate methods for correcting static foil data for Reynolds number effects.
We will use the Sheldahl and Klimas (1981) NACA 0021 datasets.
Yamauchi and Johnson (1983) proposed a simple correction derived from turbulent flat plate boundary layer results, where the drag coefficient is corrected as
\begin{equation} C_d = C_{d_{\mathrm{table}}}/ K, \end{equation}where $K = f(Re_\mathrm{table})/f(Re)$. There are several choices for the scaling function $f(Re)$:
\begin{equation} f(Re) = Re^{-0.5}, \end{equation}\begin{equation} f(Re) = Re^{-0.2}, \end{equation}\begin{equation} f(Re) = \frac{0.455}{\ln Re}2.58 - \frac{A}{Re}, \end{equation}\begin{equation} f(Re) = (3.46 \ln Re - 5.6)^{-2}, \end{equation}or
\begin{equation} f(Re) = (\ln Re - 0.407)^{-2.64}. \end{equation}Yamauchi and Johnson propose a correction for the lift coefficient that will keep the lift slope constant, i.e.
\begin{equation} C_l = K C_{l_\mathrm{table}} (\alpha/K), \end{equation}where
\begin{equation} K = \alpha_{\max} / \alpha_{\max_\mathrm{table}} = C_{l_{\max}} / C_{l_{\max_\mathrm{table}}}. \end{equation}The scaling constant is chosen as
\begin{equation} K = \left( Re/Re_\mathrm{table} \right)^n, \end{equation}where $n$ is a small positive number between approximately 0.125 and 0.2.
In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d
import pandas as pd
from pxl.styleplot import set_sns
set_sns()
In [20]:
def load_data(Re, alpha_deg_max=25):
"""Load foil data."""
fname = "data/NACA0021_{:.1e}.csv".format(Re).replace("+0", "")
df = pd.read_csv(fname)
return df[df.alpha_deg <= alpha_deg_max]
def lookup(df, alpha_deg, quantity="cl"):
"""Lookup specified quantity at given angle of attack using linear interpolation."""
alpha_deg = np.asarray(alpha_deg)
f = interp1d(df.alpha_deg, df[quantity])
return f(alpha_deg)
def correct_cl(df, Re, Re_table, n=0.125):
"""Correct lift coefficient."""
K = (Re/Re_table)**n
df["cl_corr"] = K*lookup(df, df.alpha_deg/K, quantity="cl")
return df
def f_Re_a(Re):
return Re**(-0.5)
def f_Re_b(Re):
return Re**(-0.2)
def f_Re_c(Re):
A = None # ???
return 0.455/np.log(Re) * 2.58 - A/Re
def f_Re_d(Re):
return (3.46*np.log(Re) - 5.6)**(-2)
def f_Re_e(Re):
return (np.log(Re) - 0.407)**(-2.64)
def correct_cd(df, Re, Re_table, f_Re=f_Re_a):
"""Correct drag coefficient."""
K = f_Re(Re_table)/f_Re(Re)
df["cd_corr"] = df.cd/K
return df
Re_low = 1.6e5
Re_high = 3.6e5
df = load_data(Re_low)
df = correct_cl(df, Re_high, Re_low, n=0.23)
df = correct_cd(df, Re_high, Re_low, f_Re=f_Re_e)
df_high = load_data(Re_high)
fig, ax = plt.subplots(figsize=(7.5, 3.25), ncols=2)
ax[0].plot(df.alpha_deg, df.cl, label=r"Input ($Re_c = {:.1f} \times 10^5$)".format(Re_low/1e5))
ax[0].plot(df.alpha_deg, df.cl_corr, linestyle="--",
label=r"Corr. ($Re_c = {:.1f} \times 10^5$)".format(Re_high/1e5))
ax[0].plot(df_high.alpha_deg, df_high.cl, label=r"Raw ($Re_c = {:.1f} \times 10^5$)".format(Re_high/1e5))
ax[0].set_ylabel("$C_l$")
ax[0].legend(loc="best")
ax[1].plot(df.alpha_deg, df.cd)
ax[1].plot(df.alpha_deg, df.cd_corr, linestyle="--")
ax[1].plot(df_high.alpha_deg, df_high.cd)
ax[1].set_xlim((0, 12))
ax[1].set_ylim((0, 0.04))
for a in ax:
a.set_xlabel(r"$\alpha$ (deg.)")
fig.tight_layout()
plt.show()