From 18767faa03c73319355210bb1611d9644acfccd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Fri, 12 Jul 2019 16:16:52 +0300 Subject: [PATCH] Correct convention factors in read scuff T-matrices (hopefully). Former-commit-id: 2e53b8ab0c5e7eb86398f0044baf10a68aa48c50 --- qpms/normalisation.h | 34 ++++++++++++++++++++++++++-------- qpms/tmatrices.c | 14 +++++++++----- qpms/tmatrices.h | 7 +++++++ 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/qpms/normalisation.h b/qpms/normalisation.h index f3fa044..c7ee22b 100644 --- a/qpms/normalisation.h +++ b/qpms/normalisation.h @@ -10,7 +10,7 @@ #include "qpms_error.h" #include #include - +#include "indexing.h" /// Returns the (real positive) common norm factor of a given normalisation compared to the reference convention. /** Does NOT perform the inversion if QPMS_NORMALISATION_INVERSE is set. */ @@ -29,7 +29,8 @@ static inline double qpms_normalisation_normfactor(qpms_normalisation_t norm, qp } -/// Returns the factors of a magnetic VSWF of a given convention compared to the reference convention. + +/// Returns the factors of a magnetic basis VSWF of a given convention compared to the reference convention. /** * This version ignores the Condon-Shortley phase bit (perhaps because the Condon-Shortley * phase is already taken into account in a `gsl_sf_legendre_*_e()` call.) @@ -43,7 +44,7 @@ static inline complex double qpms_normalisation_factor_M_noCS(qpms_normalisation } -/// Returns the factors of a magnetic VSWF of a given convention compared to the reference convention. +/// Returns the factors of a magnetic basis VSWF of a given convention compared to the reference convention. /** * This version takes into account the Condon-Shortley phase bit. * Do not use if the C.-S. has already been taken into account e.g. in @@ -55,7 +56,7 @@ static inline complex double qpms_normalisation_factor_M(qpms_normalisation_t no } -/// Returns the factors of a electric VSWF of a given convention compared to the reference convention. +/// Returns the factors of a electric basis VSWF of a given convention compared to the reference convention. /** * This version ignores the Condon-Shortley phase bit (perhaps because the Condon-Shortley * phase is already taken into account in a `gsl_sf_legendre_*_e()` call.) @@ -69,7 +70,7 @@ static inline complex double qpms_normalisation_factor_N_noCS(qpms_normalisation } -/// Returns the factors of a electric VSWF of a given convention compared to the reference convention. +/// Returns the factors of a electric basis VSWF of a given convention compared to the reference convention. /** * This version takes into account the Condon-Shortley phase bit. * Do not use if the C.-S. has already been taken into account e.g. in @@ -81,14 +82,14 @@ static inline complex double qpms_normalisation_factor_N(qpms_normalisation_t no } -/// Returns the factors of a electric VSWF divided by the factor of a magnetic VWFS of a given convention, compared to the reference one. +/// Returns the factors of a electric basis VSWF divided by the factor of a magnetic VWFS of a given convention, compared to the reference one. static inline complex double qpms_normalisation_factor_N_M(qpms_normalisation_t norm, qpms_l_t l, qpms_m_t m) { return qpms_normalisation_factor_N_noCS(norm, l, m) / qpms_normalisation_factor_M_noCS(norm, l, m); } -/// Returns the factors of a longitudinal VSWF of a given convention compared to the reference convention. +/// Returns the factors of a longitudinal basis VSWF of a given convention compared to the reference convention. /** * This version ignores the Condon-Shortley phase bit (perhaps because the Condon-Shortley * phase is already taken into account in a `gsl_sf_legendre_*_e()` call.) @@ -101,7 +102,7 @@ static inline complex double qpms_normalisation_factor_L_noCS(qpms_normalisation return fac; } -/// Returns the factors of a longitudinal VSWF of a given convention compared to the reference convention. +/// Returns the factors of a longitudinal basis VSWF of a given convention compared to the reference convention. /** * This version takes into account the Condon-Shortley phase bit. * Do not use if the C.-S. has already been taken into account e.g. in @@ -112,6 +113,23 @@ static inline complex double qpms_normalisation_factor_L(qpms_normalisation_t no return ((norm & QPMS_NORMALISATION_CSPHASE) && (m % 2)) ? -fac : fac; } +/// Returns the factors of a basis VSWF of a given convention compared to the reference convention. +static inline complex double qpms_normalisation_factor_uvswfi(const qpms_normalisation_t norm, qpms_uvswfi_t ui) { + qpms_vswf_type_t t; qpms_m_t m; qpms_l_t l; + qpms_uvswfi2tmn(ui, &t, &m, &l); + switch(t) { + case QPMS_VSWF_MAGNETIC: + return qpms_normalisation_factor_M(norm, l, m); + case QPMS_VSWF_ELECTRIC: + return qpms_normalisation_factor_N(norm, l, m); + case QPMS_VSWF_LONGITUDINAL: + return qpms_normalisation_factor_L(norm, l, m); + default: + QPMS_WTF; + } +} + + /// Returns normalisation flags corresponding to the dual spherical harmonics / waves. /** * This reverses the normalisation factors returned by qpms_normalisation_factor_* diff --git a/qpms/tmatrices.c b/qpms/tmatrices.c index baf6ae4..567ffce 100644 --- a/qpms/tmatrices.c +++ b/qpms/tmatrices.c @@ -17,6 +17,7 @@ #include "qpms_error.h" #include "tmatrices.h" #include "qpms_specfunc.h" +#include "normalisation.h" #define HBAR (1.05457162825e-34) #define ELECTRONVOLT (1.602176487e-19) @@ -352,10 +353,9 @@ qpms_errno_t qpms_read_scuff_tmatrix( if (!(freqs && n && tmdata)) qpms_pr_error_at_flf(__FILE__, __LINE__, __func__, "freqs, n, and tmdata are mandatory arguments and must not be NULL."); - if (bs->norm != QPMS_NORMALISATION_POWER_CS) // CHECKME CORRECT? - qpms_pr_error_at_flf(__FILE__, __LINE__, __func__, - "Not implemented; only QPMS_NORMALISATION_POWER_CS (CHECKME)" - " norm supported right now."); + if(bs->norm & (QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE + | QPMS_NORMALISATION_SPHARM_REAL)) + QPMS_NOT_IMPLEMENTED("Sorry, only standard complex-spherical harmonic based waves are supported right now"); int n_alloc = 128; // First chunk to allocate *n = 0; *freqs = malloc(n_alloc * sizeof(double)); @@ -413,7 +413,11 @@ qpms_errno_t qpms_read_scuff_tmatrix( /* This element has not been requested in bs->ilist. */ continue; else - (*tmdata)[(*n-1)*bs->n*bs->n + desti*bs->n + srci] = tr + I*ti; + (*tmdata)[(*n-1)*bs->n*bs->n + desti*bs->n + srci] = (tr + I*ti) + * qpms_normalisation_factor_uvswfi(bs->norm, srcui) + / qpms_normalisation_factor_uvswfi(bs->norm, destui) + * qpms_normalisation_factor_uvswfi(QPMS_NORMALISATION_CONVENTION_SCUFF, destui) + / qpms_normalisation_factor_uvswfi(QPMS_NORMALISATION_CONVENTION_SCUFF, srcui); } free(linebuf); // free some more memory diff --git a/qpms/tmatrices.h b/qpms/tmatrices.h index ae1208e..f77d4e4 100644 --- a/qpms/tmatrices.h +++ b/qpms/tmatrices.h @@ -142,6 +142,13 @@ qpms_errno_t qpms_load_scuff_tmatrix( /// Loads a scuff-tmatrix generated file. /** A simple wrapper over qpms_read_scuff_tmatrix() that needs a * path instead of open FILE. + * + * The T-matrix is transformed from the VSWF basis defined by + * QPMS_NORMALISATION_CONVENTION_SCUFF into the basis defined + * by convention bspec->norm. + * + * Right now, bspec->norm with real or "reversed complex" spherical + * harmonics are not supported. */ qpms_errno_t qpms_read_scuff_tmatrix( FILE *f, ///< An open stream with the T-matrix data.