codexleading-edge-radius-window.py
leading-edge-radius-window.py
"""Conditioning and truncation bias in a sampled leading-edge radius estimate.
Run from the desired media output directory. NumPy and Matplotlib dependencies
are supplied by pyproject.toml. The analytic local nose is stipulated, not a NACA
profile or measured data; the PNG is written to the working directory.
"""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
TRUE_RADIUS_M = 0.003
QUARTIC_COEFFICIENT = 1.0e7 # m^-3
HORIZONTAL_ERROR_M = 1.0e-5
def estimates(height_m):
x = height_m**2 / (2*TRUE_RADIUS_M) + QUARTIC_COEFFICIENT*height_m**4
centre = height_m**2 / (2*x)
lower = height_m**2 / (2*(x+HORIZONTAL_ERROR_M))
upper = height_m**2 / (2*(x-HORIZONTAL_ERROR_M))
return x, centre, lower, upper
def main():
height = np.linspace(0.35e-3, 2.0e-3, 900)
x, centre, lower, upper = estimates(height)
assert np.all(x > HORIZONTAL_ERROR_M)
fig, ax = plt.subplots(figsize=(7.2, 4.6), dpi=100, facecolor='white')
ax.set_facecolor('white')
ax.fill_between(height*1000, lower/TRUE_RADIUS_M, upper/TRUE_RADIUS_M,
color='#98c4e8', alpha=.65, label='Bounded horizontal error: ±10 μm')
ax.plot(height*1000, centre/TRUE_RADIUS_M, color='#145d98', lw=2.3,
label='Quadratic quotient, exact coordinates')
ax.axhline(1.0, color='black', lw=1.3, ls='--', label='True nose radius: 3 mm')
ax.set(xlim=(.35, 2.0), ylim=(.6, 2.05), xlabel='Sample height from nose centreline (mm)',
ylabel='Estimated radius / true radius')
ax.set_title('Leading-edge radius: coordinate error versus model bias', fontsize=12)
ax.text(.98, .94, r'$x=y^2/(2r_0)+b y^4$'+'\n'+r'$b=10^7\ \mathrm{m}^{-3}$',
transform=ax.transAxes, ha='right', va='top', fontsize=11)
ax.legend(loc='upper center', bbox_to_anchor=(.52,.74), fontsize=8.7, framealpha=1)
ax.annotate('Small offsets amplify\nfixed coordinate errors', xy=(.4,1.48),
xytext=(.72,1.85), fontsize=9,
arrowprops={'arrowstyle':'->','color':'#555555'}, color='#444444')
ax.annotate('Larger offsets retain\nmore quartic-model bias', xy=(1.85,.83),
xytext=(1.15,.67), fontsize=9,
arrowprops={'arrowstyle':'->','color':'#555555'}, color='#444444')
ax.grid(alpha=.16)
fig.text(.5,.017,'Original local geometry; exact vertical coordinates; not measured airfoil data.',
ha='center',fontsize=8.5,color='#555555')
fig.tight_layout(rect=(0,.035,1,1))
fig.savefig(Path('leading-edge-radius-window.png'),dpi=100,facecolor='white',transparent=False)
plt.close(fig)
if __name__ == '__main__':
main()