WIP T-matrix generators debugging

Former-commit-id: e3708a28b1fe62522fa45527452d2aa1c37bca49
This commit is contained in:
Marek Nečada 2019-08-12 11:18:25 +03:00
parent 8ec697a1dc
commit 82337ca07f
5 changed files with 34 additions and 14 deletions

View File

@ -5,7 +5,7 @@ from .qpms_c import PointGroup, FinitePointGroup, FinitePointGroupElement, Parti
from .qpms_p import * from .qpms_p import *
from .cyquaternions import CQuat, IRot3 from .cyquaternions import CQuat, IRot3
from .cybspec import VSWFNorm, BaseSpec from .cybspec import VSWFNorm, BaseSpec
from .cytmatrices import CTMatrix, TMatrixInterpolator from .cytmatrices import CTMatrix, TMatrixInterpolator, TMatrixGenerator
from .cytranslations import trans_calculator from .cytranslations import trans_calculator
from .cymaterials import MaterialInterpolator, EpsMu, LorentzDrudeModel, lorentz_drude, EpsMuGenerator from .cymaterials import MaterialInterpolator, EpsMu, LorentzDrudeModel, lorentz_drude, EpsMuGenerator
from .cycommon import dbgmsg_enable, dbgmsg_disable, dbgmsg_active, BesselType from .cycommon import dbgmsg_enable, dbgmsg_disable, dbgmsg_active, BesselType

View File

@ -231,7 +231,7 @@ cdef class TMatrixGenerator:
raise ValueError("Something went wrong") raise ValueError("Something went wrong")
return return
elif isinstance(arg, BaseSpec): # Make a new CTMatrix elif isinstance(arg, BaseSpec): # Make a new CTMatrix
tm = CTMatrix(bspec, None) tm = CTMatrix(arg, None)
if self.g.function(tm.rawpointer(), omega, self.g.params) != 0: if self.g.function(tm.rawpointer(), omega, self.g.params) != 0:
raise ValueError("Something went wrong") raise ValueError("Something went wrong")
return tm return tm
@ -243,12 +243,14 @@ cdef class TMatrixGenerator:
def sphere(outside, inside, r): def sphere(outside, inside, r):
return TMatrixGenerator(__MieParams(EpsMuGenerator(outside), return TMatrixGenerator(__MieParams(EpsMuGenerator(outside),
EpsMuGenerator(inside), r)) EpsMuGenerator(inside), r))
@staticmethod
def sphere_asarc(outside, inside, r, *args, **kwargs):
return TMatrixGenerator(__AxialSymParams(
EpsMuGenerator(outside), EpsMuGenerator(inside),
ArcFunction(__ArcSphere(r)), *args, **kwargs))
@staticmethod
def cylinder(outside, inside, r, h, *args, **kwargs): def cylinder(outside, inside, r, h, *args, **kwargs):
return TMatrixGenerator(__AxialSymParams( return TMatrixGenerator(__AxialSymParams(
EpsMuGenerator(outside), EpsMuGenerator(inside), EpsMuGenerator(outside), EpsMuGenerator(inside),
ArcFunction(__ArcCylinder(r, h)), *args, **kwargs)) ArcFunction(__ArcCylinder(r, h)), *args, **kwargs))
def sphere_asarc(outside, inside, r, h, *args, **kwargs):
return TMatrixGenerator(__AxialSymParams(
EpsMuGenerator(outside), EpsMuGenerator(inside),
ArcFunction(__ArcSphere(r)), *args, **kwargs))

View File

