fresnel_reflection

iadpython.fresnel.fresnel_reflection(n_i, nu_i, n_t)[source]

Fresnel Reflection.

Calculates the specular reflection for light incident at an angle theta_i from the normal (having a cosine equal to nu_i) in a medium with index of refraction ‘n_i’ onto a medium with index of refraction ‘n_t’ .

The usual way to calculate the total reflection for unpolarized light is to use the Fresnel formula

\[R = \frac{1}{2} \left[\frac{\sin^2(\theta_i-\theta_t)}{\sin^2(\theta_i+\theta_t)} + \frac{\tan^2(\theta_i-\theta_t)}{\tan^2(\theta_i+\theta_t)} \right]\]

where theta_i and theta_t represent the angle (from normal) that light is incident and the angle at which light is transmitted. There are several problems with calculating the reflection using this formula. First, if the angle of incidence is zero, then the formula results in division by zero. Furthermore, if the angle of incidence is near zero, then the formula is the ratio of two small numbers and the results can be inaccurate. Second, if the angle of incidence exceeds the critical angle, then the calculation of theta_t results in an attempt to find the arcsine of a quantity greater than one. Third, all calculations in this program are based on the cosine of the angle. This routine forces the calling routine to find theta_i = cos**-1 nu. Fourth, the routine also gives problems when the critical angle is exceeded.

Closer inspection reveals that this is the wrong formulation to use. The formulas that should be used for parallel and perpendicular polarization are

\[R_\parallel = \left[\frac{n_t\cos\theta_i-n_i\cos\theta_t} {n_t\cos\theta_i+n_i\cos\theta_t}\right]^2,\]
\[R_\perp = \left[\frac{n_i\cos\theta_i-n_t\cos\theta_t} {n_i\cos\theta_i+n_t\cos\theta_t}\right]^2.\]

The formula for unpolarized light, written in terms of \(\nu_i = \cos \theta_i\) and \(\nu_t = \cos \theta_t\) is

\[R = \frac{1}{2} \left[\frac{n_t\nu_i-n_i\nu_t}{n_t \nu_i+n_i \nu_t}\right]^2 + \frac{1}{2} \left[\frac{n_i\nu_i-n_t\nu_t}{n_i \nu_i+n_t \nu_t}\right]^2\]

This formula has the advantage that no trig routines need to be called and that the case of normal irradiance does not cause division by zero. Near normal incidence remains numerically well-conditioned. In the routine below, I test for matched boundaries and normal incidence to eliminate unnecessary calculations. I also test for total internal reflection to avoid possible division by zero. I also find the ratio of the indices of refraction to avoid an extra multiplication and several intermediate variables.

The tricky things about this implementation are to get handle angles above the critical angle properly and trying to keep everything working when arrays are passed. If n_i==n_t then we want to return zero, otherwise we want to return 1.