IAM that supports AR coating like Fresnel
See original GitHub issueProblem
Currently pvlib supports the DeSoto physical model (similar to normal glass), ASHRAE, Martin & Ruiz, and SAPM polynomial, but it doesn’t have a pure Fresnel model that allows additional interfaces like an AR coating.
- DeSoto physical model is most similar to the Fresnel for normal glass but only has one interface, so is limited to IAM curves below it only, while an AR coating would have a greater ρ
- Martin & Ruiz could be used to approximate an AR coated glass if the correct
a_r
were known. The default ofa_r=0.16
is slightly above the normal glass Fresnel IAM, but ana_r=0.14
seems to match an AR coating with index of refraction of 1.2 most closely.
Proposal
a new method in pvl.iam.fresnel_ar(aoi, n_ar=1.2, n_air=1.0, n_glass=1.56)
that implements the Fresnel equation
Alternative
Suggest readers to use Martin & Ruiz with a_r=0.14
instead of default.
additional content
PVsyst has switched to Fresnel equations. We can duplicate their methods ignoring additional reflections and the encapsulant layer:
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
# constants
n_glass = 1.56
n_air = 1.0
theta_inc = np.linspace(0, 88, 100)
def snell(theta_1, n1, n2):
"""Snell's equation"""
sintheta_2 = n1/n2 * np.sin(np.radians(theta_1))
return sintheta_2, np.degrees(np.arcsin(sintheta_2))
def refl_s(theta_1, theta_2, n1, n2):
"""Fresnel's equation"""
n1_costheta_1 = n1*np.cos(np.radians(theta_1))
n2_costheta_2 = n2*np.cos(np.radians(theta_2))
return np.abs((n1_costheta_1 - n2_costheta_2)/(n1_costheta_1 + n2_costheta_2))**2
def refl_p(theta_1, theta_2, n1, n2):
"""Fresnel's equation"""
n1_costheta_2 = n1*np.cos(np.radians(theta_2))
n2_costheta_1 = n2*np.cos(np.radians(theta_1))
return np.abs((n1_costheta_2 - n2_costheta_1)/(n1_costheta_2 + n2_costheta_1))**2
def refl_eff(rs, rp):
"""effective reflectivity"""
return (rs+rp)/2
def trans(refl):
"""transmissivity"""
return 1-refl
def refl0(n1, n2):
"""reflectivity at normal incidence"""
return np.abs((n1-n2)/(n1+n2))**2
def fresnel(theta_inc, n1=n_air, n2=n_glass):
"""calculate IAM using Fresnel's Law"""
_, theta_tr = snell(theta_inc, n1, n2)
rs = refl_s(theta_inc, theta_tr, n1, n2)
rp = refl_p(theta_inc, theta_tr, n1, n2)
reff = refl_eff(rs, rp)
r0 = refl0(n1, n2)
return trans(reff)/trans(r0)
def ashrae(theta_inc, b0=0.05):
"""ASHRAE equation"""
return 1 - b0*(1/np.cos(np.radians(theta_inc)) - 1)
def fresnel_ar(theta_inc, n_ar, n1=n_air, n2=n_glass):
"""calculate IAM using Fresnel's law with AR"""
# use fresnel() for n2=n_ar
_, theta_ar = snell(theta_inc, n1, n_ar)
rs_ar1 = refl_s(theta_inc, theta_ar, n1, n_ar)
rp_ar1 = refl_p(theta_inc, theta_ar, n1, n_ar)
r0_ar1 = refl0(n1, n_ar)
# repeat with fresnel() with n1=n_ar
_, theta_tr = snell(theta_ar, n_ar, n2)
rs = refl_s(theta_ar, theta_tr, n_ar, n2)
rp = refl_p(theta_ar, theta_tr, n_ar, n2)
# note that combined reflectivity is product of transmissivity!
# so... rho12 = 1 - (1-rho1)(1-rho2)
reff = refl_eff(1-(1-rs_ar1)*(1-rs), 1-(1-rp_ar1)*(1-rp))
r0 = 1-(1-refl0(n_ar, n2))*(1-r0_ar1)
return trans(reff)/trans(r0)
# plot Fresnel for normal glass and ASHRAE
plt.plot(theta_inc, fresnel(theta_inc))
plt.plot(theta_inc, ashrae(theta_inc))
# calculate IAM for AR with n=1.1 and plot
iam_ar11 = fresnel_ar(theta_inc, n_ar=1.1)
plt.plot(theta_inc, iam_ar11)
# repeat for AR with n=1.2
iam_ar12 = fresnel_ar(theta_inc, n_ar=1.2)
plt.plot(theta_inc, iam_ar12)
# make plot pretty
plt.legend(['Fresnel, normal glass', 'ASHRAE, $b_0=0.05$', 'Fresnel $n_{AR}=1.1$', 'Fresnel $n_{AR}=1.2$'])
plt.title("IAM correction, Fresnel vs. ASHRAE, using basic eqn's")
plt.ylabel('IAM')
plt.xlabel(r'incidence angle $\theta_{inc} [\degree]$')
plt.grid()
plt.ylim([0.55,1.05])
Issue Analytics
- State:
- Created a year ago
- Reactions:4
- Comments:12 (12 by maintainers)
Top Results From Across the Web
Array incidence loss (IAM) - PVsyst
The new modules with "AR coating" or "Textured glass" will use the Fresnel calculation with AR coating.
Read more >Anti-Reflective Coating Materials: A Holistic Review from PV ...
Antireflection coatings (ARCs) are predominantly utilized to suppress the Fresnel reflection losses when light propagates from one medium to ...
Read more >Diffuse IAM Calculation - pvlib python - Read the Docs
The incident angle modifier (IAM) is defined as the ratio of light transmitted at the ... n=1.526 and a glass with anti-reflective (AR)...
Read more >Anti-Reflective Coatings | Creating Solutions
The term anti-reflective (AR) coating is deceiving. What it should be called is a “transmission booster” or “light booster for a lens.
Read more >Antifogging antireflective coatings on Fresnel lenses by ...
Fresnel lenses turn out to have excellent antireflective and antifogging properties after spin-assembling both solid and mesoporous silica nanoparticles.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Well, from my perspective if it is clear you implement these formulas correctly for a two-layer window then it doesn’t need to match PVsyst or claim that it is doing the same as PVsyst.
In #1616 I submitted a proposal to extend the
ìam.physical()
function with an extra optional argumentn_ar
to support AR coating.Main differences with the code proposed above by @mikofski :
fresnel
andfresnel_ar
, the existing functionphysical
(which is equivalent withfresnel
) is extended with support for AR coating through the optional argumentn_ar
.Main differences with the previous code of
iam.physical()
(besides support for AR coating):a_tol
in the existingtest_physical
unit test.Main differences with PVSyst: