162 lines
7.6 KiB
C
162 lines
7.6 KiB
C
/*! \file materials.h
|
|
* \brief Optical properties of materials.
|
|
*/
|
|
#ifndef QPMS_MATERIALS_H
|
|
#define QPMS_MATERIALS_H
|
|
#include "qpms_types.h"
|
|
#include <gsl/gsl_spline.h>
|
|
|
|
#ifndef SPEED_OF_LIGHT
|
|
/// Speed of light in m/s.
|
|
#define SPEED_OF_LIGHT (2.99792458e8)
|
|
#endif
|
|
|
|
|
|
/// Prototype for general optical property generator for isotropic materials.
|
|
typedef struct qpms_epsmu_generator_t {
|
|
/// Generator function.
|
|
/** Implemented by:
|
|
* qpms_epsmu_const_g(),
|
|
* qpms_permittivity_interpolator_epsmu_g(),
|
|
* qpms_lorentzdrude_epsmu_g().
|
|
*/
|
|
qpms_epsmu_t (*function) (complex double omega, const void *params);
|
|
const void *params;
|
|
} qpms_epsmu_generator_t;
|
|
|
|
/// Convenience function for generating material properties at given frequency.
|
|
static inline qpms_epsmu_t qpms_epsmu_generator_eval(
|
|
qpms_epsmu_generator_t gen, complex double omega) {
|
|
return gen.function(omega, gen.params);
|
|
}
|
|
|
|
/// Constant optical property "generator" for qpms_epsmu_generator_t.
|
|
qpms_epsmu_t qpms_epsmu_const_g(complex double omega, ///< Frequency ignored.
|
|
const void *epsmu ///< Points to the qpms_epsmu_t to be returned.
|
|
);
|
|
|
|
/// Gets refractive index of a material from its permeability and permittivity.
|
|
/** \f[ n = \sqrt{\mu_r \varepsilon_r} \f] */
|
|
static inline complex double qpms_refindex(qpms_epsmu_t em) {
|
|
return csqrt(em.eps * em.mu);
|
|
}
|
|
|
|
/// Gets wave number \a k from angular frequency and material permeability and permittivity.
|
|
/** \f[ k = \frac{n\omega}{c_0} = \frac{\omega\sqrt{\mu_r \varepsilon_r}}{c_0} \f] */
|
|
static inline complex double qpms_wavenumber(complex double omega, qpms_epsmu_t em) {
|
|
return qpms_refindex(em)*omega/SPEED_OF_LIGHT;
|
|
}
|
|
|
|
/// Gets (relative) wave impedance \f$ \eta_r \f$ from material permeability and permittivity.
|
|
/** \eta_r = \sqrt{\mu_r / \varepsilon_r} \f] */
|
|
static inline complex double qpms_waveimpedance(qpms_epsmu_t em) {
|
|
return csqrt(em.mu / em.eps);
|
|
}
|
|
|
|
/// A \f$ (f_j, \omega_j, \gamma_j) \f$ triple for qpms_ldparams_t.
|
|
typedef struct qpms_ldparams_triple_t {
|
|
double f;
|
|
double omega;
|
|
double gamma;
|
|
} qpms_ldparams_triple_t;
|
|
|
|
/// Structure holding Lorentz-Drude model parameters of a material.
|
|
/** \f[
|
|
* \varepsilon = \varepsilon_\infty + \sum_j=0^{n-1}
|
|
* \frac{f_j \omega_p^2}{\omega_j^2-\omega^2+i\omega\gamma_j}
|
|
* \f]
|
|
*/
|
|
typedef struct qpms_ldparams_t {
|
|
complex double eps_inf; ///< Permittivity at infinity.
|
|
double omega_p; ///< Plasma frequency.
|
|
size_t n; ///< Number of "oscillators".
|
|
qpms_ldparams_triple_t data[]; ///< "Oscillator" parameters.
|
|
} qpms_ldparams_t;
|
|
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_AG; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for silver.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_AU; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for gold.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_CU; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for copper.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_AL; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for aluminium.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_CR; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for chromium.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_TI; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for titanium.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_BE; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for beryllium.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_NI; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for nickel.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_PD; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for polonium.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_PT; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for platinum.
|
|
extern const qpms_ldparams_t *const QPMS_LDPARAMS_W ; ///< Lorentz-Drude parameters from \cite rakic_optical_1998 for tungsten.
|
|
|
|
/// Lorentz-Drude permittivity.
|
|
complex double qpms_lorentzdrude_eps(complex double omega, const qpms_ldparams_t *);
|
|
|
|
/// Lorentz-Drude optical properties, with relative permeability set always to one.
|
|
qpms_epsmu_t qpms_lorentzdrude_epsmu(complex double omega, const qpms_ldparams_t *);
|
|
|
|
/// Lorentz-Drude optical properties, with relative permeability set always to one, compatible with qpms_epsmu_generator_t.
|
|
qpms_epsmu_t qpms_lorentzdrude_epsmu_g(
|
|
complex double omega,
|
|
const void *ldparams ///< Lorentz-Drude parameters, in reality const qpms_ldparams_t *.
|
|
);
|
|
|
|
|
|
/// Interpolator of tabulated optical properties.
|
|
// TODO use gsl_interp instead of gsl_spline.
|
|
typedef struct qpms_permittivity_interpolator_t {
|
|
double *wavelength_m; ///< Wavelength array (in meters).
|
|
double *n; ///< Refraction index array.
|
|
double *k; ///< Attenuation coefficient array.
|
|
gsl_interp *interp_n; ///< Refraction index interpolator object.
|
|
gsl_interp *interp_k; ///< Attenuation coeff interpolator object.
|
|
size_t size; ///< Size of n[], k[], and wavelength_m[].
|
|
// I could add gsl_interp_accel, but that is not necessary.
|
|
} qpms_permittivity_interpolator_t;
|
|
|
|
/// Creates a permittivity interpolator from tabulated wavelengths, refraction indices and extinction coeffs.
|
|
qpms_permittivity_interpolator_t *qpms_permittivity_interpolator_create(const size_t incount,
|
|
const double *wavelength_m, ///< Tabulated vacuum wavelength in metres, in strictly increasing order.
|
|
const double *n, ///< Tabulated refraction indices at omega.
|
|
const double *k, ///< Tabulated extinction coefficients.
|
|
const gsl_interp_type *iptype ///< GSL interpolator type
|
|
);
|
|
|
|
/// Creates a permittivity interpolator from an yml file downloaded from refractiveindex.info website.
|
|
qpms_permittivity_interpolator_t *qpms_permittivity_interpolator_from_yml(
|
|
const char *path, ///< Path to the yml file.
|
|
const gsl_interp_type *iptype ///< GSL interpolator type
|
|
);
|
|
|
|
/// Evaluates interpolated material permittivity at a given angular frequency.
|
|
complex double qpms_permittivity_interpolator_eps_at_omega(
|
|
const qpms_permittivity_interpolator_t *interp, double omega_SI);
|
|
|
|
/// Evaluates interpolated material permittivity at a given angular frequency, qpms_epsmu_generator_t compatible version.
|
|
/** Permeability is always set to one. Imaginary part of omega is discarded.
|
|
*/
|
|
qpms_epsmu_t qpms_permittivity_interpolator_epsmu_g(
|
|
complex double omega, ///< Angular frequency. The imaginary part is ignored!
|
|
const void * interpolator ///< Interpolator of type qpms_permittivity_interpolator_t
|
|
);
|
|
|
|
/// Returns the minimum angular frequency supported by the interpolator.
|
|
double qpms_permittivity_interpolator_omega_min(
|
|
const qpms_permittivity_interpolator_t *ip);
|
|
|
|
/// Returns the minimum angular frequency supported by the interpolator.
|
|
double qpms_permittivity_interpolator_omega_max(
|
|
const qpms_permittivity_interpolator_t *ip);
|
|
|
|
/// Destroy a permittivity interpolator.
|
|
void qpms_permittivity_interpolator_free(qpms_permittivity_interpolator_t *interp);
|
|
|
|
/// Relative permittivity from the Drude model.
|
|
static inline complex double qpms_drude_epsilon(
|
|
complex double eps_inf, ///< Relative permittivity "at infinity".
|
|
complex double omega_p, ///< Plasma frequency \f$ \omega_p \f$ of the material.
|
|
complex double gamma_p, ///< Decay constant \f$ \gamma_p \f$ of the material.
|
|
complex double omega ///< Frequency \f$ \omega \f$ at which the permittivity is evaluated.
|
|
) {
|
|
return eps_inf - omega_p*omega_p/(omega*(omega+I*gamma_p));
|
|
}
|
|
|
|
|
|
#endif //QPMS_MATERIALS_H
|