WIP documentation on phase/normalisation implementation.

This commit is contained in:
Marek Nečada 2020-10-23 16:23:45 +03:00
parent fd588b7c02
commit e486e04e2f
3 changed files with 122 additions and 2 deletions

View File

@ -1,6 +1,10 @@
VSWF conventions {#vswf_conventions} VSWF conventions {#vswf_conventions}
==================================== ====================================
*This page provides reference about the VSWF conventions used in the literature.
For VSWF convention specification in QPMS API, see
[SWF Conventions in QPMS](@ref swf_conventions_qpms).*
In general, the (transversal) VSWFs can be defined using (some) vector spherical harmonics In general, the (transversal) VSWFs can be defined using (some) vector spherical harmonics
as follows: \f[ as follows: \f[
\wfm\pr{k\vect r}_{lm} = \sphbes_l(kr) \vshrot_{lm} (\uvec r),\\ \wfm\pr{k\vect r}_{lm} = \sphbes_l(kr) \vshrot_{lm} (\uvec r),\\
@ -50,7 +54,7 @@ where the connection to negative orders is
\dlmfFer{\nu}{m}(x) = (-1)^m \frac{\Gamma\pr{\nu-m+1}}{\Gamma\pr{\nu+m+1}}\dlmfFer{\nu}{m}(x),\\ \dlmfFer{\nu}{m}(x) = (-1)^m \frac{\Gamma\pr{\nu-m+1}}{\Gamma\pr{\nu+m+1}}\dlmfFer{\nu}{m}(x),\\
%\dlmfLeg{\nu}{m}(x) = \frac{\Gamma\pr{\nu-m+1}}{\Gamma\pr{\nu+m+1}}\dlmfLeg{\nu}{m}(x).\\ %\dlmfLeg{\nu}{m}(x) = \frac{\Gamma\pr{\nu-m+1}}{\Gamma\pr{\nu+m+1}}\dlmfLeg{\nu}{m}(x).\\
\f] \f]
Note that there are called "Ferrers" functions in DLMF, while the "Legendre" functions have slightly Note that they are called "Ferrers" functions in DLMF, while the "Legendre" functions have slightly
different meaning / conventions (Ferrers functions being defined for \f$ \abs{x} \le 1 \f$, whereas different meaning / conventions (Ferrers functions being defined for \f$ \abs{x} \le 1 \f$, whereas
Legendre for \f$ \abs{x} \ge 1 \f$. We will not use the DLMF "Legendre" functions here. Legendre for \f$ \abs{x} \ge 1 \f$. We will not use the DLMF "Legendre" functions here.

114
notes/conventions_qpms.md Normal file
View File

@ -0,0 +1,114 @@
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

View File

@ -99,7 +99,9 @@ typedef enum {
* These bit flags are used by the functions declared in normalisation.h * These bit flags are used by the functions declared in normalisation.h
* that return the appropriate convention-dependent factors. * that return the appropriate convention-dependent factors.
* *
* See @ref vswf_conventions for comparison of the various conventions used. * \see @ref vswf_conventions for comparison of the various conventions used.
* \see @ref swf_conventions_qpms for description how the conventions are used internally and in the QPMS API.
*
*/ */
typedef enum { typedef enum {
QPMS_NORMALISATION_UNDEF = 0, ///< Convention undefined. This should not happen. QPMS_NORMALISATION_UNDEF = 0, ///< Convention undefined. This should not happen.