charm_leg#
Module to work with the fully-normalized associated Legendre functions of the first kind:
defines the
charm_pnmjstructure to store Fourier coefficients of the Legendre functions,allocates, initializes and frees
charm_pnmj,computes Fourier coefficients of Legendre functions after Fukushima (2018).
References:
Fukushima, T. (2018) Fast computation of sine/cosine series coefficients of associated Legendre functions of arbitrary high degree and order
Fukushima T (2014) Numerical computation of spherical harmonics of arbitrary degree and order by extending exponent of floating point numbers. Computers and Geosciences 63, 17-21, doi: 10.1016/j.cageo.2013.10.010
Note
This documentation is written for double precision version of CHarm.
Allocate and free the charm_pnmj structure
Functions to allocate and free charm_pnmj.
-
charm_pnmj *charm_leg_pnmj_malloc(unsigned long nmax, int ordering)#
Allocates Fourier coefficients of the fully-normalized associated Legendre functions up to harmonic degree
nmaxusing the ordering schemeordering. The Fourier coefficients are uninitialized, so their values are undefined.orderingcan be set either toCHARM_LEG_PMNJorCHARM_LEG_PMJN.Warning
The
charm_pnmjstructure created by this function must be deallocated by callingcharm_leg_pnmj_free(). The usual deallocationfreewill not deallocate the memory and will lead to memory leaks.- Returns:
On success, returned is a pointer to the
charm_pnmjstructure. On error,NULLis returned.
-
charm_pnmj *charm_leg_pnmj_calloc(unsigned long nmax, int ordering)#
The same as
charm_leg_pnmj_malloc()but all Fourier coefficients are initialized to zero.
-
void charm_leg_pnmj_free(charm_pnmj *pnmj)#
Frees the memory associated with
pnmj. No operation is performed ifpnmjisNULL.
Fourier coefficients of Legendre functions
Functions to compute the Fourier coefficients of Legendre functions and some associated useful functions.
-
void charm_leg_pnmj_coeffs(charm_pnmj *pnmj, unsigned long nmax, charm_err *err)#
Computes Fourier coefficients of fully normalized associated Legendre functions up to degree
nmaxand saves them topnmj. The structure ofpnmj->pnmjdepends onpnmj->ordering. Ifnmax < pnmj->nmax, all Fourier coefficients inpnmj->pnmjbeyondnmaxare set to zero. In case of failure, the error is written toerr.The algorithm of Fukushima (2018) is employed.
References:
Fukushima, T. (2018) Fast computation of sine/cosine series coefficients of associated Legendre functions of arbitrary high degree and order.
-
unsigned long charm_leg_pnmj_j2k(unsigned long n, unsigned long j)#
Transforms a wave-number-related variable
jto the wave-numberkof a Fourier coefficient of fully-normalized associated Legendre function of degreen(see Section C.1 of Fukushima, 2018),.\[k = \left[ 1 - (-1)^n \right] / 2 + 2 j{.}\]- Parameters:
n – [in] Harmonic degree of the Legendre function.
j – [in] Variable related to the wave-number
k.
- Returns:
Wave-number
kof the Fourier coefficient of a Legendre function.
-
unsigned long charm_leg_pnmj_k2j(unsigned long k)#
Transforms a wave-number
kof a Fourier coefficient of fully-normalized associated Legendre function to the wave-number-related variablej(see Section C.1 of Fukushima, 2018),.\[j = \left[ k / 2 \right]_{\mathrm{floor}}{.}\]- Parameters:
k – [in] Wave-number of a Fourier coefficients of Legendre function.
- Returns:
Wave-number-related variable
jof the Fourier coefficient of a Legendre function.
Enums
-
enum [anonymous]#
Ordering scheme of
charm_pnmj.pnmj(a 3D array).Values:
-
enumerator CHARM_LEG_PMNJ#
Order
m, degreen, wave-number-related variablej. Note thatjis not a wave-numberk, but is related to it (seecharm_leg_pnmj_j2k()andcharm_leg_pnmj_k2j()).
-
enumerator CHARM_LEG_PMJN#
Order
m, wave-number-related variablej, degreen.
-
enumerator CHARM_LEG_PMNJ#
-
struct charm_pnmj#
Structure to store Fourier coefficients of the fully-normalized associated Legendre functions.
Public Members
-
unsigned long nmax#
Maximum harmonic degree of the Fourier coefficients.
-
int ordering#
Ordering scheme of the Fourier coefficients in
charm_pnmj.pnmj: eitherCHARM_LEG_PMNJorCHARM_LEG_PMJN.
-
size_t npnmj#
Total number of Fourier coefficients \(P_{nmj}\) in
charm_pnmj.pnmj.
-
double ***pnmj#
Fourier coefficients.
The structure of
charm_pnmj.pnmjdepends oncharm_pnmj.ordering, which takes one of two constants:CHARM_LEG_PMNJorCHARM_LEG_PMJN.Structure of
charm_pnmj.pnmjwhencharm_pnmj.orderingisCHARM_LEG_PMNJ:The first dimension of
charm_pnmj.pnmjis related to harmonic orders, the second dimension to harmonic degrees and the third dimension to wave-numbers. Importantly,charm_pnmj.pnmjis not a regular 3D array, as the number of elements in the second and the third dimension varies based on the first dimension. The following scheme is applied:each
charm_pnmj.pnmj[m], withm = 0,1, …,nmax, hascharm_pnmj.nmax - m + 1elements for harmonic degreesn = m,m + 1, …,charm_pnmj.nmax(respectively),each
charm_pnmj.pnmj[m][n - m]hasfloor(n / 2) + 1elements for wave-numbers.
The Fourier coefficient \(P_{nmj}\), using the notation from Eq. (62) of Fukushima (2018), can therefore be access as follows
charm_pnmj.pnmj[m][n - m][j].Structure of
charm_pnmj.pnmjwhencharm_pnmj.orderingisCHARM_LEG_PMJN:The first dimension of
charm_pnmj.pnmjis related to harmonic orders, the second dimension to wave-numbers and the third dimension to harmonic degrees. Importantly,charm_pnmj.pnmjis not a regular 3D array, as the number of elements in the third dimension varies based on themandjvariables. The following scheme is applied:each
charm_pnmj.pnmj[m], withm = 0,1, …,charm_pnmj.nmax, hasfloor(charm_pnmj.nmax / 2) + 1elements for wave-number-related variablej = 0,1, …,floor(charm_pnmj.nmax / 2),each
charm_pnmj.pnmj[m][j]has(charm_pnmj.nmax - CHARM_MAX(2 * j, m) + 1)elements for harmonic degreesCHARM_MAX(2 * j, m),CHARM_MAX(2 * j, m) + 1, …,charm_pnmj.nmax.
The Fourier coefficient \(P_{nmj}\), using the notation from Eq. (62) of Fukushima (2018), can therefore be access as follows
charm_pnmj.pnmj[m][j][n - CHARM_MAX(m, 2 * j)].
If
charm_pnmj.orderingisCHARM_LEG_PMNJ, the following loop order is recommended for fast sequential access to the \(P_{nmj}\) coefficients: harmonic orderm, harmonic degreenand wave-number-related variablej; e.g.:charm_pnmj *pnmj = charm_leg_pnmj_calloc(nmax, CHARM_LEG_PMNJ) for (unsigned long m = 0; m <= nmax; m++) for (unsigned long n = m; n <= nmax; n++) for (unsigned long j = 0; j <= (n / 2); j++) pnmj->pnmj[m][n - m][j];
If
charm_pnmj.orderingisCHARM_LEG_PMJN, the recommended loop order is:charm_pnmj *pnmj = charm_leg_pnmj_calloc(nmax, CHARM_LEG_PMJN) for (unsigned long m = 0; m <= nmax; m++) for (unsigned long j = 0; j <= (nmax / 2); j++) for (unsigned long n = CHARM_MAX(m, 2 * j); n <= nmax; n++) pnmj->pnmj[m][j][n - CHARM_MAX(m, 2 * j)];
The coefficients (elements) in
charm_pnmj.pnmjare stored in a single contiguous block of memory.Warning
jdoes not represent the wave-numberk, but it is closely related to it (seecharm_leg_pnmj_j2k()andcharm_leg_pnmj_k2j()).
-
unsigned long nmax#