Correct convention factors in read scuff T-matrices (hopefully).

Former-commit-id: 2e53b8ab0c5e7eb86398f0044baf10a68aa48c50
This commit is contained in:
Marek Nečada 2019-07-12 16:16:52 +03:00
parent 76bc4827ca
commit 18767faa03
3 changed files with 42 additions and 13 deletions

View File

@ -10,7 +10,7 @@
#include "qpms_error.h" #include "qpms_error.h"
#include <math.h> #include <math.h>
#include <complex.h> #include <complex.h>
#include "indexing.h"
/// Returns the (real positive) common norm factor of a given normalisation compared to the reference convention. /// 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. */ /** 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 * 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.) * 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. * 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 * 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 * 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.) * 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. * 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 * 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) { 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) return qpms_normalisation_factor_N_noCS(norm, l, m)
/ qpms_normalisation_factor_M_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 * 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.) * 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; 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. * 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 * 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; 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. /// Returns normalisation flags corresponding to the dual spherical harmonics / waves.
/** /**
* This reverses the normalisation factors returned by qpms_normalisation_factor_* * This reverses the normalisation factors returned by qpms_normalisation_factor_*

View File

@ -17,6 +17,7 @@
#include "qpms_error.h" #include "qpms_error.h"
#include "tmatrices.h" #include "tmatrices.h"
#include "qpms_specfunc.h" #include "qpms_specfunc.h"
#include "normalisation.h"
#define HBAR (1.05457162825e-34) #define HBAR (1.05457162825e-34)
#define ELECTRONVOLT (1.602176487e-19) #define ELECTRONVOLT (1.602176487e-19)
@ -352,10 +353,9 @@ qpms_errno_t qpms_read_scuff_tmatrix(
if (!(freqs && n && tmdata)) if (!(freqs && n && tmdata))
qpms_pr_error_at_flf(__FILE__, __LINE__, __func__, qpms_pr_error_at_flf(__FILE__, __LINE__, __func__,
"freqs, n, and tmdata are mandatory arguments and must not be NULL."); "freqs, n, and tmdata are mandatory arguments and must not be NULL.");
if (bs->norm != QPMS_NORMALISATION_POWER_CS) // CHECKME CORRECT? if(bs->norm & (QPMS_NORMALISATION_REVERSE_AZIMUTHAL_PHASE
qpms_pr_error_at_flf(__FILE__, __LINE__, __func__, | QPMS_NORMALISATION_SPHARM_REAL))
"Not implemented; only QPMS_NORMALISATION_POWER_CS (CHECKME)" QPMS_NOT_IMPLEMENTED("Sorry, only standard complex-spherical harmonic based waves are supported right now");
" norm supported right now.");
int n_alloc = 128; // First chunk to allocate int n_alloc = 128; // First chunk to allocate
*n = 0; *n = 0;
*freqs = malloc(n_alloc * sizeof(double)); *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. */ /* This element has not been requested in bs->ilist. */
continue; continue;
else 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(linebuf);
// free some more memory // free some more memory

View File

@ -142,6 +142,13 @@ qpms_errno_t qpms_load_scuff_tmatrix(
/// Loads a scuff-tmatrix generated file. /// Loads a scuff-tmatrix generated file.
/** A simple wrapper over qpms_read_scuff_tmatrix() that needs a /** A simple wrapper over qpms_read_scuff_tmatrix() that needs a
* path instead of open FILE. * 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( qpms_errno_t qpms_read_scuff_tmatrix(
FILE *f, ///< An open stream with the T-matrix data. FILE *f, ///< An open stream with the T-matrix data.