@ -26,8 +26,8 @@
#include <gsl/gsl_integration.h> #include <gsl/gsl_integration.h>
// These are quite arbitrarily chosen constants for the quadrature in qpms_tmatrix_axialsym_fill() // These are quite arbitrarily chosen constants for the quadrature in qpms_tmatrix_axialsym_fill()
#define TMATRIX_AXIALSYM_INTEGRAL_EPSREL (1e-6) #define TMATRIX_AXIALSYM_INTEGRAL_EPSREL (1e-5)
#define TMATRIX_AXIALSYM_INTEGRAL_EPSABS (1e-10) #define TMATRIX_AXIALSYM_INTEGRAL_EPSABS (1e-8)
#define HBAR (1.05457162825e-34) #define HBAR (1.05457162825e-34)
#define ELECTRONVOLT (1.602176487e-19) #define ELECTRONVOLT (1.602176487e-19)
@ -511,6 +511,8 @@ complex double *qpms_mie_coefficients_reflection(
/* /*
* This implementation pretty much copies mie_coefficients() from qpms_p.py, so * 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. * any bugs there should affect this function as well and perhaps vice versa.
*
* Compared to mie_coefficients() from qpms_p.py, this has opposite sign.
*/ */
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."); 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)); if (!target) QPMS_CRASHING_MALLOC(target, bspec->n * sizeof(complex double));
@ -536,8 +538,8 @@ complex double *qpms_mie_coefficients_reflection(
complex double fi = zi[l]/x_i+dzi; complex double fi = zi[l]/x_i+dzi;
complex double fs = zs[l]/x_e+dzs; complex double fs = zs[l]/x_e+dzs;
complex double fe = ze[l]/x_e+dze; 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)); 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)); 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) { for (size_t i = 0; i < bspec->n; ++i) {
@ -701,6 +703,7 @@ qpms_errno_t qpms_tmatrix_axialsym_fill(
p.z = qpms_waveimpedance(outside); p.z = qpms_waveimpedance(outside);
p.z_in = qpms_waveimpedance(inside); p.z_in = qpms_waveimpedance(inside);
p.f = shape; p.f = shape;
p.bspec = bspec;
const gsl_function f = {tmatrix_axialsym_integrand, (void *) &p}; const gsl_function f = {tmatrix_axialsym_integrand, (void *) &p};
if (lMaxQR < bspec->lMax) lMaxQR = bspec->lMax; if (lMaxQR < bspec->lMax) lMaxQR = bspec->lMax;
@ -721,6 +724,7 @@ qpms_errno_t qpms_tmatrix_axialsym_fill(
for(size_t i2 = 0; i2 < bspecQR->n; ++i2) { for(size_t i2 = 0; i2 < bspecQR->n; ++i2) {
// NOTE that the Q', R' matrices are !TRANSPOSED! here because of zgetrs // NOTE that the Q', R' matrices are !TRANSPOSED! here because of zgetrs
const size_t iQR = i1 + i2 * bspecQR->n; const size_t iQR = i1 + i2 * bspecQR->n;
double abserr; // gsl_integration_qag() needs this; thrown away for now
qpms_m_t m1, m2; qpms_m_t m1, m2;
qpms_l_t l1, l2; qpms_l_t l1, l2;
qpms_vswf_type_t t1, t2; qpms_vswf_type_t t1, t2;
@ -740,26 +744,26 @@ qpms_errno_t qpms_tmatrix_axialsym_fill(
p.btype = QPMS_BESSEL_REGULAR; p.btype = QPMS_BESSEL_REGULAR;
p.realpart = true; p.realpart = true;
QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel, QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel,
intlimit, 2, w, &result, NULL)); intlimit, 2, w, &result, &abserr));
R[iQR] = result; R[iQR] = result;
// Im(R') // Im(R')
p.realpart = false; p.realpart = false;
QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel, QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel,
intlimit, 2, w, &result, NULL)); intlimit, 2, w, &result, &abserr));
R[iQR] += I*result; R[iQR] += I*result;
// Re(Q') // Re(Q')
p.btype = QPMS_HANKEL_PLUS; p.btype = QPMS_HANKEL_PLUS;
p.realpart = true; p.realpart = true;
QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel, QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel,
intlimit, 2, w, &result, NULL)); intlimit, 2, w, &result, &abserr));
Q[iQR] = result; Q[iQR] = result;
// Im(Q') // Im(Q')
p.realpart = false; p.realpart = false;
QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel, QPMS_ENSURE_SUCCESS(gsl_integration_qag(&f, 0, M_PI, epsabs, epsrel,
intlimit, 2, w, &result, NULL)); intlimit, 2, w, &result, &abserr));
Q[iQR] += I*result; Q[iQR] += I*result;
} }
} }

View File

@ -435,6 +435,11 @@ qpms_arc_function_retval_t qpms_arc_sphere(double theta,
/// Replaces T-matrix contents with those of a particle with \f$ C_\infty \f$ symmetry. /// Replaces T-matrix contents with those of a particle with \f$ C_\infty \f$ symmetry.
/**
* N.B. currently, this might crash for higher values of lMax (lMax > 5).
* Also, it seems that I am doing something wrong, as the result is accurate for sphere
* with lMax = 1 and for higher l the accuracy decreases.
*/
qpms_errno_t qpms_tmatrix_axialsym_fill( qpms_errno_t qpms_tmatrix_axialsym_fill(
qpms_tmatrix_t *t, ///< T-matrix whose contents are to be replaced. Not NULL. qpms_tmatrix_t *t, ///< T-matrix whose contents are to be replaced. Not NULL.
complex double omega, ///< Angular frequency. complex double omega, ///< Angular frequency.

9
tests/tmatrixgens.py Normal file
View File

@ -0,0 +1,9 @@
from qpms import *
lMax = 3
spec = BaseSpec(lMax=lMax)
ω = 1.5*eV/
gensphere_arc = TMatrixGenerator.sphere_asarc(outside=EpsMu(2.3104,1), inside=lorentz_drude['Au'], r=50e-9)
np.diag(gensphere_arc(spec,ω)[...])