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
|
|||
|
|
|||
|
|