Overview of Legendre function and spherical harmonics conventions.
Former-commit-id: 163846444cce82f34982d67ab7ab0b951c20e29e
This commit is contained in:
parent
c6177163ae
commit
750a6125a9
|
@ -36,7 +36,9 @@ Infinite systems (lattices)
|
|||
|
||||
Installation
|
||||
============
|
||||
The package depends on several python modules and GSL (>= 2.0).
|
||||
The package depends on several python modules, a BLAS/LAPACK library with
|
||||
the respective C bindings (incl. the `lapacke.h` and `cblas.h` headers;
|
||||
[OpenBLAS][OpenBLAS] does have it all and is recommended) and GSL (>= 2.0).
|
||||
The python module dependencies should be installed automatically when running
|
||||
the installation script. If you have a recent enough OS,
|
||||
you can get GSL easily from the repositories; on Debian and derivatives,
|
||||
|
@ -84,6 +86,7 @@ Tutorials
|
|||
* [Finite system tutorial][tutorial-finite]
|
||||
|
||||
[SCUFF-EM]: https://homerreid.github.io/scuff-em-documentation/
|
||||
[OpenBLAS]: https://www.openblas.net/
|
||||
[GSL]: https://www.gnu.org/software/gsl/
|
||||
[cmake]: https://cmake.org
|
||||
[TRITON-README]: README.Triton.md
|
||||
|
|
3
TODO.md
3
TODO.md
|
@ -25,5 +25,8 @@ TODO list before public release
|
|||
- Prefix all identifiers. Maybe think about a different prefix than qpms?
|
||||
- Consistent indentation and style overall.
|
||||
|
||||
Nice but less important features
|
||||
--------------------------------
|
||||
|
||||
- Static, thread-safe caches of constant coefficients + API without the current "calculators".
|
||||
|
||||
|
|
|
@ -1733,6 +1733,13 @@ The anapole is an intriguing example of a nonradiating source useful in the stud
|
|||
file = {/u/46/necadam1/unix/.mozilla/firefox/6m8fw48s.default/zotero/storage/Q7ZEETFQ/Kristensson ja Waterman - 1982 - The T matrix for acoustic and electromagnetic scat.pdf;/u/46/necadam1/unix/.mozilla/firefox/6m8fw48s.default/zotero/storage/XAQLYYR5/1.html}
|
||||
}
|
||||
|
||||
@article{NIST:DLMF,
|
||||
title = {{{NIST Digital Library}} of {{Mathematical Functions}}},
|
||||
url = {http://dlmf.nist.gov/},
|
||||
key = {DLMF},
|
||||
note = {F.~W.~J. Olver, A.~B. Olde Daalhuis, D.~W. Lozier, B.~I. Schneider, R.~F. Boisvert, C.~W. Clark, B.~R. Miller and B.~V. Saunders, eds.}
|
||||
}
|
||||
|
||||
@article{enoch_sums_2001,
|
||||
title = {Sums of Spherical Waves for Lattices, Layers, and Lines},
|
||||
volume = {42},
|
||||
|
@ -1813,7 +1820,7 @@ The anapole is an intriguing example of a nonradiating source useful in the stud
|
|||
author = {Kristensson, Gerhard},
|
||||
month = jul,
|
||||
year = {2016},
|
||||
file = {/u/46/necadam1/unix/.mozilla/firefox/6m8fw48s.default/zotero/storage/3R7VYZUK/Kristensson - 2016 - Scattering of Electromagnetic Waves by Obstacles.pdf}
|
||||
file = {/u/46/necadam1/unix/.mozilla/firefox/6m8fw48s.default/zotero/storage/ZRYZ4KLK/Kristensson - 2016 - Scattering of Electromagnetic Waves by Obstacles.pdf}
|
||||
}
|
||||
|
||||
@article{kristensson_priori_2015,
|
||||
|
@ -1940,4 +1947,12 @@ expansion in terms of Cartesian multipole moments under the rigidity approximati
|
|||
file = {/u/46/necadam1/unix/.mozilla/firefox/6m8fw48s.default/zotero/storage/NIQFEUGY/Nemkov ym. - 2018 - Electromagnetic sources beyond common multipoles.pdf;/u/46/necadam1/unix/.mozilla/firefox/6m8fw48s.default/zotero/storage/9SYKXLI3/PhysRevA.98.html}
|
||||
}
|
||||
|
||||
@misc{GSL,
|
||||
title = {{{GNU Scientific Library}} \textemdash{} {{GSL}} 2.5 Documentation},
|
||||
urldate = {2019-07-09},
|
||||
file = {/u/46/necadam1/unix/.mozilla/firefox/6m8fw48s.default/zotero/storage/TG3YNXVC/index.html},
|
||||
url = {http://dlmf.nist.gov/},
|
||||
key = {GSL}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,18 +27,89 @@ Let us define the "dual" vector spherical harmonics \f$ \vshD_{\tau lm} \f$ as f
|
|||
where the \f$ \cdot \f$ symbol here means the bilinear form of the vector components
|
||||
without complex conjugation (which is included in the "duality" mapping).
|
||||
|
||||
For the sake of non-ambiguity, let us define the "canonical" associated Legendre polynomials
|
||||
as in \cite DLMF TODO exact refs:
|
||||
The problem with conventions starts with the very definition of associated Legendre / Ferrers functions.
|
||||
|
||||
For the sake of non-ambiguity, let us first define the "canonical" associated Legendre/Ferrers polynomials
|
||||
*without* the Condon-Shortley phase.
|
||||
\f[
|
||||
\rawLeg{l}{0}(x) = \frac{1}{2^n n!} \frac{\ud^n}{\ud x^n} \pr{x^2-1}^n , \\
|
||||
\rawLeg{l}{m}(x) = \pr{1-x^2}^{m/2} \frac{\ud^m}{\ud x^m} \rawLeg{l}{0},\quad\abs{x}\le 1, m \ge 0, \\
|
||||
\rawLeg{l}{m}(x) = (-1)^\abs{m} \frac{(l-\abs{m})!}{(l+\abs{m})!} \rawLeg{l}{\abs{m}},
|
||||
\quad \abs{x} \le 1, m < 0.
|
||||
\f]
|
||||
DLMF \cite NIST:DLMF has for non-negative integer \f$m\f$ (18.5.5), (14.6.1), (14.9.3):
|
||||
\f[
|
||||
\dlmfFer{\nu}{} = \dlmfLeg{\nu}{} = \frac{1}{2^n n!} \frac{\ud^n}{\ud x^n} \pr{x^2-1}^n , \\
|
||||
\dlmfFer{\nu}{m}\left(x\right)=(-1)^{m}\left(1-x^2\right)^{m/2}\frac{{
|
||||
\ud}^{m}\dlmfFer{\nu}{}\left(x\right)}{{\ud x}^{m}},\\
|
||||
%\dlmfLeg{\nu}{m}\left(x\right)=\left(-1+x^2\right)^{m/2}\frac{{
|
||||
%\ud}^{m}\dlmfLeg{\nu}{}\left(x\right)}{{\ud x}^{m}},\\
|
||||
\f]
|
||||
where the connection to negative orders is
|
||||
\f[
|
||||
\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).\\
|
||||
\f]
|
||||
Note that there 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
|
||||
Legendre for \f$ \abs{x} \ge 1 \f$. We will not use the DLMF "Legendre" functions here.
|
||||
|
||||
One sees that \f$ \dlmfFer{l}{m} = (-1)^m \rawFer{l}{m} \f$, i.e. the Condon-Shortley phase is
|
||||
already included in the DLMF definitions of Ferrers functions.
|
||||
|
||||
GSL computes \f$ \rawFer{l}{m} \f$ unless the corresponding `csphase` argument is set to
|
||||
\f$-1\f$ (then it computes \f$ \dlmfFer{l}{m} \f$). This is not explicitly obvious from the docs
|
||||
\cite GSL,
|
||||
but can be tested by running `gsl_sf_legendre_array_e` for some specific arguments and comparing signs.
|
||||
|
||||
|
||||
Literature convention table
|
||||
---------------------------
|
||||
Literature convention tables
|
||||
----------------------------
|
||||
|
||||
### Legendre functions and spherical harmonics
|
||||
|
||||
| Source | Ferrers function | Negative \f$m\f$ | Spherical harmonics |
|
||||
|------------------------|-----------------------|--------------------|---------------------|
|
||||
| DLMF \cite NIST:DLMF | \f[
|
||||
\dlmfFer{\nu}{m}\left(x\right)=(-1)^{m}\left(1-x^2\right)^{m/2}\frac{{
|
||||
\ud}^{m}\dlmfFer{\nu}{}\left(x\right)}{{\ud x}^{m}}
|
||||
\f] | \f[
|
||||
\dlmfFer{\nu}{m}(x) = (-1)^m \frac{\Gamma\pr{\nu-m+1}}{\Gamma\pr{\nu+m+1}}\dlmfFer{\nu}{m}(x)
|
||||
\f] | Complex (14.30.1): \f[
|
||||
\dlmfYc{l}{m} = \sqrt{\frac{(l-m)!(2l+1)}{4\pi(l+m)!}} e^{im\phi} \dlmfFer{l}{m}(\cos\theta).
|
||||
\f] Real, unnormalized (14.30.2): \f$
|
||||
\dlmfYrUnnorm{l}{m}\pr{\theta,\phi} = \cos\pr{m\phi} \dlmfFer{l}{m}\pr{\cos\theta}
|
||||
\f$ or \f$
|
||||
\dlmfYrUnnorm{l}{m}\pr{\theta,\phi} = \sin\pr{m\phi} \dlmfFer{l}{m}\pr{\cos\theta}
|
||||
\f$. |
|
||||
| GSL \cite GSL | \f[
|
||||
\Fer[GSL]{l}{m} = \csphase^m N \rawFer{l}{m}
|
||||
\f] for non-negative \f$m\f$. \f$
|
||||
\csphase\f$ is one by default and can be set to \f$
|
||||
-1\f$ using the functions ending with \_e with argument `csphase = -1`. \f$
|
||||
N\f$ is a positive normalisation factor from from `gsl_sf_legendre_t`. | N/A. Must be calculated manually. | The asimuthal part must be calculated manually. Use `norm = GSL_SF_LEGENDRE_SPHARM` to get the usual normalisation factor \f$
|
||||
N= \sqrt{\frac{(l-m)!(2l+1)}{4\pi(l+m)!}} \f$. |
|
||||
| Kristensson I \cite kristensson_spherical_2014 | \f$ \rawFer{l}{m} \f$ | As in \f$ \rawFer{l}{m} \f$. | \f[
|
||||
\spharm[Kc]{l}{m} = (-1)^m \sqrt{\frac{(l-m)!(2l+1)}{4\pi(l+m)!}} \rawFer{l}{m}(\cos\theta) e^{im\phi},
|
||||
\f] cf. Sec. D.2. |
|
||||
| Kristensson II \cite kristensson_scattering_2016 | \f$ \rawFer{l}{m} \f$ | As in \f$ \rawFer{l}{m} \f$. | \f[
|
||||
\spharm[Kr]{\begin{Bmatrix}e \\ o\end{Bmatrix}}{l}{m} =
|
||||
\sqrt{2-\delta_{m0}}\sqrt{\frac{(l-m)!(2l+1)}{4\pi(l+m)!}}
|
||||
\rawFer{l}{m}(\cos\theta)
|
||||
\begin{Bmatrix}\cos\phi \\ \sin\phi\end{Bmatrix},
|
||||
\f] \f$ m \ge 0 \f$. Cf. Appendix C.3. |
|
||||
| Reid \cite reid_electromagnetism_2016 | Not described in the memos. Superficial look into the code suggests that the `GetPlm` function *does* include the Condon-Shortley phase and spherical harmonic normalisation, so \f[
|
||||
\Fer[GetPlm]{l}{m} = (-1)^m \sqrt{\frac{(l-m)!(2l+1)}{4\pi(l+m)!}} \rawFer{l}{m}
|
||||
\f] for non-negative \f$ m \f$. | N/A. Must be calculated manually. | \f[
|
||||
\spharm[GetYlm]{l}{m}(\theta,\phi) = \Fer[GetPlm]{l}{m}(\cos\theta) e^{im\phi},\quad m\le 0, \\
|
||||
\spharm[GetYlm]{l}{m}(\theta,\phi) = (-1)^m\Fer[GetPlm]{l}{\abs{m}}(\cos\theta) e^{-im\phi},\quad m<0,
|
||||
\f] and the negative sign in the second line's exponent is quite concerning, because that would mean the asimuthal part is actually \f$ e^{i\abs{m}\phi} \f$. _Is this a bug in scuff-em_? Without it, it would be probably equivalent to DLMF's \f$ \dlmfYc{l}{m} \f$s for both positive and negative \f$ m\f$s. However, it seems that `GetYlmDerivArray` has it consistent, with \f[
|
||||
\spharm[GetYlmDerivArray]{l}{m} = \dlmfYc{l}{m}
|
||||
\f] for all \f$m\f$, and this is what is actually used in `GetMNlmArray` (used by both `SphericalWave` in `libIncField` (via `GetMNlm`) and `GetSphericalMoments` in `libscuff` (via `GetWaveMatrix`)) and `GetAngularFunctionArray` (not used). |
|
||||
|
||||
|
||||
|
||||
### VSWF conventions
|
||||
|
||||
| Source | VSWF definition | E/M interrelations | VSWF norm | CS Phase | Field expansion | Radiated power | Notes |
|
||||
|--- |--- |--- |--- |--- |--- |--- |--- |
|
||||
|
|
|
@ -21,7 +21,16 @@ MathJax.Hub.Config({
|
|||
wfe: "{\\mathbf{N}}", // Electric wave general
|
||||
wfm: "{\\mathbf{M}}", // Magnetic wave general
|
||||
sphbes: "{z}", // General spherical Bessel fun
|
||||
rawLeg: ["{P_{#1}^{#2}}", 2], // "Canonical" associated Legendre polynomial
|
||||
rawLeg: ["{\\mathfrak{P}_{#1}^{#2}}", 2], // "Canonical" associated Legendre polynomial without C.S. phase
|
||||
rawFer: ["\\rawLeg{#1}{#2}", 2], // "Canonical" associated Legendre polynomial without C.S. phase
|
||||
dlmfLeg: ["{P_{#1}^{#2}}", 2], // Associated Legendre function as in DLMF (14.3.6)
|
||||
dlmfFer: ["{\\mathsf{P}_{#1}^{#2}}", 2], // Ferrers Function as in DLMF (14.3.1)
|
||||
dlmfYc: ["{Y_{{#1},{#2}}}", 2], // Complex spherical harmonics as in DLMF (14.30.1)
|
||||
dlmfYrUnnorm: ["{Y_{#1}^{#2}}", 2], // Real spherical harmonics as in DLMF (14.30.2)
|
||||
Fer: ["{{P_{\\mathrm{#1}}}_{#2}^{#3}}", 3, ""], // Legendre / Ferrers function
|
||||
spharm: ["{{Y_{\\mathrm{#1}}}_{#2}^{#3}}", 3, ""], // Spherical harmonics
|
||||
spharmR: ["{{Y_{\\mathrm{#1}}}_{\\mathrm{#1}{#2}{#3}}", 4, ""], // Spherical harmonics
|
||||
csphase: "\\mathsf{C_{CS}}", // Condon-Shortley phase
|
||||
|
||||
// Kristensson's VSWFs, complex version (2014 notes)
|
||||
wfkcreg: "{\\vect{v}}", // regular wave
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#include <stddef.h>
|
||||
#include <gsl/gsl_sf_legendre.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
const size_t lmax = 2;
|
||||
const double x = .5;
|
||||
size_t arrsiz = gsl_sf_legendre_array_n(lmax);
|
||||
double csphase = 1;
|
||||
double target[arrsiz];
|
||||
printf("lmax = %zd, x = %g, csphase = %g:\n", lmax, x, csphase);
|
||||
gsl_sf_legendre_array_e(GSL_SF_LEGENDRE_NONE, lmax, x, csphase, target);
|
||||
for(int l = 0; l <= lmax; ++l) for (int m = 0; m <= l; ++m)
|
||||
printf("P_%d^%d(%g)\t= %g\n", l, m, x, target[gsl_sf_legendre_array_index(l,m)]);
|
||||
csphase = -1;
|
||||
printf("lmax = %zd, x = %g, csphase = %g:\n", lmax, x, csphase);
|
||||
gsl_sf_legendre_array_e(GSL_SF_LEGENDRE_NONE, lmax, x, csphase, target);
|
||||
for(int l = 0; l <= lmax; ++l) for (int m = 0; m <= l; ++m)
|
||||
printf("P_%d^%d(%g)\t= %g\n", l, m, x, target[gsl_sf_legendre_array_index(l,m)]);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue