'''
Author: Unsaturated Transistor; Code created and exported to HTML using the eric IDE; Dated 15th January 2026
Want the code? Download the python file here.
Go back?
'''
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import argrelextrema
import textwrap
# === Matplotlib config to keep text selectable in vector outputs ===
plt.rcParams.update({
'font.size': 12,
'svg.fonttype': 'none', # keep text as <text> elements in SVG (selectable)
'pdf.fonttype': 42, # embed TrueType fonts in PDF (selectable text)
'text.usetex': False
})
# Parameters
n0 = 1.0
nL = 1.6
nH = 2.0
ns = 1.5
lambda_0 = 1000.0 # Design wavelength in nm
# Wavelength range (200..1800 nm, 1 nm resolution)
wavelengths = np.linspace(200.0, 1800.0, 1601)
reflectances = []
# Calculation loop
for lam in wavelengths:
# Optical thickness n * d = lambda_0 / 4
# delta = (2*pi*n*d)/lambda => using n*d = lambda_0/4 gives:
delta = (np.pi * lambda_0) / (2.0 * lam)
# Characteristic matrices for quarter-wave layers
M1 = np.array([
[np.cos(delta), 1j / nL * np.sin(delta)],
[1j * nL * np.sin(delta), np.cos(delta)]
])
M2 = np.array([
[np.cos(delta), 1j / nH * np.sin(delta)],
[1j * nH * np.sin(delta), np.cos(delta)]
])
M = M1.dot(M2)
B, C = M.dot(np.array([1.0, ns]))
r = (n0 * B - C) / (n0 * B + C)
R = np.abs(r) ** 2
reflectances.append(R)
reflectances = np.array(reflectances)
# Find indices of local maxima and minima
max_indices = argrelextrema(reflectances, np.greater)[0]
min_indices = argrelextrema(reflectances, np.less)[0]
max_lambdas = wavelengths[max_indices]
max_R = reflectances[max_indices]
min_lambdas = wavelengths[min_indices]
min_R = reflectances[min_indices]
# === Plotting (A4 landscape size) ===
fig = plt.figure(figsize=(11.69, 8.27))
plt.plot(
wavelengths,
reflectances * 100,
'k-',
linewidth=1.5,
label='Reflectance'
)
plt.plot(
max_lambdas,
max_R * 100,
'k^',
markersize=8,
linestyle='None',
label='Maxima'
)
plt.plot(
min_lambdas,
min_R * 100,
'kv',
markersize=8,
linestyle='None',
label='Minima'
)
# add 1800 nm boundary marker explicitly
plt.plot(1800.0, reflectances[-1] * 100, 'kv', markersize=8)
plt.xlabel('Wavelength / nm', fontsize=12)
plt.ylabel('Percentage Reflectance', fontsize=12)
title_text = (
"Plot of the reflectance for the two-layer coating upon the glass substrate, "
"with a design wavelength $\lambda_0$ = 1000 nm"
)
wrapped_title = "
".join(textwrap.wrap(title_text, width=70))
plt.title(wrapped_title, fontsize=16)
plt.grid(True, color='gray', linestyle='--', alpha=0.5)
plt.xlim(200, 1800)
plt.ylim(0, reflectances.max() * 100 + 1)
plt.legend(loc='upper right', frameon=True)
# Save as SVG and PDF
plt.savefig(
'reflectance_plot_A4_monochrome_1800.svg',
format='svg',
bbox_inches='tight'
)
plt.savefig(
'reflectance_plot_A4_monochrome_1800.pdf',
format='pdf',
bbox_inches='tight'
)
plt.show()
# Print formatted extrema and boundary value
for l, r_val in zip(max_lambdas, max_R):
print(f"Max: {l:.1f} nm, R = {r_val*100:.2f}%")
for l, r_val in zip(min_lambdas, min_R):
print(f"Min: {l:.1f} nm, R = {r_val*100:.2f}%")
print(f"Boundary 1800 nm, R = {reflectances[-1]*100:.2f}%")