115 lines
4.4 KiB
Markdown
115 lines
4.4 KiB
Markdown
SWF conventions in QPMS {#swf_conventions_qpms}
|
||
=================================================
|
||
|
||
*This page describes how (V)SWF conventions are specified
|
||
internally and in QPMS API. For a general overview of VSWF
|
||
conventions in the literature, see [VSWF Conventions](@ref vswf_conventions).*
|
||
|
||
Convention enumerator
|
||
---------------------
|
||
|
||
Most of the meaningful phase and normalisation conventions for spherical waves
|
||
can be specified by the enum type @ref qpms_normalisation_t.
|
||
|
||
The type can be also used to specify conventions that are currently not fully
|
||
supported in QPMS (such as those based on real spherical harmonics).
|
||
|
||
As an enum type, it does not cover all the conventions possibly imaginable,
|
||
but it does cover the most meaningful ones and most of those that can be found
|
||
in the literature.
|
||
|
||
(Most notably, it does not cover the “anti-normalisation”
|
||
that does appear in certain expressions in some literature where the spherical
|
||
harmonics contain unnormalised Legendre functions, so that the basis set of
|
||
of spherical harmonics has different norms for different signs of *m*
|
||
for the same *l*. This is a bad idea overall and an absolutely atrocious
|
||
approach for numerics. Do not use that.)
|
||
|
||
|
||
VSWF evaluation
|
||
---------------
|
||
|
||
Evaluation of VSWFs using qpms_vswf_fill(), qpms_eval_vswf(),
|
||
qpms_uvswf_fill() and other functions from vswf.h are evaluated as follows.
|
||
These fuctions take a @ref qpms_normalisation_t as an argument.
|
||
The Ferrers-Legendre functions and the π, τ functions are evaluated
|
||
by qpms_pitau_get(), which internally uses gsl_sf_legendre_deriv_array_e().
|
||
|
||
Note only the information about the Condon-Shortley
|
||
phase is passed to qpms_pitau_get() – the result of this function
|
||
uses always the GSL_SF_LEGENDRE_SPHARM normalisation,
|
||
and possible normalisation and other phase factors are evaluated afterwards
|
||
using the inline functions
|
||
qpms_normalisation_factor_L_noCS(),
|
||
qpms_normalisation_factor_M_noCS(),
|
||
qpms_normalisation_factor_N_noCS().
|
||
|
||
Evaluation of vector spherical harmonics only with qpms_vecspharm_fill()
|
||
works similarly but TODO.
|
||
|
||
TODO reference to pi, tau.
|
||
|
||
VSWF translation operator evaluation
|
||
------------------------------------
|
||
|
||
In practice, translation operators are calculated by first creating
|
||
an instance of the qpms_trans_calculator structure, which contains
|
||
a table of constant normalisation factors for a given phase/normalisation
|
||
convention (it is assumed that the phase/normalisation conventions do not
|
||
change with the translation), and then calling
|
||
qpms_trans_calculator_get_AB_arrays()
|
||
(or others).
|
||
|
||
The precomputed factor table in qpms_trans_calculator_t contains a CS phase
|
||
related factor (via qpms_trans_normfac()).
|
||
|
||
Function qpms_trans_calculator_get_AB_arrays_buf() then calculates
|
||
the unnormalised (GSL_SF_LEGENDRE_NONE)
|
||
associated Legendre functions always with CS phase -1;
|
||
and the A, B arrays are filled (via qpms_trans_calculator_get_AB_arrays_precalcbuf())
|
||
by individual calls of qpms_trans_calculator_get_A_precalcbuf()
|
||
and qpms_trans_calculator_B_precalcbuf(), which basically just multiply
|
||
and sum the precalculated constant factors with the radial (Bessel),
|
||
polar (Legendre) and azimuthal (exponential/trigonometric) functions.
|
||
**This means that the normalisation and phase convention is fully embedded
|
||
in the constant factor tables, and nothing is calculated during "runtime".**
|
||
|
||
The "higher-level" qpms_trans_calculator_get_trans_array() currently
|
||
just calls qpms_trans_calculator_get_AB_arrays() and then reorders
|
||
the elements (using qpms_trans_array_from_AB()), asserting that
|
||
the normalisation conventions remain the same.
|
||
|
||
|
||
There seems to be an inconsistency between
|
||
qpms_trans_calculator_get_B_buf() and
|
||
qpms_trans_calculator_get_A_buf() on one hand, and
|
||
qpms_trans_calculator_get_AB_buf_p() and
|
||
qpms_trans_calculator_get_AB_arrays_buf() on the other.
|
||
While the latter two functions use always -1 as the CS phase,
|
||
the former two take it from the normalisation enumerator.
|
||
**Although the former two are probably used nowhere in the production,
|
||
this needs to be fixed.**
|
||
|
||
|
||
|
||
Lattice sums
|
||
------------
|
||
|
||
### Scalar SWFs
|
||
|
||
### Translation operators
|
||
|
||
Function qpms_trans_calculator_get_AB_arrays_e32_e()
|
||
first compute the scalar lattice sums (using ewald3_sigma_short(),
|
||
ewald3_sigma_long() and ewald3_sigma0() calls).
|
||
|
||
These are then transformed into the VSWF translation operator
|
||
elements in a similar manner as in
|
||
qpms_trans_calculator_get_A_precalcbuf() and
|
||
qpms_trans_calculator_get_B_precalcbuf(), although there some optical
|
||
differences (CHECK!).
|
||
|
||
### VSWFs
|
||
|
||
|