From c3831eec52748ab24e7234347c3a680ef8124034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Thu, 8 Aug 2019 17:49:45 +0300 Subject: [PATCH] General optical property generator prototype for isotropic materials. Former-commit-id: 327109fe99334febe5a69c9028113555a0c89dba --- qpms/drudeparam_data.c | 24 ++++++++++++------------ qpms/materials.c | 30 +++++++++++++++++++++++++++--- qpms/materials.h | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 73 insertions(+), 18 deletions(-) diff --git a/qpms/drudeparam_data.c b/qpms/drudeparam_data.c index 1516dd7..b513fc2 100644 --- a/qpms/drudeparam_data.c +++ b/qpms/drudeparam_data.c @@ -10,12 +10,12 @@ static const qpms_ldparams_t LDPARAMS_AU = { 9.03*EH, // omega_p 6, // n { - {0.76 *EH, 0. *EH, 0.053*EH}, - {0.024*EH, 0.415*EH, 0.241*EH}, - {0.01 *EH, 0.83 *EH, 0.345*EH}, - {0.071*EH, 2.969*EH, 0.87 *EH}, - {0.601*EH, 4.304*EH, 2.494*EH}, - {4.384*EH, 13.32 *EH, 2.214*EH} + {0.76 , 0. *EH, 0.053*EH}, + {0.024, 0.415*EH, 0.241*EH}, + {0.01 , 0.83 *EH, 0.345*EH}, + {0.071, 2.969*EH, 0.87 *EH}, + {0.601, 4.304*EH, 2.494*EH}, + {4.384, 13.32 *EH, 2.214*EH} } }; @@ -26,12 +26,12 @@ static const qpms_ldparams_t LDPARAMS_AG = { 9.01*EH, // omega_p 6, // n { - {0.84 *EH, 0. *EH, 0.053*EH}, - {0.065*EH, 0.816*EH, 3.886*EH}, - {0.124*EH, 4.481*EH, 0.452*EH}, - {0.111*EH, 8.185*EH, 0.065*EH}, - {0.84 *EH, 9.083*EH, 0.916*EH}, - {5.646*EH, 20.29 *EH, 2.419*EH} + {0.84 , 0. *EH, 0.053*EH}, + {0.065, 0.816*EH, 3.886*EH}, + {0.124, 4.481*EH, 0.452*EH}, + {0.111, 8.185*EH, 0.065*EH}, + {0.84 , 9.083*EH, 0.916*EH}, + {5.646, 20.29 *EH, 2.419*EH} } }; diff --git a/qpms/materials.c b/qpms/materials.c index 8905fc9..1f591c2 100644 --- a/qpms/materials.c +++ b/qpms/materials.c @@ -128,6 +128,19 @@ complex double qpms_permittivity_interpolator_eps_at_omega( return epsilon; } +qpms_epsmu_t qpms_permittivity_interpolator_epsmu_g( + complex double omega, const void *p) +{ + const qpms_permittivity_interpolator_t *interp = p; + static bool imag_already_bitched = false; + if(cimag(omega) && !imag_already_bitched) + QPMS_WARN("Complex frequencies not supported by qpms_permittivity_interpolator_t. Imaginary parts will be discarded!"); + qpms_epsmu_t em; + em.eps = qpms_permittivity_interpolator_eps_at_omega(interp, omega); + em.mu = 1; + return em; +} + double qpms_permittivity_interpolator_omega_max( const qpms_permittivity_interpolator_t *ip) { @@ -140,7 +153,8 @@ double qpms_permittivity_interpolator_omega_min( return 2*M_PI*SPEED_OF_LIGHT / ip->wavelength_m[ip->size-1]; } -complex double qpms_lorentzdrude_eps(const qpms_ldparams_t *p, complex double omega) { +complex double qpms_lorentzdrude_eps(complex double omega, const qpms_ldparams_t *p) +{ complex double eps = 0; for(size_t j = 0; j < p->n; ++j) { const qpms_ldparams_triple_t d = p->data[j]; @@ -149,10 +163,20 @@ complex double qpms_lorentzdrude_eps(const qpms_ldparams_t *p, complex double om return eps; } -qpms_epsmu_t qpms_lorentzdrude_epsmu(const qpms_ldparams_t *p, complex double omega) { +qpms_epsmu_t qpms_lorentzdrude_epsmu(complex double omega, const qpms_ldparams_t *p) +{ qpms_epsmu_t em; - em.eps = qpms_lorentzdrude_eps(p, omega); + em.eps = qpms_lorentzdrude_eps(omega, p); em.mu = 1; return em; } +qpms_epsmu_t qpms_lorentzdrude_epsmu_g(complex double omega, const void *p) +{ + return qpms_lorentzdrude_epsmu(omega, (const qpms_ldparams_t *)p); +} + +qpms_epsmu_t qpms_epsmu_const_g(complex double omega, const void *p) +{ + return *(const qpms_epsmu_t *)p; +} diff --git a/qpms/materials.h b/qpms/materials.h index 8fecb36..ce4e34f 100644 --- a/qpms/materials.h +++ b/qpms/materials.h @@ -12,6 +12,23 @@ #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; + +/// 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) { @@ -30,7 +47,7 @@ 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 for qpms_ldparams_t. +/// A \f$ (f_j, \omega_j, \gamma_j) \f$ triple for qpms_ldparams_t. typedef struct qpms_ldparams_triple_t { double f; double omega; @@ -54,10 +71,16 @@ extern const qpms_ldparams_t *const QPMS_LDPARAMS_AG; ///< Lorentz-Drude paramet extern const qpms_ldparams_t *const QPMS_LDPARAMS_AU; ///< Lorentz-Drude parameters for gold. /// Lorentz-Drude permittivity. -complex double qpms_lorentzdrude_eps(const qpms_ldparams_t *, complex double omega); +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(const qpms_ldparams_t *, complex double omega); +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. @@ -90,6 +113,14 @@ qpms_permittivity_interpolator_t *qpms_permittivity_interpolator_from_yml( 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);