Fix saving lists of arrays with recent versions of numpy
[qpms.git] / qpms / materials.h
blob912e15d3d427d91269707d33d5e9ea03316f188a
1 /*! \file materials.h
2 * \brief Optical properties of materials.
3 */
4 #ifndef QPMS_MATERIALS_H
5 #define QPMS_MATERIALS_H
6 #include "qpms_types.h"
7 #include <gsl/gsl_spline.h>
9 #ifndef SPEED_OF_LIGHT
10 /// Speed of light in m/s.
11 #define SPEED_OF_LIGHT (2.99792458e8)
12 #endif
15 /// Prototype for general optical property generator for isotropic materials.
16 typedef struct qpms_epsmu_generator_t {
17 /// Generator function.
18 /** Implemented by:
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);
24 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 {
58 double f;
59 double omega;
60 double gamma;
61 } qpms_ldparams_triple_t;
63 /// Structure holding Lorentz-Drude model parameters of a material.
64 /** \f[
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}
67 * \f]
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.
74 } qpms_ldparams_t;
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(
96 complex double omega,
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