2 * \brief Optical properties of materials.
4 #ifndef QPMS_MATERIALS_H
5 #define QPMS_MATERIALS_H
6 #include "qpms_types.h"
7 #include <gsl/gsl_spline.h>
10 /// Speed of light in m/s.
11 #define SPEED_OF_LIGHT (2.99792458e8)
15 /// Prototype for general optical property generator for isotropic materials.
16 typedef struct qpms_epsmu_generator_t
{
17 /// Generator function.
19 * qpms_epsmu_const_g(),
20 * qpms_permittivity_interpolator_epsmu_g(),
21 * qpms_lorentzdrude_epsmu_g().
23 qpms_epsmu_t (*function
) (complex double omega
, const void *params
);
25 } qpms_epsmu_generator_t
;
27 /// Convenience function for generating material properties at given frequency.
28 static inline qpms_epsmu_t
qpms_epsmu_generator_eval(
29 qpms_epsmu_generator_t gen
, complex double omega
) {
30 return gen
.function(omega
, gen
.params
);
33 /// Constant optical property "generator" for qpms_epsmu_generator_t.
34 qpms_epsmu_t
qpms_epsmu_const_g(complex double omega
, ///< Frequency ignored.
35 const void *epsmu
///< Points to the qpms_epsmu_t to be returned.
38 /// Gets refractive index of a material from its permeability and permittivity.
39 /** \f[ n = \sqrt{\mu_r \varepsilon_r} \f] */
40 static inline complex double qpms_refindex(qpms_epsmu_t em
) {
41 return csqrt(em
.eps
* em
.mu
);
44 /// Gets wave number \a k from angular frequency and material permeability and permittivity.
45 /** \f[ k = \frac{n\omega}{c_0} = \frac{\omega\sqrt{\mu_r \varepsilon_r}}{c_0} \f] */
46 static inline complex double qpms_wavenumber(complex double omega
, qpms_epsmu_t em
) {
47 return qpms_refindex(em
)*omega
/SPEED_OF_LIGHT
;
50 /// Gets (relative) wave impedance \f$ \eta_r \f$ from material permeability and permittivity.
51 /** \eta_r = \sqrt{\mu_r / \varepsilon_r} \f] */
52 static inline complex double qpms_waveimpedance(qpms_epsmu_t em
) {
53 return csqrt(em
.mu
/ em
.eps
);
56 /// A \f$ (f_j, \omega_j, \gamma_j) \f$ triple for qpms_ldparams_t.
57 typedef struct qpms_ldparams_triple_t
{
61 } qpms_ldparams_triple_t
;
63 /// Structure holding Lorentz-Drude model parameters of a material.
65 * \varepsilon = \varepsilon_\infty + \sum_j=0^{n-1}
66 * \frac{f_j \omega_p^2}{\omega_j^2-\omega^2+i\omega\gamma_j}
69 typedef struct qpms_ldparams_t
{
70 complex double eps_inf
; ///< Permittivity at infinity.
71 double omega_p
; ///< Plasma frequency.
72 size_t n
; ///< Number of "oscillators".
73 qpms_ldparams_triple_t data
[]; ///< "Oscillator" parameters.
76 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_AG
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for silver.
77 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_AU
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for gold.
78 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_CU
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for copper.
79 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_AL
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for aluminium.
80 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_CR
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for chromium.
81 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_TI
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for titanium.
82 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_BE
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for beryllium.
83 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_NI
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for nickel.
84 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_PD
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for polonium.
85 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_PT
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for platinum.
86 extern const qpms_ldparams_t
*const QPMS_LDPARAMS_W
; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for tungsten.
88 /// Lorentz-Drude permittivity.
89 complex double qpms_lorentzdrude_eps(complex double omega
, const qpms_ldparams_t
*);
91 /// Lorentz-Drude optical properties, with relative permeability set always to one.
92 qpms_epsmu_t
qpms_lorentzdrude_epsmu(complex double omega
, const qpms_ldparams_t
*);
94 /// Lorentz-Drude optical properties, with relative permeability set always to one, compatible with qpms_epsmu_generator_t.
95 qpms_epsmu_t
qpms_lorentzdrude_epsmu_g(
97 const void *ldparams
///< Lorentz-Drude parameters, in reality const qpms_ldparams_t *.
101 /// Interpolator of tabulated optical properties.
102 // TODO use gsl_interp instead of gsl_spline.
103 typedef struct qpms_permittivity_interpolator_t
{
104 double *wavelength_m
; ///< Wavelength array (in meters).
105 double *n
; ///< Refraction index array.
106 double *k
; ///< Attenuation coefficient array.
107 gsl_interp
*interp_n
; ///< Refraction index interpolator object.
108 gsl_interp
*interp_k
; ///< Attenuation coeff interpolator object.
109 size_t size
; ///< Size of n[], k[], and wavelength_m[].
110 // I could add gsl_interp_accel, but that is not necessary.
111 } qpms_permittivity_interpolator_t
;
113 /// Creates a permittivity interpolator from tabulated wavelengths, refraction indices and extinction coeffs.
114 qpms_permittivity_interpolator_t
*qpms_permittivity_interpolator_create(const size_t incount
,
115 const double *wavelength_m
, ///< Tabulated vacuum wavelength in metres, in strictly increasing order.
116 const double *n
, ///< Tabulated refraction indices at omega.
117 const double *k
, ///< Tabulated extinction coefficients.
118 const gsl_interp_type
*iptype
///< GSL interpolator type
121 /// Creates a permittivity interpolator from an yml file downloaded from refractiveindex.info website.
122 qpms_permittivity_interpolator_t
*qpms_permittivity_interpolator_from_yml(
123 const char *path
, ///< Path to the yml file.
124 const gsl_interp_type
*iptype
///< GSL interpolator type
127 /// Evaluates interpolated material permittivity at a given angular frequency.
128 complex double qpms_permittivity_interpolator_eps_at_omega(
129 const qpms_permittivity_interpolator_t
*interp
, double omega_SI
);
131 /// Evaluates interpolated material permittivity at a given angular frequency, qpms_epsmu_generator_t compatible version.
132 /** Permeability is always set to one. Imaginary part of omega is discarded.
134 qpms_epsmu_t
qpms_permittivity_interpolator_epsmu_g(
135 complex double omega
, ///< Angular frequency. The imaginary part is ignored!
136 const void * interpolator
///< Interpolator of type qpms_permittivity_interpolator_t
139 /// Returns the minimum angular frequency supported by the interpolator.
140 double qpms_permittivity_interpolator_omega_min(
141 const qpms_permittivity_interpolator_t
*ip
);
143 /// Returns the minimum angular frequency supported by the interpolator.
144 double qpms_permittivity_interpolator_omega_max(
145 const qpms_permittivity_interpolator_t
*ip
);
147 /// Destroy a permittivity interpolator.
148 void qpms_permittivity_interpolator_free(qpms_permittivity_interpolator_t
*interp
);
150 /// Relative permittivity from the Drude model.
151 static inline complex double qpms_drude_epsilon(
152 complex double eps_inf
, ///< Relative permittivity "at infinity".
153 complex double omega_p
, ///< Plasma frequency \f$ \omega_p \f$ of the material.
154 complex double gamma_p
, ///< Decay constant \f$ \gamma_p \f$ of the material.
155 complex double omega
///< Frequency \f$ \omega \f$ at which the permittivity is evaluated.
157 return eps_inf
- omega_p
*omega_p
/(omega
*(omega
+I
*gamma_p
));
161 #endif //QPMS_MATERIALS_H