C Mie T-matrices but demand yet Bessel functions of complex arguments.
Former-commit-id: 101201f5d72ab0f45eefc09c860b65b6841460bf
This commit is contained in:
parent
2af9b83e35
commit
4475cffeba
|
@ -6,6 +6,7 @@
|
||||||
#include "kahansum.h"
|
#include "kahansum.h"
|
||||||
#include <gsl/gsl_sf_bessel.h>
|
#include <gsl/gsl_sf_bessel.h>
|
||||||
#include <complex.h>
|
#include <complex.h>
|
||||||
|
#include "qpms_error.h"
|
||||||
|
|
||||||
#ifndef M_LN2
|
#ifndef M_LN2
|
||||||
#define M_LN2 0.69314718055994530942 /* log_e 2 */
|
#define M_LN2 0.69314718055994530942 /* log_e 2 */
|
||||||
|
@ -16,7 +17,7 @@ static inline complex double ipow(int x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a big issue with gsl's precision of spherical bessel function; these have to be implemented differently
|
// There is a big issue with gsl's precision of spherical bessel function; these have to be implemented differently
|
||||||
qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, double x, complex double *result_array) {
|
qpms_errno_t qpms_sph_bessel_realx_fill(qpms_bessel_t typ, qpms_l_t lmax, double x, complex double *result_array) {
|
||||||
int retval;
|
int retval;
|
||||||
double tmparr[lmax+1];
|
double tmparr[lmax+1];
|
||||||
switch(typ) {
|
switch(typ) {
|
||||||
|
@ -49,6 +50,14 @@ qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, double x, co
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, complex double x, complex double *result_array) {
|
||||||
|
int retval = qpms_sph_bessel_realx_fill(typ, lmax, creal(x), result_array);
|
||||||
|
if(!cimag(x))
|
||||||
|
return retval;
|
||||||
|
else
|
||||||
|
QPMS_NOT_IMPLEMENTED("complex argument of Bessel function.");
|
||||||
|
}
|
||||||
|
|
||||||
static inline ptrdiff_t akn_index(qpms_l_t n, qpms_l_t k) {
|
static inline ptrdiff_t akn_index(qpms_l_t n, qpms_l_t k) {
|
||||||
assert(k <= n);
|
assert(k <= n);
|
||||||
return ((ptrdiff_t) n + 1) * n / 2 + k;
|
return ((ptrdiff_t) n + 1) * n / 2 + k;
|
||||||
|
|
|
@ -1131,8 +1131,11 @@ cdef class CTMatrix: # N.B. there is another type called TMatrix in tmatrices.py
|
||||||
def __cinit__(CTMatrix self, BaseSpec spec, matrix):
|
def __cinit__(CTMatrix self, BaseSpec spec, matrix):
|
||||||
self.spec = spec
|
self.spec = spec
|
||||||
self.t.spec = self.spec.rawpointer();
|
self.t.spec = self.spec.rawpointer();
|
||||||
# The following will raise an exception if shape is wrong
|
if matrix is None or matrix == 0:
|
||||||
self.m = np.array(matrix, dtype=complex, copy=True, order='C').reshape((len(spec), len(spec)))
|
self.m = np.zeros((len(spec),len(spec)), dtype=complex, order='C')
|
||||||
|
else:
|
||||||
|
# The following will raise an exception if shape is wrong
|
||||||
|
self.m = np.array(matrix, dtype=complex, copy=True, order='C').reshape((len(spec), len(spec)))
|
||||||
#self.m.setflags(write=False) # checkme
|
#self.m.setflags(write=False) # checkme
|
||||||
cdef cdouble[:,:] m_memview = self.m
|
cdef cdouble[:,:] m_memview = self.m
|
||||||
self.t.m = &(m_memview[0,0])
|
self.t.m = &(m_memview[0,0])
|
||||||
|
@ -1158,6 +1161,19 @@ cdef class CTMatrix: # N.B. there is another type called TMatrix in tmatrices.py
|
||||||
# Maybe not totally needed after all, as np.array(T[...]) should be equivalent and not longer
|
# Maybe not totally needed after all, as np.array(T[...]) should be equivalent and not longer
|
||||||
return np.array(self.m, copy=True)
|
return np.array(self.m, copy=True)
|
||||||
|
|
||||||
|
def spherical_fill(CTMatrix self, double radius, cdouble k_int,
|
||||||
|
cdouble k_ext, cdouble mu_int = 1, cdouble mu_ext = 1):
|
||||||
|
''' Replaces the contents of the T-matrix with those of a spherical particle. '''
|
||||||
|
qpms_tmatrix_spherical_fill(&self.t, radius, k_int, k_ext, mu_int, mu_ext)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def spherical(BaseSpec spec, double radius, cdouble k_int, cdouble k_ext,
|
||||||
|
cdouble mu_int = 1, cdouble mu_ext = 1):
|
||||||
|
''' Creates a T-matrix of a spherical nanoparticle. '''
|
||||||
|
tm = CTMatrix(spec, 0)
|
||||||
|
tm.spherical_fill(radius, k_int, k_ext, mu_int, mu_ext)
|
||||||
|
return tm
|
||||||
|
|
||||||
cdef char *make_c_string(pythonstring):
|
cdef char *make_c_string(pythonstring):
|
||||||
'''
|
'''
|
||||||
Copies contents of a python string into a char[]
|
Copies contents of a python string into a char[]
|
||||||
|
|
|
@ -38,6 +38,12 @@ cdef extern from "qpms_types.h":
|
||||||
QPMS_NORMALISATION_SPHARM
|
QPMS_NORMALISATION_SPHARM
|
||||||
QPMS_NORMALISATION_SPHARM_CS
|
QPMS_NORMALISATION_SPHARM_CS
|
||||||
QPMS_NORMALISATION_UNDEF
|
QPMS_NORMALISATION_UNDEF
|
||||||
|
ctypedef enum qpms_bessel_t:
|
||||||
|
QPMS_BESSEL_REGULAR
|
||||||
|
QPMS_BESSEL_SINGULAR
|
||||||
|
QPMS_HANKEL_PLUS
|
||||||
|
QPMS_HANKEL_MINUS
|
||||||
|
QPMS_HANKEL_UNDEF
|
||||||
ctypedef int qpms_lm_t
|
ctypedef int qpms_lm_t
|
||||||
ctypedef int qpms_l_t
|
ctypedef int qpms_l_t
|
||||||
ctypedef int qpms_m_t
|
ctypedef int qpms_m_t
|
||||||
|
@ -258,6 +264,12 @@ cdef extern from "tmatrices.h":
|
||||||
qpms_errno_t qpms_load_scuff_tmatrix(const char *path, const qpms_vswf_set_spec_t *bspec,
|
qpms_errno_t qpms_load_scuff_tmatrix(const char *path, const qpms_vswf_set_spec_t *bspec,
|
||||||
size_t *n, double **freqs, double **freqs_su, qpms_tmatrix_t **tmatrices_array,
|
size_t *n, double **freqs, double **freqs_su, qpms_tmatrix_t **tmatrices_array,
|
||||||
cdouble **tmdata)
|
cdouble **tmdata)
|
||||||
|
cdouble *qpms_mie_coefficients_reflection(cdouble *target, const qpms_vswf_set_spec_t *bspec,
|
||||||
|
double a, cdouble k_i, cdouble k_e, cdouble mu_i, cdouble mu_e, qpms_bessel_t J_ext, qpms_bessel_t J_scat)
|
||||||
|
qpms_errno_t qpms_tmatrix_spherical_fill(qpms_tmatrix_t *t, double a,
|
||||||
|
cdouble k_i, cdouble k_e, cdouble mu_i, cdouble mu_e)
|
||||||
|
qpms_tmatrix_t *qpms_tmatrix_spherical(const qpms_vswf_set_spec_t *bspec,
|
||||||
|
double a, cdouble k_i, cdouble k_e, cdouble mu_i, cdouble mu_e)
|
||||||
|
|
||||||
cdef extern from "scatsystem.h":
|
cdef extern from "scatsystem.h":
|
||||||
struct qpms_particle_t:
|
struct qpms_particle_t:
|
||||||
|
|
|
@ -29,4 +29,7 @@ void qpms_pr_debug_at_flf(const char *filename, unsigned int linenum,
|
||||||
|
|
||||||
#define QPMS_ENSURE(x, msg, ...) {if(!(x)) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__); }
|
#define QPMS_ENSURE(x, msg, ...) {if(!(x)) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__); }
|
||||||
|
|
||||||
|
#define QPMS_NOT_IMPLEMENTED(msg, ...) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__, \
|
||||||
|
"Not implemented:" msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
// TODO unify types
|
// TODO unify types
|
||||||
qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, double x, complex double *result_array);
|
qpms_errno_t qpms_sph_bessel_fill(qpms_bessel_t typ, qpms_l_t lmax, complex double x, complex double *result_array);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "qpms_error.h"
|
#include "qpms_error.h"
|
||||||
#include "tmatrices.h"
|
#include "tmatrices.h"
|
||||||
|
#include "qpms_specfunc.h"
|
||||||
|
|
||||||
#define HBAR (1.05457162825e-34)
|
#define HBAR (1.05457162825e-34)
|
||||||
#define ELECTRONVOLT (1.602176487e-19)
|
#define ELECTRONVOLT (1.602176487e-19)
|
||||||
|
@ -314,16 +315,21 @@ void qpms_tmatrix_interpolator_free(qpms_tmatrix_interpolator_t *ip) {
|
||||||
|
|
||||||
qpms_tmatrix_t *qpms_tmatrix_interpolator_eval(const qpms_tmatrix_interpolator_t *ip, double freq) {
|
qpms_tmatrix_t *qpms_tmatrix_interpolator_eval(const qpms_tmatrix_interpolator_t *ip, double freq) {
|
||||||
qpms_tmatrix_t *t = qpms_tmatrix_init(ip->bspec);
|
qpms_tmatrix_t *t = qpms_tmatrix_init(ip->bspec);
|
||||||
|
QPMS_ENSURE_SUCCESS(qpms_tmatrix_interpolator_eval_fill(t, ip, freq));
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
qpms_errno_t qpms_tmatrix_interpolator_eval_fill(qpms_tmatrix_t *t,
|
||||||
|
const qpms_tmatrix_interpolator_t *ip, double freq) {
|
||||||
|
QPMS_ENSURE(qpms_vswf_set_spec_isidentical(t->spec, ip->bspec), "Tried to fill a T-matrix with an incompatible interpolator!");
|
||||||
const size_t n = ip->bspec->n;
|
const size_t n = ip->bspec->n;
|
||||||
for (size_t i = 0; i < n*n; ++i){
|
for (size_t i = 0; i < n*n; ++i){
|
||||||
if (ip->splines_real[i]) t->m[i] = gsl_spline_eval(ip->splines_real[i], freq, NULL /*does this work?*/);
|
if (ip->splines_real[i]) t->m[i] = gsl_spline_eval(ip->splines_real[i], freq, NULL /*does this work?*/);
|
||||||
if (ip->splines_imag[i]) t->m[i] += I* gsl_spline_eval(ip->splines_imag[i], freq, NULL /*does this work?*/);
|
if (ip->splines_imag[i]) t->m[i] += I* gsl_spline_eval(ip->splines_imag[i], freq, NULL /*does this work?*/);
|
||||||
}
|
}
|
||||||
return t;
|
return QPMS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double qpms_SU2eV(double e_SU) {
|
double qpms_SU2eV(double e_SU) {
|
||||||
return e_SU * SCUFF_OMEGAUNIT / (ELECTRONVOLT / HBAR);
|
return e_SU * SCUFF_OMEGAUNIT / (ELECTRONVOLT / HBAR);
|
||||||
}
|
}
|
||||||
|
@ -454,3 +460,82 @@ qpms_errno_t qpms_load_scuff_tmatrix(
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
complex double *qpms_mie_coefficients_reflection(
|
||||||
|
complex double *target, ///< Target array of length bspec->n. If NULL, a new one will be allocated.
|
||||||
|
const qpms_vswf_set_spec_t *bspec, ///< Defines which of the coefficients are calculated.
|
||||||
|
double a, ///< Radius of the sphere.
|
||||||
|
complex double k_i, ///< Wave number of the internal material of the sphere.
|
||||||
|
complex double k_e, ///< Wave number of the surrounding medium.
|
||||||
|
complex double mu_i, ///< Relative permeability of the sphere material.
|
||||||
|
complex double mu_e, ///< Relative permeability of the surrounding medium.
|
||||||
|
qpms_bessel_t J_ext,
|
||||||
|
qpms_bessel_t J_scat
|
||||||
|
// TODO J_ext, J_scat?
|
||||||
|
) {
|
||||||
|
/*
|
||||||
|
* This implementation pretty much copies mie_coefficients() from qpms_p.py, so
|
||||||
|
* any bugs there should affect this function as well and perhaps vice versa.
|
||||||
|
*/
|
||||||
|
QPMS_ENSURE(J_ext != J_scat, "J_ext and J_scat must not be equal. Perhaps you want J_ext = 1 and J_scat = 3 anyways.");
|
||||||
|
if (!target) QPMS_CRASHING_MALLOC(target, bspec->n * sizeof(complex double));
|
||||||
|
qpms_l_t lMax = bspec->lMax;
|
||||||
|
complex double x_i = k_i * a;
|
||||||
|
complex double x_e = k_e * a;
|
||||||
|
complex double m = k_i / k_e;
|
||||||
|
complex double eta_inv_i = k_i / mu_i;
|
||||||
|
complex double eta_inv_e = k_e / mu_e;
|
||||||
|
|
||||||
|
complex double zi[lMax + 2];
|
||||||
|
complex double ze[lMax + 2];
|
||||||
|
complex double zs[lMax + 2];
|
||||||
|
complex double RH[lMax + 1] /* MAGNETIC */, RV[lMax+1] /* ELECTRIC */;
|
||||||
|
QPMS_ENSURE_SUCCESS(qpms_sph_bessel_fill(QPMS_BESSEL_REGULAR, lMax+1, x_i, zi));
|
||||||
|
QPMS_ENSURE_SUCCESS(qpms_sph_bessel_fill(J_ext, lMax+1, x_e, ze));
|
||||||
|
QPMS_ENSURE_SUCCESS(qpms_sph_bessel_fill(J_scat, lMax+1, x_e, zs));
|
||||||
|
for (qpms_l_t l = 0; l <= lMax; ++l) {
|
||||||
|
// Bessel function derivatives as in DLMF 10.51.2
|
||||||
|
complex double dzi = -zi[l+1] + l/x_i*zi[l];
|
||||||
|
complex double dze = -ze[l+1] + l/x_e*ze[l];
|
||||||
|
complex double dzs = -zs[l+1] + l/x_e*zs[l];
|
||||||
|
complex double fi = zi[l]/x_i+dzi;
|
||||||
|
complex double fs = zs[l]/x_e+dzs;
|
||||||
|
complex double fe = ze[l]/x_e+dze;
|
||||||
|
RV[l] = -((-eta_inv_i * fe * zi[l] + eta_inv_e * ze[l] * fi)/(-eta_inv_e * fi * zs[l] + eta_inv_i * zi[l] * fs));
|
||||||
|
RH[l] = -((-eta_inv_e * fe * zi[l] + eta_inv_i * ze[l] * fi)/(-eta_inv_i * fi * zs[l] + eta_inv_e * zi[l] * fs));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < bspec->n; ++i) {
|
||||||
|
qpms_l_t l; qpms_m_t m; qpms_vswf_type_t t;
|
||||||
|
QPMS_ENSURE_SUCCESS(qpms_uvswfi2tmn(bspec->ilist[i], &t, &m, &l));
|
||||||
|
assert(l <= lMax);
|
||||||
|
switch(t) {
|
||||||
|
case QPMS_VSWF_ELECTRIC:
|
||||||
|
target[i] = RV[l];
|
||||||
|
break;
|
||||||
|
case QPMS_VSWF_MAGNETIC:
|
||||||
|
target[i] = RH[l];
|
||||||
|
break;
|
||||||
|
default: QPMS_WTF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replaces the contents of an existing T-matrix with that of a spherical nanoparticle calculated using the Lorentz-mie theory.
|
||||||
|
qpms_errno_t qpms_tmatrix_spherical_fill(qpms_tmatrix_t *t, ///< T-matrix whose contents are to be replaced. Not NULL.
|
||||||
|
double a, ///< Radius of the sphere.
|
||||||
|
complex double k_i, ///< Wave number of the internal material of the sphere.
|
||||||
|
complex double k_e, ///< Wave number of the surrounding medium.
|
||||||
|
complex double mu_i, ///< Relative permeability of the sphere material.
|
||||||
|
complex double mu_e ///< Relative permeability of the surrounding medium.
|
||||||
|
) {
|
||||||
|
qpms_l_t lMax = t->spec->lMax;
|
||||||
|
complex double *miecoeffs = qpms_mie_coefficients_reflection(NULL, t->spec, a, k_i, k_e, mu_i, mu_e,
|
||||||
|
QPMS_BESSEL_REGULAR, QPMS_HANKEL_PLUS);
|
||||||
|
memset(t->m, 0, SQ(t->spec->n));
|
||||||
|
for(size_t i = 0; i < t->spec->n; ++i)
|
||||||
|
t->m[t->spec->n*i + i] = miecoeffs[i];
|
||||||
|
free(miecoeffs);
|
||||||
|
return QPMS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,10 @@ typedef struct qpms_tmatrix_interpolator_t {
|
||||||
/// Free a T-matrix interpolator.
|
/// Free a T-matrix interpolator.
|
||||||
void qpms_tmatrix_interpolator_free(qpms_tmatrix_interpolator_t *interp);
|
void qpms_tmatrix_interpolator_free(qpms_tmatrix_interpolator_t *interp);
|
||||||
|
|
||||||
|
/// Fills an existing T-matrix with new interpolated values.
|
||||||
|
qpms_errno_t qpms_tmatrix_interpolator_eval_fill(qpms_tmatrix_t *target, ///< T-matrix to be updated, not NULL.
|
||||||
|
const qpms_tmatrix_interpolator_t *interp, double freq);
|
||||||
|
|
||||||
/// Evaluate a T-matrix interpolated value.
|
/// Evaluate a T-matrix interpolated value.
|
||||||
/** The result is to be freed using qpms_tmatrix_free().*/
|
/** The result is to be freed using qpms_tmatrix_free().*/
|
||||||
qpms_tmatrix_t *qpms_tmatrix_interpolator_eval(const qpms_tmatrix_interpolator_t *interp, double freq);
|
qpms_tmatrix_t *qpms_tmatrix_interpolator_eval(const qpms_tmatrix_interpolator_t *interp, double freq);
|
||||||
|
@ -244,6 +248,63 @@ qpms_tmatrix_interpolator_t *qpms_tmatrix_interpolator_create(size_t n, ///< Num
|
||||||
//, bool copy_bspec ///< if true, copies its own copy of basis spec from the first T-matrix.
|
//, bool copy_bspec ///< if true, copies its own copy of basis spec from the first T-matrix.
|
||||||
/*, ...? */);
|
/*, ...? */);
|
||||||
|
|
||||||
|
/// Calculates the reflection Mie-Lorentz coefficients for a spherical particle.
|
||||||
|
/**
|
||||||
|
* This function is based on the previous python implementation mie_coefficients() from qpms_p.py,
|
||||||
|
* so any bugs therein should affect this function as well and perhaps vice versa.
|
||||||
|
*
|
||||||
|
* Most importantly, the case of magnetic material, \a mu_i != 0 or \a mu_e != 0 has never been tested
|
||||||
|
* and might give wrong results.
|
||||||
|
*
|
||||||
|
* \return Array with the Mie-Lorentz reflection coefficients in the order determined by bspec.
|
||||||
|
* If \a target was not NULL, this is target, otherwise a newly allocated array.
|
||||||
|
*
|
||||||
|
* TODO better doc.
|
||||||
|
*/
|
||||||
|
complex double *qpms_mie_coefficients_reflection(
|
||||||
|
complex double *target, ///< Target array of length bspec->n. If NULL, a new one will be allocated.
|
||||||
|
const qpms_vswf_set_spec_t *bspec, ///< Defines which of the coefficients are calculated.
|
||||||
|
double a, ///< Radius of the sphere.
|
||||||
|
complex double k_i, ///< Wave number of the internal material of the sphere.
|
||||||
|
complex double k_e, ///< Wave number of the surrounding medium.
|
||||||
|
complex double mu_i, ///< Relative permeability of the sphere material.
|
||||||
|
complex double mu_e, ///< Relative permeability of the surrounding medium.
|
||||||
|
qpms_bessel_t J_ext, ///< Kind of the "incoming" waves. Most likely QPMS_BESSEL_REGULAR.
|
||||||
|
qpms_bessel_t J_scat ///< Kind of the "scattered" waves. Most likely QPMS_HANKEL_PLUS.
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Replaces the contents of an existing T-matrix with that of a spherical nanoparticle calculated using the Lorentz-mie theory.
|
||||||
|
qpms_errno_t qpms_tmatrix_spherical_fill(qpms_tmatrix_t *t, ///< T-matrix whose contents are to be replaced. Not NULL.
|
||||||
|
double a, ///< Radius of the sphere.
|
||||||
|
complex double k_i, ///< Wave number of the internal material of the sphere.
|
||||||
|
complex double k_e, ///< Wave number of the surrounding medium.
|
||||||
|
complex double mu_i, ///< Relative permeability of the sphere material.
|
||||||
|
complex double mu_e ///< Relative permeability of the surrounding medium.
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Creates a new T-matrix of a spherical particle using the Lorentz-Mie theory.
|
||||||
|
static inline qpms_tmatrix_t *qpms_tmatrix_spherical(
|
||||||
|
const qpms_vswf_set_spec_t *bspec,
|
||||||
|
double a, ///< Radius of the sphere.
|
||||||
|
complex double k_i, ///< Wave number of the internal material of the sphere.
|
||||||
|
complex double k_e, ///< Wave number of the surrounding medium.
|
||||||
|
complex double mu_i, ///< Relative permeability of the sphere material.
|
||||||
|
complex double mu_e ///< Relative permeability of the surrounding medium.
|
||||||
|
) {
|
||||||
|
qpms_tmatrix_t *t = qpms_tmatrix_init(bspec);
|
||||||
|
qpms_tmatrix_spherical_fill(t, a, k_i, k_e, mu_i, mu_e);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Relative permittivity from the Drude model.
|
||||||
|
static inline complex double qpms_drude_epsilon(
|
||||||
|
complex double eps_inf, ///< Permittivity at
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Abstract types that describe T-matrix/particle/scatsystem symmetries
|
// Abstract types that describe T-matrix/particle/scatsystem symmetries
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# In[1]:
|
||||||
|
|
||||||
|
|
||||||
|
from qpms import *
|
||||||
|
|
||||||
|
|
||||||
|
# In[6]:
|
||||||
|
|
||||||
|
|
||||||
|
R = 40e-9
|
||||||
|
ω_p = 9*eV/ℏ #9*eV/ℏ
|
||||||
|
ε_inf = 4.6
|
||||||
|
γ_p = 0.1*eV/ℏ
|
||||||
|
ε_b = 2.13
|
||||||
|
lMax = 3
|
||||||
|
|
||||||
|
ω = 1.5*eV/ℏ
|
||||||
|
|
||||||
|
|
||||||
|
# In[7]:
|
||||||
|
|
||||||
|
|
||||||
|
ε_m = ε_drude(ε_inf, ω_p, γ_p, ω)
|
||||||
|
|
||||||
|
|
||||||
|
# In[9]:
|
||||||
|
|
||||||
|
|
||||||
|
k_i = cmath.sqrt(ε_m)*ω/c
|
||||||
|
k_e = cmath.sqrt(ε_b)*ω/c
|
||||||
|
RH, RV, TH, TV = mie_coefficients(a=R, nmax=lMax, k_i=k_i, k_e=k_e, J_ext=1, J_scat=3)
|
||||||
|
|
||||||
|
|
||||||
|
# In[11]:
|
||||||
|
|
||||||
|
|
||||||
|
spec = BaseSpec(lMax=lMax)
|
||||||
|
cT = CTMatrix.spherical(spec, R, k_i, k_e, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
# In[16]:
|
||||||
|
|
||||||
|
|
||||||
|
print(np.diag(cT[...]))
|
||||||
|
|
||||||
|
|
||||||
|
# In[18]:
|
||||||
|
|
||||||
|
|
||||||
|
print(RV)
|
||||||
|
print(RH)
|
||||||
|
|
||||||
|
|
||||||
|
# In[ ]:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue